Interop, backend: refactor and reorder interop lowering

* Do not break type compatibility when lowering interop intrinsics.
* Place interop lowering before callable reference lowering.
* Add other improvements to interop implementation.
This commit is contained in:
Svyatoslav Scherbina
2017-02-22 14:09:44 +07:00
committed by SvyatoslavScherbina
parent 6c627a0b55
commit 3411ce2e8c
12 changed files with 118 additions and 115 deletions
@@ -6,6 +6,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.TypeUtils
private val cPointerName = "CPointer"
private val nativePointedName = "NativePointed"
@@ -37,12 +38,26 @@ internal class InteropBuiltIns(builtIns: KonanBuiltIns) {
val cPointerRawValue = cPointer.unsubstitutedMemberScope.getContributedVariables("rawValue").single()
val cPointerGetRawValue = packageScope.getContributedFunctions("getRawValue").single {
val extensionReceiverParameter = it.extensionReceiverParameter
extensionReceiverParameter != null &&
TypeUtils.getClassDescriptor(extensionReceiverParameter.type) == cPointer
}
val nativePointedRawPtrGetter =
nativePointed.unsubstitutedMemberScope.getContributedVariables("rawPtr").single().getter!!
val nativePointedGetRawPointer = packageScope.getContributedFunctions("getRawPointer").single {
val extensionReceiverParameter = it.extensionReceiverParameter
extensionReceiverParameter != null &&
TypeUtils.getClassDescriptor(extensionReceiverParameter.type) == nativePointed
}
val memberAt = packageScope.getContributedFunctions("memberAt").single()
val interpretPointed = packageScope.getContributedFunctions("interpretPointed").single()
val interpretNullablePointed = packageScope.getContributedFunctions("interpretNullablePointed").single()
val interpretCPointer = packageScope.getContributedFunctions("interpretCPointer").single()
val arrayGetByIntIndex = packageScope.getContributedFunctions("get").single {
KotlinBuiltIns.isInt(it.valueParameters.single().type)
@@ -48,6 +48,9 @@ internal class KonanLower(val context: Context) {
phaser.phase(KonanPhase.LOWER_INNER_CLASSES) {
InnerClassLowering(context).runOnFilePostfix(irFile)
}
phaser.phase(KonanPhase.LOWER_INTEROP) {
InteropLowering(context).lower(irFile)
}
phaser.phase(KonanPhase.LOWER_CALLABLES) {
CallableReferenceLowering(context).runOnFilePostfix(irFile)
}
@@ -62,8 +65,5 @@ internal class KonanLower(val context: Context) {
phaser.phase(KonanPhase.AUTOBOX) {
Autoboxing(context).lower(irFile)
}
phaser.phase(KonanPhase.LOWER_INTEROP) {
InteropLowering(context).lower(irFile)
}
}
}
@@ -1661,6 +1661,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
val interop = context.interopBuiltIns
return when (descriptor) {
interop.interpretNullablePointed, interop.interpretCPointer,
interop.nativePointedGetRawPointer, interop.cPointerGetRawValue -> args.single()
in interop.readPrimitive -> {
val pointerType = pointerType(codegen.getLLVMType(descriptor.returnType!!))
val rawPointer = args.last()
@@ -148,20 +148,25 @@ private class InteropTransformer(val context: Context) : IrBuildingTransformer(c
if (descriptor is ClassConstructorDescriptor) {
val type = descriptor.constructedClass.defaultType
if (type.isRepresentedAs(ValueType.C_POINTER) || type.isRepresentedAs(ValueType.NATIVE_POINTED)) {
return expression.getValueArgument(0)!!
throw Error("Native interop types constructors must not be called directly")
}
}
if (descriptor == interop.nativePointedRawPtrGetter ||
OverridingUtil.overrides(descriptor, interop.nativePointedRawPtrGetter)) {
return expression.dispatchReceiver!!
// Replace by the intrinsic call to be handled by code generator:
return builder.irCall(interop.nativePointedGetRawPointer).apply {
extensionReceiver = expression.dispatchReceiver
}
}
return when (descriptor) {
interop.cPointerRawValue.getter -> expression.dispatchReceiver!!
interop.interpretPointed -> expression.getValueArgument(0)!!
interop.cPointerRawValue.getter ->
// Replace by the intrinsic call to be handled by code generator:
builder.irCall(interop.cPointerGetRawValue).apply {
extensionReceiver = expression.dispatchReceiver
}
interop.arrayGetByIntIndex, interop.arrayGetByLongIndex -> {
val array = expression.extensionReceiver!!