Avoid hanging external functions. (#2265)

This commit is contained in:
Nikolay Igotti
2018-10-30 18:47:38 +03:00
committed by GitHub
parent d02a51ba98
commit 0a43fa21d3
5 changed files with 29 additions and 22 deletions
@@ -461,12 +461,3 @@ typealias CArrayPointerVar<T> = CPointerVar<T>
* The C function. * The C function.
*/ */
class CFunction<T : Function<*>>(rawPtr: NativePtr) : CPointed(rawPtr) class CFunction<T : Function<*>>(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 <F : Function<*>> staticCFunction(function: F): CPointer<CFunction<F>>
@@ -602,7 +602,7 @@ class StubGenerator(
} else { } else {
sequenceOf( sequenceOf(
annotationForUnableToImport, annotationForUnableToImport,
"external $header" "$header = throw UnsupportedOperationException()"
) )
} }
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.konan.llvm package org.jetbrains.kotlin.backend.konan.llvm
import llvm.LLVMTypeRef 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.descriptors.isAbstract
import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.isInlined 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 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 cnameAnnotation = FqName("kotlin.native.CName")
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime") private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
@@ -205,13 +209,17 @@ internal val FunctionDescriptor.symbolName: String
if (!this.isExported()) { if (!this.isExported()) {
throw AssertionError(this.descriptor.toString()) 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)!! 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 { this.descriptor.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let {
val name = getStringValue(it) ?: this.name.asString() val name = getStringValue(it) ?: this.name.asString()
return name // no wrapping currently required return name // no wrapping currently required
@@ -24,7 +24,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty 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 is FunctionDescriptor
-> this.uniqueName -> this.uniqueName
is PropertyDescriptor is PropertyDescriptor
@@ -35,7 +37,7 @@ internal fun DeclarationDescriptor.symbolName(): String = when (this) {
} }
internal val DeclarationDescriptor.uniqId internal val DeclarationDescriptor.uniqId
get() = this.symbolName().localHash.value get() = this.symbolName.localHash.value
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this) 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 symbolNameAnnotation = FqName("kotlin.native.SymbolName")
private val intrinsicAnnotation = FqName("kotlin.native.internal.Intrinsic")
private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime") private val exportForCppRuntimeAnnotation = FqName("kotlin.native.internal.ExportForCppRuntime")
private val cnameAnnotation = FqName("kotlin.native.internal.CName") private val cnameAnnotation = FqName("kotlin.native.internal.CName")
@@ -244,13 +248,16 @@ private val FunctionDescriptor.uniqueName: String
throw AssertionError(this.toString()) throw AssertionError(this.toString())
} }
this.annotations.findAnnotation(symbolNameAnnotation)?.let { if (this.isExternal) {
if (this.isExternal) { this.annotations.findAnnotation(symbolNameAnnotation)?.let {
return getStringValue(it)!! 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 { this.annotations.findAnnotation(exportForCppRuntimeAnnotation)?.let {
val name = getStringValue(it) ?: this.name.asString() val name = getStringValue(it) ?: this.name.asString()
+2 -1
View File
@@ -2,13 +2,14 @@
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license * 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. * that can be found in the LICENSE file.
*/ */
import kotlin.native.internal.ExportForCppRuntime import kotlin.native.internal.ExportForCppRuntime
// This function is produced by the code generator given // This function is produced by the code generator given
// the '-entry foo.bar.main' flag. // the '-entry foo.bar.main' flag.
// It calls the requested entry point. // It calls the requested entry point.
// The default is main(Array<String>):Unit in the root package. // The default is main(Array<String>):Unit in the root package.
@ExportForCppRuntime @SymbolName("EntryPointSelector")
external fun EntryPointSelector(args: Array<String>) external fun EntryPointSelector(args: Array<String>)
@ExportForCppRuntime @ExportForCppRuntime