[WASM] Make object creation inside constructors

This commit is contained in:
Igor Yakovlev
2022-10-28 10:26:12 +02:00
committed by teamcity
parent 346b2f162c
commit 0e54e00e48
2 changed files with 27 additions and 10 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.wasm.utils.*
import org.jetbrains.kotlin.backend.wasm.utils.isCanonical
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.backend.js.lower.PrimaryConstructorLowering
import org.jetbrains.kotlin.ir.backend.js.utils.erasedUpperBound
import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver
@@ -262,9 +263,8 @@ class BodyGenerator(
return
}
generateAnyParameters(klassSymbol)
if (expression.symbol.owner.hasWasmPrimitiveConstructorAnnotation()) {
generateAnyParameters(klassSymbol)
for (i in 0 until expression.valueArgumentsCount) {
generateExpression(expression.getValueArgument(i)!!)
}
@@ -272,14 +272,7 @@ class BodyGenerator(
return
}
val irFields: List<IrField> = klass.allFields(backendContext.irBuiltIns)
irFields.forEachIndexed { index, field ->
if (index > 1) {
generateDefaultInitializerForType(context.transformType(field.type), body)
}
}
body.buildStructNew(wasmGcType)
body.buildRefNull(WasmHeapType.Simple.NullNone) // this = null
generateCall(expression)
}
@@ -296,6 +289,26 @@ class BodyGenerator(
body.buildConstI32(0) // Any::_hashCode
}
fun generateObjectCreationPrefixIfNeeded(constructor: IrConstructor) {
val parentClass = constructor.parentAsClass
if (constructor.origin == PrimaryConstructorLowering.SYNTHETIC_PRIMARY_CONSTRUCTOR) return
if (parentClass.isAbstractOrSealed) return
val thisParameter = context.referenceLocal(parentClass.thisReceiver!!.symbol)
body.buildGetLocal(thisParameter)
body.buildInstr(WasmOp.REF_IS_NULL)
body.buildIf("this_init")
generateAnyParameters(parentClass.symbol)
val irFields: List<IrField> = parentClass.allFields(backendContext.irBuiltIns)
irFields.forEachIndexed { index, field ->
if (index > 1) {
generateDefaultInitializerForType(context.transformType(field.type), body)
}
}
body.buildStructNew(context.referenceGcType(parentClass.symbol))
body.buildSetLocal(thisParameter)
body.buildEnd()
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
val klass = context.irFunction.parentAsClass
@@ -133,6 +133,10 @@ class DeclarationGenerator(
isGetUnitFunction = declaration == unitGetInstanceFunction
)
if (declaration is IrConstructor) {
bodyBuilder.generateObjectCreationPrefixIfNeeded(declaration)
}
require(declaration.body is IrBlockBody) { "Only IrBlockBody is supported" }
declaration.body?.acceptVoid(bodyBuilder)