diff --git a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt index 0fff26ad5a1..f8fc000eb52 100644 --- a/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt +++ b/Interop/Runtime/src/main/kotlin/kotlinx/cinterop/Types.kt @@ -460,13 +460,4 @@ typealias CArrayPointerVar = CPointerVar /** * The C function. */ -class CFunction>(rawPtr: NativePtr) : CPointed(rawPtr) - -/** - * Returns a pointer to C function which calls given Kotlin *static* function. - * - * @param function must be *static*, i.e. an (unbound) reference to a Kotlin function or - * a closure which doesn't capture any variable - */ -@Deprecated("The function type is too general. Supply argument with known arity.", level = DeprecationLevel.ERROR) -external fun > staticCFunction(function: F): CPointer> \ No newline at end of file +class CFunction>(rawPtr: NativePtr) : CPointed(rawPtr) \ No newline at end of file diff --git a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt index fea11929dd5..8f824030749 100644 --- a/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt +++ b/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/StubGenerator.kt @@ -602,7 +602,7 @@ class StubGenerator( } else { sequenceOf( annotationForUnableToImport, - "external $header" + "$header = throw UnsupportedOperationException()" ) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt index 4f501562db9..3d69739a9fb 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.LLVMTypeRef +import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.isInlined @@ -104,6 +105,9 @@ internal tailrec fun DeclarationDescriptor.isExported(): Boolean { private val symbolNameAnnotation = FqName("kotlin.native.SymbolName") +private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic") +private val objCMethodAnnotation = FqName("kotlinx.cinterop.ObjCMethod") + private val cnameAnnotation = FqName("kotlin.native.CName") private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime") @@ -205,13 +209,17 @@ internal val FunctionDescriptor.symbolName: String if (!this.isExported()) { throw AssertionError(this.descriptor.toString()) } - this.descriptor.annotations.findAnnotation(symbolNameAnnotation)?.let { - if (this.isExternal) { + + if (isExternal) { + this.descriptor.annotations.findAnnotation(symbolNameAnnotation)?.let { return getStringValue(it)!! - } else { - // ignore; TODO: report compile error + } + if (!this.descriptor.annotations.hasAnnotation(intrinsicAnnotation) && + !this.descriptor.annotations.hasAnnotation(objCMethodAnnotation)) { + throw Error("external function ${this.descriptor} must have @SymbolName, @Intrinsic or @ObjCMethod annotation") } } + this.descriptor.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let { val name = getStringValue(it) ?: this.name.asString() return name // no wrapping currently required diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DescriptorTable.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DescriptorTable.kt index 61e1cdb0d05..7e3fd85a6fa 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DescriptorTable.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/DescriptorTable.kt @@ -24,7 +24,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty -internal fun DeclarationDescriptor.symbolName(): String = when (this) { + +// TODO: merge with FunctionDescriptor.symbolName in BinaryInterface.kt. +internal val DeclarationDescriptor.symbolName: String get() = when (this) { is FunctionDescriptor -> this.uniqueName is PropertyDescriptor @@ -35,7 +37,7 @@ internal fun DeclarationDescriptor.symbolName(): String = when (this) { } internal val DeclarationDescriptor.uniqId - get() = this.symbolName().localHash.value + get() = this.symbolName.localHash.value internal val DeclarationDescriptor.isSerializableExpectClass: Boolean get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) @@ -154,6 +156,8 @@ internal tailrec fun DeclarationDescriptor.isExported(): Boolean { private val symbolNameAnnotation = FqName("kotlin.native.SymbolName") +private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic") + private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime") private val cnameAnnotation = FqName("kotlin.native.internal.CName") @@ -244,13 +248,16 @@ private val FunctionDescriptor.uniqueName: String throw AssertionError(this.toString()) } - this.annotations.findAnnotation(symbolNameAnnotation)?.let { - if (this.isExternal) { + if (this.isExternal) { + this.annotations.findAnnotation(symbolNameAnnotation)?.let { return getStringValue(it)!! - } else { - // ignore; TODO: report compile error + } + if (!annotations.hasAnnotation(intrinsicAnnotation)) { + throw Error("external function $this must have @SymbolName annotation") } } + // TODO: check that only external function has @SymbolName. + this.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let { val name = getStringValue(it) ?: this.name.asString() diff --git a/runtime/src/launcher/kotlin/konan/start.kt b/runtime/src/launcher/kotlin/konan/start.kt index 2bb43656695..658e168dfeb 100644 --- a/runtime/src/launcher/kotlin/konan/start.kt +++ b/runtime/src/launcher/kotlin/konan/start.kt @@ -2,13 +2,14 @@ * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE file. */ + import kotlin.native.internal.ExportForCppRuntime // This function is produced by the code generator given // the '-entry foo.bar.main' flag. // It calls the requested entry point. // The default is main(Array):Unit in the root package. -@ExportForCppRuntime +@SymbolName("EntryPointSelector") external fun EntryPointSelector(args: Array) @ExportForCppRuntime