[JS IR BE] Cast types in bridges

This commit is contained in:
Svyatoslav Kuzmich
2018-07-25 15:44:50 +03:00
parent 97faff246d
commit 439350d41a
4 changed files with 19 additions and 14 deletions
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.ir.backend.js.lower package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.bridges.Bridge
import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle
import org.jetbrains.kotlin.backend.common.bridges.generateBridges import org.jetbrains.kotlin.backend.common.bridges.generateBridges
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
@@ -30,11 +29,12 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.isStatic import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.isStatic
import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.toKotlinType import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.createParameterDeclarations import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.isInterface
@@ -112,17 +112,17 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass {
val bridgeDescriptorForIrFunction = SimpleFunctionDescriptorImpl.create( val bridgeDescriptorForIrFunction = SimpleFunctionDescriptorImpl.create(
containingClass, containingClass,
Annotations.EMPTY, Annotations.EMPTY, // TODO: Should we copy annotations?
bridge.name, bridge.name,
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
function.descriptor.source) function.descriptor.source
)
// TODO: should copy modality
bridgeDescriptorForIrFunction.initialize( bridgeDescriptorForIrFunction.initialize(
bridge.descriptor.extensionReceiverParameter?.returnType, containingClass.thisAsReceiverParameter, bridge.descriptor.extensionReceiverParameter?.returnType, containingClass.thisAsReceiverParameter,
bridge.descriptor.typeParameters, bridge.descriptor.typeParameters,
bridge.descriptor.valueParameters.map { it.copy(bridgeDescriptorForIrFunction, it.name, it.index) }, bridge.descriptor.valueParameters.map { it.copy(bridgeDescriptorForIrFunction, it.name, it.index) },
bridge.descriptor.returnType, Modality.OPEN, function.visibility bridge.descriptor.returnType, bridge.descriptor.modality, function.visibility
) )
// TODO: Support offsets for debug info // TODO: Support offsets for debug info
@@ -130,15 +130,14 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass {
irFunction.createParameterDeclarations() irFunction.createParameterDeclarations()
irFunction.returnType = bridge.returnType irFunction.returnType = bridge.returnType
// TODO: Add type casts
context.createIrBuilder(irFunction.symbol).irBlockBody(irFunction) { context.createIrBuilder(irFunction.symbol).irBlockBody(irFunction) {
val call = irCall(delegateTo.symbol) val call = irCall(delegateTo.symbol)
call.dispatchReceiver = irGet(irFunction.dispatchReceiverParameter!!) call.dispatchReceiver = irGet(irFunction.dispatchReceiverParameter!!)
irFunction.extensionReceiverParameter?.let { irFunction.extensionReceiverParameter?.let {
call.extensionReceiver = irGet(it) call.extensionReceiver = irCastIfNeeded(irGet(it), delegateTo.extensionReceiverParameter!!.type)
} }
irFunction.valueParameters.mapIndexed { i, valueParameter -> irFunction.valueParameters.mapIndexed { i, valueParameter ->
call.putValueArgument(i, irGet(valueParameter)) call.putValueArgument(i, irCastIfNeeded(irGet(valueParameter), delegateTo.valueParameters[i].type))
} }
+irReturn(call) +irReturn(call)
}.apply { }.apply {
@@ -147,6 +146,9 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass {
return irFunction return irFunction
} }
private fun IrBlockBodyBuilder.irCastIfNeeded(argument: IrExpression, type: IrType): IrExpression =
if (argument.type.classifierOrNull == type.classifierOrNull) argument else irAs(argument, type)
} }
// Handle for common.bridges // Handle for common.bridges
@@ -157,10 +159,10 @@ data class IrBasedFunctionHandle(val function: IrSimpleFunction) : FunctionHandl
override val isAbstract: Boolean = override val isAbstract: Boolean =
function.modality == Modality.ABSTRACT function.modality == Modality.ABSTRACT
override val isInterfaceDeclaration= override val isInterfaceDeclaration =
function.parentAsClass.isInterface function.parentAsClass.isInterface
override fun getOverridden()= override fun getOverridden() =
function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) } function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) }
} }
@@ -180,7 +182,7 @@ class FunctionAndSignature(val function: IrSimpleFunction) {
private val signature = Signature( private val signature = Signature(
function.name, function.name,
function.extensionReceiverParameter?.type?.toKotlinType()?.toString(), function.extensionReceiverParameter?.type?.toKotlinType()?.toString(),
function.valueParameters.map { it.type.toKotlinType()?.toString() } function.valueParameters.map { it.type.toKotlinType().toString() }
) )
override fun equals(other: Any?) = override fun equals(other: Any?) =
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: NATIVE // IGNORE_BACKEND: NATIVE
// IGNORE_BACKEND: JS_IR
class StrList : List<String?> { class StrList : List<String?> {
override val size: Int override val size: Int
@@ -1,3 +1,4 @@
// IGNORE_BACKEND: JS_IR
private object EmptyMap : Map<Any, Nothing> { private object EmptyMap : Map<Any, Nothing> {
override val size: Int get() = 0 override val size: Int get() = 0
override fun isEmpty(): Boolean = true override fun isEmpty(): Boolean = true
@@ -1,3 +1,4 @@
// IGNORE_BACKEND: JS_IR
private object EmptyStringMap : Map<String, Nothing> { private object EmptyStringMap : Map<String, Nothing> {
override val size: Int get() = 0 override val size: Int get() = 0
override fun isEmpty(): Boolean = true override fun isEmpty(): Boolean = true