diff --git a/Interop/Runtime/src/main/kotlin/kotlin_native/interop/Utils.kt b/Interop/Runtime/src/main/kotlin/kotlin_native/interop/Utils.kt index d1de51c09cf..8027e9bc5e6 100644 --- a/Interop/Runtime/src/main/kotlin/kotlin_native/interop/Utils.kt +++ b/Interop/Runtime/src/main/kotlin/kotlin_native/interop/Utils.kt @@ -2,15 +2,6 @@ package kotlin_native.interop fun malloc(type: NativeRef.TypeWithSize) = type.byPtr(bridge.malloc(type.size)) -inline fun malloc(type: NativeRef.TypeWithSize, 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 Placement.allocNativeArrayOf(elemType: NativeRef.Type, va fun mallocNativeArrayOf(elemType: NativeRef.Type, vararg elements: T?) = heap.allocNativeArrayOf(elemType, *elements) +fun Placement.allocNativeArrayOf(elements: ByteArray): NativeArray { + 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.asCString() = CString.fromArray(this) fun Int8Box.asCString() = CString.fromArray(NativeArray.byRefToFirstElem(this, Int8Box)) -fun String.toCString() = CString.fromString(this) \ No newline at end of file +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 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 memScoped(block: MemScope.()->R): R { + @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") // TODO: it is a hack + return MemScope.use(block) +} \ No newline at end of file diff --git a/backend.native/build.gradle b/backend.native/build.gradle index aa1625fe52d..5faa5acc5ca 100644 --- a/backend.native/build.gradle +++ b/backend.native/build.gradle @@ -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' diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt index 2f585dd0bb2..aec90c0eccc 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt @@ -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, 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) + } } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/ContextUtils.kt index 7ca0df21e11..4ab4ca692b8 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/ContextUtils.kt @@ -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 } \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/HashUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/HashUtils.kt new file mode 100644 index 00000000000..e5129d32972 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/HashUtils.kt @@ -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) \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt index ae0fa296d11..24d3331d231 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/IrToBitcode.kt @@ -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())!!) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/LlvmUtils.kt index 70338199966..8fca993ec9f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/LlvmUtils.kt @@ -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() { +internal class ConstArray(val elemType: LLVMOpaqueType?, val elements: List) : 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() { +internal open class Struct(val type: LLVMOpaqueType?, val elements: List) : 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.asCompileTimeValue(size: Int): ConstArray { + return ConstArray(int8Type, (0 .. size-1).map { + Int8(this[it].value) + }) +} \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/NameUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/NameUtils.kt index 6f9f743cbac..a5646d4dead 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/NameUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/NameUtils.kt @@ -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() \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt index 18e08942248..2788b5172c2 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/RTTIGenerator.kt @@ -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): 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) diff --git a/backend.native/tests/Makefile b/backend.native/tests/Makefile index f23c927b4e7..556b47f474f 100644 --- a/backend.native/tests/Makefile +++ b/backend.native/tests/Makefile @@ -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 $< diff --git a/runtime/src/main/cpp/Names.cpp b/common/src/hash/cpp/Names.cpp similarity index 100% rename from runtime/src/main/cpp/Names.cpp rename to common/src/hash/cpp/Names.cpp diff --git a/runtime/src/main/cpp/Names.h b/common/src/hash/headers/Names.h similarity index 100% rename from runtime/src/main/cpp/Names.h rename to common/src/hash/headers/Names.h diff --git a/common/src/hash/headers/Sha1.h b/common/src/hash/headers/Sha1.h index 65352e66fd9..34019dfe62f 100644 --- a/common/src/hash/headers/Sha1.h +++ b/common/src/hash/headers/Sha1.h @@ -1,5 +1,8 @@ #ifndef RUNTIME_SHA1_H #define RUNTIME_SHA1_H + +#include + /* SHA-1 in C By Steve Reid diff --git a/runtime/src/main/kotlin/kotlin_native/annotations.kt b/runtime/src/main/kotlin/kotlin_native/annotations.kt new file mode 100644 index 00000000000..de835209772 --- /dev/null +++ b/runtime/src/main/kotlin/kotlin_native/annotations.kt @@ -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)