backend.native: support external functions
also implement changing external function symbol name with the annotation
This commit is contained in:
+4
@@ -11,6 +11,10 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
|||||||
var currentFunction:FunctionDescriptor? = null
|
var currentFunction:FunctionDescriptor? = null
|
||||||
|
|
||||||
fun function(declaration: IrFunction) {
|
fun function(declaration: IrFunction) {
|
||||||
|
if (declaration.descriptor.isExternal) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
currentFunction = declaration.descriptor
|
currentFunction = declaration.descriptor
|
||||||
val fn = LLVMAddFunction(context.llvmModule, declaration.descriptor.symbolName, getLlvmFunctionType(declaration.descriptor))
|
val fn = LLVMAddFunction(context.llvmModule, declaration.descriptor.symbolName, getLlvmFunctionType(declaration.descriptor))
|
||||||
|
|||||||
+15
@@ -34,6 +34,12 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
|||||||
|
|
||||||
override fun visitClass(declaration: IrClass) {
|
override fun visitClass(declaration: IrClass) {
|
||||||
super.visitClass(declaration)
|
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)
|
generator.generate(declaration.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,6 +56,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
element.acceptChildrenVoid(this)
|
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) {
|
override fun visitSetVariable(expression: IrSetVariable) {
|
||||||
val value = evaluateExpression(generator.tmpVariable(), expression.value)
|
val value = evaluateExpression(generator.tmpVariable(), expression.value)
|
||||||
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
||||||
|
|||||||
+15
-1
@@ -2,10 +2,24 @@ package org.jetbrains.kotlin.backend.native.llvm
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
|
||||||
|
private val symbolNameAnnotation = FqName("kotlin_native.SymbolName")
|
||||||
|
|
||||||
internal val FunctionDescriptor.symbolName: String
|
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
|
internal val ClassDescriptor.typeInfoSymbolName: String
|
||||||
get() = "ktype:" + this.fqNameSafe.toString()
|
get() = "ktype:" + this.fqNameSafe.toString()
|
||||||
@@ -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