backend.konan: support function types in codegen
This commit is contained in:
committed by
SvyatoslavScherbina
parent
2fa2727935
commit
b5ffc48547
+1
@@ -154,6 +154,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
||||
fun lastBasicBlock(): LLVMBasicBlockRef? = LLVMGetLastBasicBlock(currentFunction!!.llvmFunction)
|
||||
|
||||
fun functionLlvmValue(descriptor: FunctionDescriptor) = descriptor.llvmFunction
|
||||
fun functionEntryPointAddress(descriptor: FunctionDescriptor) = descriptor.entryPointAddress.llvm
|
||||
fun functionHash(descriptor: FunctionDescriptor): LLVMValueRef = descriptor.functionName.localHash.llvm
|
||||
|
||||
fun br(bbLabel: LLVMBasicBlockRef): LLVMValueRef {
|
||||
|
||||
+2
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.kotlin.backend.konan.llvm
|
||||
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.isUnboundCallableReference
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -8,6 +9,7 @@ internal fun ContextUtils.getLLVMType(type: KotlinType): LLVMTypeRef {
|
||||
return when {
|
||||
// Nullable types must be represented as objects for boxing.
|
||||
type.isMarkedNullable -> this.kObjHeaderPtr
|
||||
type.isUnboundCallableReference() -> int8TypePtr
|
||||
KotlinBuiltIns.isBoolean(type) -> LLVMInt1Type()
|
||||
KotlinBuiltIns.isByte(type) -> LLVMInt8Type()
|
||||
KotlinBuiltIns.isShort(type) || KotlinBuiltIns.isChar(type) -> LLVMInt16Type()
|
||||
|
||||
+42
@@ -4,6 +4,7 @@ import kotlinx.cinterop.*
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -607,12 +608,14 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
is IrTry -> return evaluateTry ( value)
|
||||
is IrStringConcatenation -> return evaluateStringConcatenation(tmpVariableName, value)
|
||||
is IrBlockBody -> return evaluateBlock (tmpVariableName, value as IrStatementContainer)
|
||||
is IrComposite -> return evaluateBlock (tmpVariableName, value)
|
||||
is IrWhileLoop -> return evaluateWhileLoop ( value)
|
||||
is IrDoWhileLoop -> return evaluateDoWhileLoop ( value)
|
||||
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
||||
is IrBreak -> return evaluateBreak ( value)
|
||||
is IrContinue -> return evaluateContinue ( value)
|
||||
is IrGetObjectValue -> return evaluateGetObjectValue (tmpVariableName, value)
|
||||
is IrCallableReference -> return evaluateCallableReference (tmpVariableName, value)
|
||||
null -> return null
|
||||
else -> {
|
||||
TODO("${ir2string(value)}")
|
||||
@@ -1549,9 +1552,19 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateCallableReference(tmpVariableName: String, expression: IrCallableReference): LLVMValueRef {
|
||||
assert (expression.type.isUnboundCallableReference())
|
||||
assert (expression.getArguments().isEmpty())
|
||||
val entry = codegen.functionEntryPointAddress(expression.descriptor as FunctionDescriptor)
|
||||
return entry
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateFunctionCall(tmpVariableName: String, callee: IrCall, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
val descriptor:FunctionDescriptor = callee.descriptor as FunctionDescriptor
|
||||
when (descriptor) {
|
||||
is FunctionInvokeDescriptor -> return evaluateFunctionInvoke (tmpVariableName, descriptor, args)
|
||||
is IrBuiltinOperatorDescriptorBase -> return evaluateOperatorCall (tmpVariableName, callee, args)
|
||||
is ClassConstructorDescriptor -> return evaluateConstructorCall (tmpVariableName, callee, args)
|
||||
else -> return evaluateSimpleFunctionCall(tmpVariableName, descriptor, args)
|
||||
@@ -1560,6 +1573,35 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private val functionImplUnboundRefGetter by lazy {
|
||||
context.builtIns.getKonanInternalClass("FunctionImpl")
|
||||
.unsubstitutedMemberScope.getContributedDescriptors()
|
||||
.filterIsInstance<PropertyDescriptor>()
|
||||
.single { it.name.asString() == "unboundRef" }
|
||||
.getter!!
|
||||
}
|
||||
|
||||
private fun evaluateFunctionInvoke(tmpVariableName: String,
|
||||
descriptor: FunctionInvokeDescriptor,
|
||||
args: List<LLVMValueRef>): LLVMValueRef {
|
||||
|
||||
// Note: the whole function code below is written in the assumption that
|
||||
// `invoke` method receiver is passed as first argument.
|
||||
|
||||
val functionImpl = args[0]
|
||||
|
||||
val unboundRefType = codegen.getLlvmFunctionType(descriptor)
|
||||
|
||||
val unboundRef = evaluateSimpleFunctionCall(codegen.newVar(),
|
||||
functionImplUnboundRefGetter, listOf(functionImpl))
|
||||
|
||||
val entryPtr = codegen.bitcast(pointerType(unboundRefType), unboundRef, "entry")
|
||||
|
||||
return call(descriptor, entryPtr, args, tmpVariableName)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateSimpleFunctionCall(tmpVariableName: String, descriptor: FunctionDescriptor, args: List<LLVMValueRef>): LLVMValueRef {
|
||||
//logger.log("evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}")
|
||||
if (descriptor.isOverridable)
|
||||
|
||||
Reference in New Issue
Block a user