From e3f826d1b9e9d18938c818c522d43ca0eb5af6e1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Mon, 11 Oct 2021 15:53:29 +0300 Subject: [PATCH] [Wasm] Handle IrClass::thisReceiver receiver outside of constructors --- .../kotlin/backend/wasm/ir2wasm/BodyGenerator.kt | 12 ++++++++++-- .../EraseVirtualDispatchReceiverParametersTypes.kt | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt index 87eb589edae..21eb87599f7 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/BodyGenerator.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.wasm.utils.* import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction +import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* @@ -175,9 +176,16 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV override fun visitGetValue(expression: IrGetValue) { val valueSymbol = expression.symbol - body.buildGetLocal(context.referenceLocal(valueSymbol)) - val valueDeclaration = valueSymbol.owner + body.buildGetLocal( + // Handle cases when IrClass::thisReceiver is referenced instead + // of the value parameter of current function + if (valueDeclaration.isDispatchReceiver) + context.referenceLocal(0) + else + context.referenceLocal(valueSymbol) + ) + if (valueSymbol.owner is IrValueParameter) { val parent = valueDeclaration.parent if (parent is IrFunction && parent.isExported(backendContext)) { diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/EraseVirtualDispatchReceiverParametersTypes.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/EraseVirtualDispatchReceiverParametersTypes.kt index 0d35ca81db3..2e4c2ff27e3 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/EraseVirtualDispatchReceiverParametersTypes.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/EraseVirtualDispatchReceiverParametersTypes.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.types.isAny import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -76,10 +77,12 @@ class EraseVirtualDispatchReceiverParametersTypes(val context: CommonBackendCont val newReceiver = oldReceiver.copyTo(irFunction, type = context.irBuiltIns.anyType) irFunction.dispatchReceiverParameter = newReceiver + val classThisReceiverSymbol = irFunction.parentAsClass.thisReceiver?.symbol + // Cast receiver usages back to original type irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitGetValue(expression: IrGetValue): IrExpression { - if (expression.symbol == oldReceiver.symbol) { + if (expression.symbol == oldReceiver.symbol || expression.symbol == classThisReceiverSymbol) { return with(builder) { irImplicitCast(irGet(newReceiver), originalReceiverType) }