Merge pull request #11 from JetBrains/some-stupid-coding-1
Various fixes and and improvements
This commit is contained in:
@@ -2,15 +2,6 @@ package kotlin_native.interop
|
||||
|
||||
fun <T : NativeRef> malloc(type: NativeRef.TypeWithSize<T>) = type.byPtr(bridge.malloc(type.size))
|
||||
|
||||
inline fun <T : NativeRef, R> malloc(type: NativeRef.TypeWithSize<T>, action: (T) -> R): R {
|
||||
val ref = malloc(type)
|
||||
try {
|
||||
return action(ref)
|
||||
} finally {
|
||||
free(ref)
|
||||
}
|
||||
}
|
||||
|
||||
fun free(ptr: NativePtr?) {
|
||||
if (ptr != null) {
|
||||
bridge.free(ptr)
|
||||
@@ -29,6 +20,14 @@ fun <T : NativeRef> Placement.allocNativeArrayOf(elemType: NativeRef.Type<T>, va
|
||||
|
||||
fun <T : NativeRef> mallocNativeArrayOf(elemType: NativeRef.Type<T>, vararg elements: T?) = heap.allocNativeArrayOf(elemType, *elements)
|
||||
|
||||
fun Placement.allocNativeArrayOf(elements: ByteArray): NativeArray<Int8Box> {
|
||||
val res = this.alloc(array[elements.size](Int8Box))
|
||||
elements.forEachIndexed { i, element ->
|
||||
res[i].value = element
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
fun CString.Companion.fromString(str: String?): CString? {
|
||||
if (str == null) {
|
||||
return null
|
||||
@@ -48,4 +47,29 @@ fun CString.Companion.fromString(str: String?): CString? {
|
||||
|
||||
fun NativeArray<Int8Box>.asCString() = CString.fromArray(this)
|
||||
fun Int8Box.asCString() = CString.fromArray(NativeArray.byRefToFirstElem(this, Int8Box))
|
||||
fun String.toCString() = CString.fromString(this)
|
||||
fun String.toCString() = CString.fromString(this)
|
||||
|
||||
class MemScope private constructor(private val arena: Arena) : Placement by arena {
|
||||
val memScope: Placement
|
||||
get() = this
|
||||
|
||||
companion object {
|
||||
internal inline fun <R> use(block: MemScope.()->R): R {
|
||||
val memScope = MemScope(Arena())
|
||||
try {
|
||||
return memScope.block()
|
||||
} finally {
|
||||
memScope.arena.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs given [block] providing allocation of memory
|
||||
* which will be automatically disposed at the end of this scope.
|
||||
*/
|
||||
inline fun <R> memScoped(block: MemScope.()->R): R {
|
||||
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") // TODO: it is a hack
|
||||
return MemScope.use(block)
|
||||
}
|
||||
@@ -76,7 +76,11 @@ build.dependsOn 'compilerClasses','cli_bcClasses','bc_frontendClasses'
|
||||
task run(type: JavaExec) {
|
||||
main 'org.jetbrains.kotlin.cli.bc.K2NativeKt'
|
||||
classpath sourceSets.cli_bc.runtimeClasspath
|
||||
|
||||
args 'tests/codegen/function/sum.kt'
|
||||
|
||||
args project(':runtime').file('src/main/kotlin')
|
||||
|
||||
args '-output', "$buildDir/out.bc"
|
||||
|
||||
jvmArgs '-ea'
|
||||
|
||||
+9
-3
@@ -11,6 +11,10 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
var currentFunction:FunctionDescriptor? = null
|
||||
|
||||
fun function(declaration: IrFunction) {
|
||||
if (declaration.descriptor.isExternal) {
|
||||
return
|
||||
}
|
||||
|
||||
index = 0
|
||||
currentFunction = declaration.descriptor
|
||||
val fn = LLVMAddFunction(context.llvmModule, declaration.descriptor.symbolName, getLlvmFunctionType(declaration.descriptor))
|
||||
@@ -62,9 +66,11 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
fun load(value:LLVMOpaqueValue, varName: String):LLVMOpaqueValue = LLVMBuildLoad(context.llvmBuilder, value, varName)!!
|
||||
fun store(value:LLVMOpaqueValue, ptr:LLVMOpaqueValue):LLVMOpaqueValue = LLVMBuildStore(context.llvmBuilder, value, ptr)!!
|
||||
fun call(descriptor: FunctionDescriptor, args: MutableList<LLVMOpaqueValue?>, result: String): LLVMOpaqueValue? {
|
||||
val rargs = malloc(array[args.size](Ref to LLVMOpaqueValue))
|
||||
args.forEachIndexed { i, llvmOpaqueValue -> rargs[i].value = args[i]}
|
||||
return LLVMBuildCall(context.llvmBuilder, descriptor.llvmFunction.getLlvmValue(), rargs[0], args.size, result)
|
||||
memScoped {
|
||||
val rargs = alloc(array[args.size](Ref to LLVMOpaqueValue))
|
||||
args.forEachIndexed { i, llvmOpaqueValue -> rargs[i].value = args[i] }
|
||||
return LLVMBuildCall(context.llvmBuilder, descriptor.llvmFunction.getLlvmValue(), rargs[0], args.size, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+57
-4
@@ -1,11 +1,14 @@
|
||||
package org.jetbrains.kotlin.backend.native.llvm
|
||||
|
||||
import kotlin_native.interop.mallocNativeArrayOf
|
||||
import kotlin_native.interop.*
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.native.hash.GlobalHash
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
@@ -16,6 +19,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
internal interface ContextUtils {
|
||||
val context: Context
|
||||
|
||||
val runtime: Runtime
|
||||
get() = context.runtime
|
||||
|
||||
val llvmTargetData: LLVMOpaqueTargetData?
|
||||
get() = runtime.targetData
|
||||
|
||||
/**
|
||||
* All fields of the class instance.
|
||||
* The order respects the class hierarchy, i.e. a class [fields] contains superclass [fields] as a prefix.
|
||||
@@ -73,7 +82,7 @@ internal interface ContextUtils {
|
||||
val module = context.llvmModule
|
||||
val globalName = this.typeInfoSymbolName
|
||||
val globalPtr = LLVMGetNamedGlobal(module, globalName) ?:
|
||||
LLVMAddGlobal(module, context.runtime.typeInfoType, globalName)
|
||||
LLVMAddGlobal(module, runtime.typeInfoType, globalName)
|
||||
|
||||
return compileTimeValue(globalPtr)
|
||||
}
|
||||
@@ -92,13 +101,18 @@ internal interface ContextUtils {
|
||||
/**
|
||||
* Returns pointer to first element of given array.
|
||||
*
|
||||
* Note: this function doesn't depend on the context
|
||||
*
|
||||
* @param arrayPtr pointer to array
|
||||
*/
|
||||
private fun getPtrToFirstElem(arrayPtr: CompileTimeValue): CompileTimeValue {
|
||||
val indices = longArrayOf(0, 0).map { LLVMConstInt(LLVMInt32Type(), it, 0) }.toTypedArray()
|
||||
val indicesNativeArrayPtr = mallocNativeArrayOf(LLVMOpaqueValue, *indices)[0] // TODO: dispose
|
||||
|
||||
return compileTimeValue(LLVMBuildGEP(context.llvmBuilder, arrayPtr.getLlvmValue(), indicesNativeArrayPtr, indices.size, ""))
|
||||
memScoped {
|
||||
val indicesNativeArrayPtr = allocNativeArrayOf(LLVMOpaqueValue, *indices)[0]
|
||||
|
||||
return compileTimeValue(LLVMConstGEP(arrayPtr.getLlvmValue(), indicesNativeArrayPtr, indices.size))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,4 +126,43 @@ internal interface ContextUtils {
|
||||
Zero(pointerType(elemType))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this [GlobalHash] to compile-time value of [runtime]-defined `GlobalHash` type.
|
||||
*
|
||||
* These types must be defined identically.
|
||||
*/
|
||||
private fun GlobalHash.asCompileTimeValue(): Struct {
|
||||
val size = GlobalHash.size
|
||||
assert(size.toLong() == LLVMStoreSizeOfType(llvmTargetData, runtime.globalhHashType))
|
||||
|
||||
return Struct(runtime.globalhHashType, bits.asCompileTimeValue(size))
|
||||
// TODO: implement such transformation more generally using LLVM bitcast
|
||||
// (seems to require some investigation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this string to the sequence of bytes to be used for hashing/storing to binary/etc.
|
||||
*
|
||||
* TODO: share this implementation
|
||||
*/
|
||||
private fun stringAsBytes(str: String) = str.toByteArray(Charsets.UTF_8)
|
||||
|
||||
val String.localHash: LocalHash
|
||||
get() = LocalHash(localHash(stringAsBytes(this)))
|
||||
|
||||
val String.globalHash: CompileTimeValue
|
||||
get() = memScoped {
|
||||
val hash = globalHash(stringAsBytes(this@globalHash), memScope)
|
||||
hash.asCompileTimeValue()
|
||||
}
|
||||
|
||||
val FqName.globalHash: CompileTimeValue
|
||||
get() = this.toString().globalHash
|
||||
|
||||
val Name.localHash: LocalHash
|
||||
get() = this.toString().localHash
|
||||
|
||||
val FqName.localHash: LocalHash
|
||||
get() = this.toString().localHash
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.kotlin.backend.native.llvm
|
||||
|
||||
import kotlin_native.interop.*
|
||||
import org.jetbrains.kotlin.backend.native.hash.*
|
||||
|
||||
internal fun localHash(data: ByteArray): Long {
|
||||
memScoped {
|
||||
val hashBox = alloc(Int64Box)
|
||||
val bytes = allocNativeArrayOf(data)
|
||||
MakeLocalHash(bytes.ptr, data.size, hashBox)
|
||||
return hashBox.value
|
||||
}
|
||||
}
|
||||
|
||||
internal fun globalHash(data: ByteArray, retValPlacement: Placement): GlobalHash {
|
||||
val res = retValPlacement.alloc(GlobalHash)
|
||||
memScoped {
|
||||
val bytes = allocNativeArrayOf(data)
|
||||
MakeGlobalHash(bytes.ptr, data.size, res)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
internal class LocalHash(val value: Long) : CompileTimeValue by Int64(value)
|
||||
+15
@@ -34,6 +34,12 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
super.visitClass(declaration)
|
||||
|
||||
if (declaration.descriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
// do not generate any RTTI for annotation classes as a workaround for link errors
|
||||
return
|
||||
}
|
||||
|
||||
generator.generate(declaration.descriptor)
|
||||
}
|
||||
|
||||
@@ -50,6 +56,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
if (declaration.descriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
// do not generate any code for annotation classes as a workaround for NotImplementedError
|
||||
return
|
||||
}
|
||||
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable) {
|
||||
val value = evaluateExpression(generator.tmpVariable(), expression.value)
|
||||
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
||||
|
||||
+33
-16
@@ -1,6 +1,6 @@
|
||||
package org.jetbrains.kotlin.backend.native.llvm
|
||||
|
||||
import kotlin_native.interop.mallocNativeArrayOf
|
||||
import kotlin_native.interop.*
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
@@ -8,9 +8,9 @@ import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
/**
|
||||
* Represents the value which can be emitted as bitcode const value
|
||||
*/
|
||||
internal abstract class CompileTimeValue {
|
||||
internal interface CompileTimeValue {
|
||||
|
||||
abstract fun getLlvmValue(): LLVMOpaqueValue?
|
||||
fun getLlvmValue(): LLVMOpaqueValue?
|
||||
|
||||
fun getLlvmType(): LLVMOpaqueType? {
|
||||
return LLVMTypeOf(getLlvmValue())
|
||||
@@ -18,44 +18,49 @@ internal abstract class CompileTimeValue {
|
||||
|
||||
}
|
||||
|
||||
internal class ConstArray(val elemType: LLVMOpaqueType?, val elements: List<CompileTimeValue>) : CompileTimeValue() {
|
||||
internal class ConstArray(val elemType: LLVMOpaqueType?, val elements: List<CompileTimeValue>) : CompileTimeValue {
|
||||
|
||||
override fun getLlvmValue(): LLVMOpaqueValue? {
|
||||
val values = elements.map { it.getLlvmValue() }.toTypedArray()
|
||||
val valuesNativeArrayPtr = mallocNativeArrayOf(LLVMOpaqueValue, *values)[0] // FIXME: dispose
|
||||
|
||||
return LLVMConstArray(elemType, valuesNativeArrayPtr, values.size)
|
||||
memScoped {
|
||||
val valuesNativeArrayPtr = allocNativeArrayOf(LLVMOpaqueValue, *values)[0]
|
||||
|
||||
return LLVMConstArray(elemType, valuesNativeArrayPtr, values.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal open class Struct(val type: LLVMOpaqueType?, val elements: List<CompileTimeValue>) : CompileTimeValue() {
|
||||
internal open class Struct(val type: LLVMOpaqueType?, val elements: List<CompileTimeValue>) : CompileTimeValue {
|
||||
|
||||
constructor(type: LLVMOpaqueType?, vararg elements: CompileTimeValue) : this(type, elements.toList())
|
||||
|
||||
override fun getLlvmValue(): LLVMOpaqueValue? {
|
||||
val values = elements.map { it.getLlvmValue() }.toTypedArray()
|
||||
val valuesNativeArrayPtr = mallocNativeArrayOf(LLVMOpaqueValue, *values)[0] // FIXME: dispose
|
||||
return LLVMConstNamedStruct(type, valuesNativeArrayPtr, values.size)
|
||||
memScoped {
|
||||
val valuesNativeArrayPtr = allocNativeArrayOf(LLVMOpaqueValue, *values)[0]
|
||||
return LLVMConstNamedStruct(type, valuesNativeArrayPtr, values.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int8(val value: Byte) : CompileTimeValue() {
|
||||
internal class Int8(val value: Byte) : CompileTimeValue {
|
||||
override fun getLlvmValue() = LLVMConstInt(LLVMInt8Type(), value.toLong(), 1)
|
||||
}
|
||||
|
||||
internal class Int32(val value: Int) : CompileTimeValue() {
|
||||
internal class Int32(val value: Int) : CompileTimeValue {
|
||||
override fun getLlvmValue() = LLVMConstInt(LLVMInt32Type(), value.toLong(), 1)
|
||||
}
|
||||
|
||||
internal class Int64(val value: Long) : CompileTimeValue() {
|
||||
internal class Int64(val value: Long) : CompileTimeValue {
|
||||
override fun getLlvmValue() = LLVMConstInt(LLVMInt64Type(), value, 1)
|
||||
}
|
||||
|
||||
internal class Zero(val type: LLVMOpaqueType?) : CompileTimeValue() {
|
||||
internal class Zero(val type: LLVMOpaqueType?) : CompileTimeValue {
|
||||
override fun getLlvmValue() = LLVMConstNull(type)
|
||||
}
|
||||
|
||||
internal fun compileTimeValue(value: LLVMOpaqueValue?) = object : CompileTimeValue() {
|
||||
internal fun compileTimeValue(value: LLVMOpaqueValue?) = object : CompileTimeValue {
|
||||
override fun getLlvmValue() = value
|
||||
}
|
||||
|
||||
@@ -72,6 +77,18 @@ internal fun getLlvmFunctionType(function: FunctionDescriptor): LLVMOpaqueType?
|
||||
|
||||
val paramTypes = params.map { getLLVMType(it.type) }.toTypedArray()
|
||||
if (paramTypes.size == 0) return LLVMFunctionType(returnType, null, 0, 0)
|
||||
val paramTypesPtr = mallocNativeArrayOf(LLVMOpaqueType, *paramTypes)[0] // TODO: dispose
|
||||
return LLVMFunctionType(returnType, paramTypesPtr, paramTypes.size, 0)
|
||||
|
||||
memScoped {
|
||||
val paramTypesPtr = allocNativeArrayOf(LLVMOpaqueType, *paramTypes)[0]
|
||||
return LLVMFunctionType(returnType, paramTypesPtr, paramTypes.size, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents [size] bytes contained in this array as [ConstArray].
|
||||
*/
|
||||
internal fun NativeArray<Int8Box>.asCompileTimeValue(size: Int): ConstArray {
|
||||
return ConstArray(int8Type, (0 .. size-1).map {
|
||||
Int8(this[it].value)
|
||||
})
|
||||
}
|
||||
+13
-17
@@ -3,27 +3,23 @@ package org.jetbrains.kotlin.backend.native.llvm
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import java.util.zip.CRC32
|
||||
|
||||
private fun crc32(str: String): Long {
|
||||
val c = CRC32()
|
||||
c.update(str.toByteArray())
|
||||
return c.value
|
||||
}
|
||||
|
||||
internal val String.nameHash: Long
|
||||
get() = crc32(this)
|
||||
|
||||
internal val Name.nameHash: Long
|
||||
get() = this.toString().nameHash
|
||||
|
||||
internal val FqName.nameHash: Long
|
||||
get() = this.toString().nameHash
|
||||
private val symbolNameAnnotation = FqName("kotlin_native.SymbolName")
|
||||
|
||||
internal val FunctionDescriptor.symbolName: String
|
||||
get() = "kfun:" + this.fqNameSafe.toString() // FIXME: add signature
|
||||
get() {
|
||||
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
||||
if (this.isExternal) {
|
||||
val nameValue = it.allValueArguments.values.single() as StringValue
|
||||
return nameValue.value
|
||||
} else {
|
||||
// ignore; TODO: report compile error
|
||||
}
|
||||
}
|
||||
return "kfun:" + this.fqNameSafe.toString() // FIXME: add signature
|
||||
}
|
||||
|
||||
internal val ClassDescriptor.typeInfoSymbolName: String
|
||||
get() = "ktype:" + this.fqNameSafe.toString()
|
||||
+22
-22
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.kotlin.backend.native.llvm
|
||||
|
||||
|
||||
import kotlin_native.interop.mallocNativeArrayOf
|
||||
import kotlin_native.interop.allocNativeArrayOf
|
||||
import kotlin_native.interop.memScoped
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.native.implementation
|
||||
import org.jetbrains.kotlin.backend.native.implementedInterfaces
|
||||
@@ -15,17 +16,13 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
|
||||
internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
val runtime: Runtime
|
||||
get() = context.runtime
|
||||
private inner class FieldTableRecord(val nameSignature: LocalHash, val fieldOffset: Int) :
|
||||
Struct(runtime.fieldTableRecordType, nameSignature, Int32(fieldOffset))
|
||||
|
||||
private inner class MethodTableRecord(val nameSignature: LocalHash, val methodEntryPoint: CompileTimeValue) :
|
||||
Struct(runtime.methodTableRecordType, nameSignature, methodEntryPoint)
|
||||
|
||||
private inner class FieldTableRecord(val nameSignature: Long, val fieldOffset: Int) :
|
||||
Struct(runtime.fieldTableRecordType, Int64(nameSignature), Int32(fieldOffset))
|
||||
|
||||
private inner class MethodTableRecord(val nameSignature: Long, val methodEntryPoint: CompileTimeValue) :
|
||||
Struct(runtime.methodTableRecordType, Int64(nameSignature), methodEntryPoint)
|
||||
|
||||
private inner class TypeInfo(val name: Long, val size: Int,
|
||||
private inner class TypeInfo(val name: CompileTimeValue, val size: Int,
|
||||
val superType: CompileTimeValue,
|
||||
val objOffsets: CompileTimeValue,
|
||||
val objOffsetsCount: Int,
|
||||
@@ -39,7 +36,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
Struct(
|
||||
runtime.typeInfoType,
|
||||
|
||||
Struct(runtime.globalhHashType, ConstArray(LLVMInt8Type(), Array(20, {i -> Int8(1)}).toList())),
|
||||
name,
|
||||
Int32(size),
|
||||
|
||||
superType,
|
||||
@@ -63,13 +60,16 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
private fun createStructFor(className: FqName, fields: List<PropertyDescriptor>): LLVMOpaqueType? {
|
||||
val classType = LLVMStructCreateNamed(LLVMGetModuleContext(context.llvmModule), "kclass:" + className)
|
||||
val fieldTypes = fields.map { getLLVMType(it.returnType!!) }.toTypedArray()
|
||||
val fieldTypesNativeArrayPtr = if (fieldTypes.size > 0) {
|
||||
mallocNativeArrayOf(LLVMOpaqueType, *fieldTypes)[0] // TODO: dispose
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
LLVMStructSetBody(classType, fieldTypesNativeArrayPtr, fieldTypes.size, 0)
|
||||
memScoped {
|
||||
val fieldTypesNativeArrayPtr = if (fieldTypes.size > 0) {
|
||||
allocNativeArrayOf(LLVMOpaqueType, *fieldTypes)[0]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
LLVMStructSetBody(classType, fieldTypesNativeArrayPtr, fieldTypes.size, 0)
|
||||
}
|
||||
return classType
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
val classType = createStructFor(className, classDesc.fields)
|
||||
|
||||
val name = className.nameHash
|
||||
val name = className.globalHash
|
||||
|
||||
val size = LLVMStoreSizeOfType(runtime.targetData, classType).toInt()
|
||||
|
||||
@@ -145,10 +145,10 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
|
||||
val fields = classDesc.fields.mapIndexed { index, field ->
|
||||
// Note: using FQ name because a class may have multiple fields with the same name due to property overriding
|
||||
val nameSignature = field.fqNameSafe.nameHash // FIXME: add signature
|
||||
val nameSignature = field.fqNameSafe.localHash // FIXME: add signature
|
||||
val fieldOffset = LLVMOffsetOfElement(runtime.targetData, classType, index)
|
||||
FieldTableRecord(nameSignature, fieldOffset.toInt())
|
||||
}.sortedBy { it.nameSignature }
|
||||
}.sortedBy { it.nameSignature.value }
|
||||
|
||||
val fieldsPtr = addGlobalConstArray("kfields:$className", runtime.fieldTableRecordType, fields)
|
||||
|
||||
@@ -157,11 +157,11 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
val vtablePtr = addGlobalConstArray("kvtable:$className", pointerType(int8Type), vtable)
|
||||
|
||||
val methods = getMethodTableEntries(classDesc).map {
|
||||
val nameSignature = it.name.nameHash // FIXME: add signature
|
||||
val nameSignature = it.name.localHash // FIXME: add signature
|
||||
// TODO: compile-time resolution limits binary compatibility
|
||||
val methodEntryPoint = it.implementation.entryPointAddress
|
||||
MethodTableRecord(nameSignature, methodEntryPoint)
|
||||
}.sortedBy { it.nameSignature }
|
||||
}.sortedBy { it.nameSignature.value }
|
||||
|
||||
val methodsPtr = addGlobalConstArray("kmethods:$className", runtime.methodTableRecordType, methods)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ RUNTIME=${TOP}/runtime
|
||||
BACKEND=${TOP}/backend.native
|
||||
BACKEND_CLASSES=${TOP}/backend.native/build/classes
|
||||
KOTLIN_DIST=${BACKEND}/kotlin-ir/dist
|
||||
KOTLIN_NATIVE_CLASSPATH=${BACKEND_CLASSES}/bc_frontend:${BACKEND_CLASSES}/cli_bc:${BACKEND_CLASSES}/compiler:${KOTLIN_DIST}/kotlinc/lib/kotlin-reflect.jar:${KOTLIN_DIST}kotlinc/lib/kotlin-stdlib.jar:${KOTLIN_DIST}/kotlinc/lib/kotlin-compiler.jar:${KOTLIN_DIST}/kotlinc/lib/kotlin-runtime.jar:${TOP}/Interop/Runtime/build/classes/main
|
||||
KOTLIN_NATIVE_CLASSPATH=${BACKEND_CLASSES}/bc_frontend:${BACKEND_CLASSES}/cli_bc:${BACKEND_CLASSES}/compiler:${BACKEND_CLASSES}/llvmInteropStubs:${BACKEND_CLASSES}/hashInteropStubs:${KOTLIN_DIST}/kotlinc/lib/kotlin-reflect.jar:${KOTLIN_DIST}kotlinc/lib/kotlin-stdlib.jar:${KOTLIN_DIST}/kotlinc/lib/kotlin-compiler.jar:${KOTLIN_DIST}/kotlinc/lib/kotlin-runtime.jar:${TOP}/Interop/Runtime/build/classes/main
|
||||
|
||||
|
||||
define PROTO
|
||||
@@ -41,5 +41,5 @@ clean:
|
||||
|
||||
|
||||
%.BCkt:%.kt
|
||||
${JAVA} -cp ${KOTLIN_NATIVE_CLASSPATH} -Djava.library.path=${BACKEND}/build/nativelibs org.jetbrains.kotlin.cli.bc.K2NativeKt -output $@ -runtime ${RUNTIME}/build/runtime.bc $<
|
||||
${JAVA} -cp ${KOTLIN_NATIVE_CLASSPATH} -Djava.library.path=${BACKEND}/build/nativelibs org.jetbrains.kotlin.cli.bc.K2NativeKt -output $@ -runtime ${RUNTIME}/build/runtime.bc ${RUNTIME}/src/main/kotlin $<
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#ifndef RUNTIME_SHA1_H
|
||||
#define RUNTIME_SHA1_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
SHA-1 in C
|
||||
By Steve Reid <steve@edmweb.com>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package kotlin_native
|
||||
|
||||
/**
|
||||
* Forces the compiler to use specified symbol name for the target `external` function.
|
||||
*
|
||||
* TODO: changing symbol name breaks the binary compatibility,
|
||||
* so it should probably be allowed on `internal` and `private` functions only.
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class SymbolName(val name: String)
|
||||
Reference in New Issue
Block a user