[Wasm] Remove Wasm*CodegenContext interfaces

Use classes instead
This commit is contained in:
Svyatoslav Kuzmich
2022-12-09 15:37:52 +01:00
parent 1d30ce9662
commit b9b2723b0a
9 changed files with 94 additions and 208 deletions
@@ -31,11 +31,12 @@ import org.jetbrains.kotlin.wasm.ir.source.location.SourceLocation
import org.jetbrains.kotlin.wasm.ir.source.location.withLocation
class BodyGenerator(
val context: WasmFunctionCodegenContext,
val context: WasmModuleCodegenContextImpl,
val functionContext: WasmFunctionCodegenContextImpl,
private val hierarchyDisjointUnions: DisjointUnions<IrClassSymbol>,
private val isGetUnitFunction: Boolean,
) : IrElementVisitorVoid {
val body: WasmExpressionBuilder = context.bodyGen
val body: WasmExpressionBuilder = functionContext.bodyGen
// Shortcuts
private val backendContext: WasmBackendContext = context.backendContext
@@ -131,7 +132,7 @@ class BodyGenerator(
override fun visitThrow(expression: IrThrow) {
generateExpression(expression.value)
body.buildThrow(context.tagIdx)
body.buildThrow(functionContext.tagIdx)
}
override fun visitTry(aTry: IrTry) {
@@ -141,12 +142,12 @@ class BodyGenerator(
body.buildTry(null, resultType)
generateExpression(aTry.tryResult)
body.buildCatch(context.tagIdx)
body.buildCatch(functionContext.tagIdx)
// Exception object is on top of the stack, store it into the local
aTry.catches.single().catchParameter.symbol.let {
context.defineLocal(it)
body.buildSetLocal(context.referenceLocal(it))
functionContext.defineLocal(it)
body.buildSetLocal(functionContext.referenceLocal(it))
}
generateExpression(aTry.catches.single().result)
@@ -229,15 +230,15 @@ class BodyGenerator(
// Handle cases when IrClass::thisReceiver is referenced instead
// of the value parameter of current function
if (valueDeclaration.isDispatchReceiver)
context.referenceLocal(0)
functionContext.referenceLocal(0)
else
context.referenceLocal(valueSymbol)
functionContext.referenceLocal(valueSymbol)
)
}
override fun visitSetValue(expression: IrSetValue) {
generateExpression(expression.value)
body.buildSetLocal(context.referenceLocal(expression.symbol))
body.buildSetLocal(functionContext.referenceLocal(expression.symbol))
body.buildGetUnit()
}
@@ -295,7 +296,7 @@ class BodyGenerator(
val parentClass = constructor.parentAsClass
if (constructor.origin == PrimaryConstructorLowering.SYNTHETIC_PRIMARY_CONSTRUCTOR) return
if (parentClass.isAbstractOrSealed) return
val thisParameter = context.referenceLocal(parentClass.thisReceiver!!.symbol)
val thisParameter = functionContext.referenceLocal(parentClass.thisReceiver!!.symbol)
body.buildGetLocal(thisParameter)
body.buildInstr(WasmOp.REF_IS_NULL)
body.buildIf("this_init")
@@ -312,7 +313,7 @@ class BodyGenerator(
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
val klass = context.irFunction.parentAsClass
val klass = functionContext.irFunction.parentAsClass
// Don't delegate constructors of Any to Any.
if (klass.defaultType.isAny()) {
@@ -320,7 +321,7 @@ class BodyGenerator(
return
}
body.buildGetLocal(context.referenceLocal(0)) // this parameter
body.buildGetLocal(functionContext.referenceLocal(0)) // this parameter
generateCall(expression)
}
@@ -490,7 +491,7 @@ class BodyGenerator(
assert(irInterface.isInterface)
if (irInterface.symbol in hierarchyDisjointUnions) {
val classITable = context.referenceClassITableGcType(irInterface.symbol)
val parameterLocal = context.referenceLocal(SyntheticLocalType.IS_INTERFACE_PARAMETER)
val parameterLocal = functionContext.referenceLocal(SyntheticLocalType.IS_INTERFACE_PARAMETER)
body.buildSetLocal(parameterLocal)
body.buildBlock("isInterface", WasmI32) { outerLabel ->
body.buildBlock("isInterface", WasmRefNullType(WasmHeapType.Simple.Data)) { innerLabel ->
@@ -598,7 +599,7 @@ class BodyGenerator(
}
if (expression is IrReturnableBlock) {
context.defineNonLocalReturnLevel(
functionContext.defineNonLocalReturnLevel(
expression.symbol,
body.buildBlock(context.transformBlockResultType(expression.type))
)
@@ -626,12 +627,12 @@ class BodyGenerator(
override fun visitBreak(jump: IrBreak) {
assert(jump.type == irBuiltIns.nothingType)
body.buildBr(context.referenceLoopLevel(jump.loop, LoopLabelType.BREAK))
body.buildBr(functionContext.referenceLoopLevel(jump.loop, LoopLabelType.BREAK))
}
override fun visitContinue(jump: IrContinue) {
assert(jump.type == irBuiltIns.nothingType)
body.buildBr(context.referenceLoopLevel(jump.loop, LoopLabelType.CONTINUE))
body.buildBr(functionContext.referenceLoopLevel(jump.loop, LoopLabelType.CONTINUE))
}
private fun visitFunctionReturn(expression: IrReturn) {
@@ -646,8 +647,8 @@ class BodyGenerator(
}
}
if (context.irFunction is IrConstructor) {
body.buildGetLocal(context.referenceLocal(0))
if (functionContext.irFunction is IrConstructor) {
body.buildGetLocal(functionContext.referenceLocal(0))
}
body.buildInstr(WasmOp.RETURN, expression.getSourceLocation())
@@ -734,7 +735,7 @@ class BodyGenerator(
val nonLocalReturnSymbol = expression.returnTargetSymbol as? IrReturnableBlockSymbol
if (nonLocalReturnSymbol != null) {
generateWithExpectedType(expression.value, nonLocalReturnSymbol.owner.type)
body.buildBr(context.referenceNonLocalReturnLevel(nonLocalReturnSymbol))
body.buildBr(functionContext.referenceNonLocalReturnLevel(nonLocalReturnSymbol))
body.buildUnreachable()
} else {
visitFunctionReturn(expression)
@@ -793,8 +794,8 @@ class BodyGenerator(
body.buildLoop(label) { wasmLoop ->
body.buildBlock("BREAK_$label") { wasmBreakBlock ->
body.buildBlock("CONTINUE_$label") { wasmContinueBlock ->
context.defineLoopLevel(loop, LoopLabelType.BREAK, wasmBreakBlock)
context.defineLoopLevel(loop, LoopLabelType.CONTINUE, wasmContinueBlock)
functionContext.defineLoopLevel(loop, LoopLabelType.BREAK, wasmBreakBlock)
functionContext.defineLoopLevel(loop, LoopLabelType.CONTINUE, wasmContinueBlock)
loop.body?.let { generateStatement(it) }
}
generateExpression(loop.condition)
@@ -816,8 +817,8 @@ class BodyGenerator(
body.buildLoop(label) { wasmLoop ->
body.buildBlock("BREAK_$label") { wasmBreakBlock ->
context.defineLoopLevel(loop, LoopLabelType.BREAK, wasmBreakBlock)
context.defineLoopLevel(loop, LoopLabelType.CONTINUE, wasmLoop)
functionContext.defineLoopLevel(loop, LoopLabelType.BREAK, wasmBreakBlock)
functionContext.defineLoopLevel(loop, LoopLabelType.CONTINUE, wasmLoop)
generateExpression(loop.condition)
body.buildInstr(WasmOp.I32_EQZ)
@@ -833,13 +834,13 @@ class BodyGenerator(
}
override fun visitVariable(declaration: IrVariable) {
context.defineLocal(declaration.symbol)
functionContext.defineLocal(declaration.symbol)
if (declaration.initializer == null) {
return
}
val init = declaration.initializer!!
generateExpression(init)
val varName = context.referenceLocal(declaration.symbol)
val varName = functionContext.referenceLocal(declaration.symbol)
body.buildSetLocal(varName)
}
@@ -889,7 +890,7 @@ class BodyGenerator(
}
private fun IrExpression.getSourceLocation(): SourceLocation {
val fileEntry = context.irFunction.fileEntry
val fileEntry = functionContext.irFunction.fileEntry
val path = fileEntry.name
val startLine = fileEntry.getLineNumber(startOffset)
val startColumn = fileEntry.getColumnNumber(startOffset)
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.wasm.ir.*
class DeclarationGenerator(
val context: WasmModuleCodegenContext,
val context: WasmModuleCodegenContextImpl,
private val allowIncompleteImplementations: Boolean,
private val hierarchyDisjointUnions: DisjointUnions<IrClassSymbol>,
) : IrElementVisitorVoid {
@@ -128,7 +128,8 @@ class DeclarationGenerator(
val exprGen = functionCodegenContext.bodyGen
val bodyBuilder = BodyGenerator(
context = functionCodegenContext,
context = context,
functionContext = functionCodegenContext,
hierarchyDisjointUnions = hierarchyDisjointUnions,
isGetUnitFunction = declaration == unitGetInstanceFunction
)
@@ -476,7 +477,7 @@ fun IrFunction.isExported(): Boolean =
isJsExport()
fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmBaseCodegenContext) {
fun generateConstExpression(expression: IrConst<*>, body: WasmExpressionBuilder, context: WasmModuleCodegenContextImpl) {
when (val kind = expression.kind) {
is IrConstKind.Null -> {
val bottomType = if (expression.type.getClass()?.isExternal == true) WasmRefNullExternrefType else WasmRefNullNoneType
@@ -57,7 +57,7 @@ internal fun BodyGenerator.tryGenerateOptimisedWhen(expression: IrWhen, symbols:
val minValue = intBranches.minOf { branch -> branch.conditions.minOf { it.const.value } }
if (minValue == maxValue) return false
val selectorLocal = context.referenceLocal(SyntheticLocalType.TABLE_SWITCH_SELECTOR)
val selectorLocal = functionContext.referenceLocal(SyntheticLocalType.TABLE_SWITCH_SELECTOR)
generateExpression(subject)
body.buildSetLocal(selectorLocal)
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.wasm.ir.*
class WasmTypeTransformer(
val context: WasmBaseCodegenContext,
val context: WasmModuleCodegenContextImpl,
val builtIns: IrBuiltIns
) {
val symbols = context.backendContext.wasmSymbols
@@ -1,55 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.wasm.ir2wasm
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.wasm.ir.*
interface WasmBaseCodegenContext {
val backendContext: WasmBackendContext
val scratchMemAddr: WasmSymbol<Int>
val scratchMemSizeInBytes: Int
val stringPoolSize: WasmSymbol<Int>
fun referenceFunction(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunction>
fun referenceGlobalField(irField: IrFieldSymbol): WasmSymbol<WasmGlobal>
fun referenceGlobalVTable(irClass: IrClassSymbol): WasmSymbol<WasmGlobal>
fun referenceGlobalClassITable(irClass: IrClassSymbol): WasmSymbol<WasmGlobal>
fun referenceGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration>
fun referenceVTableGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration>
fun referenceClassITableGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration>
fun defineClassITableGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration)
fun isAlreadyDefinedClassITableGcType(irClass: IrClassSymbol): Boolean
fun referenceClassITableInterfaceSlot(irClass: IrClassSymbol): WasmSymbol<Int>
fun defineClassITableInterfaceSlot(irClass: IrClassSymbol, slot: Int)
fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType>
fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int>
fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int>
fun referenceStringLiteralAddressAndId(string: String): Pair<WasmSymbol<Int>, WasmSymbol<Int>>
fun referenceConstantArray(resource: Pair<List<Long>, WasmType>): WasmSymbol<Int>
fun transformType(irType: IrType): WasmType
fun transformFieldType(irType: IrType): WasmType
fun transformBoxedType(irType: IrType): WasmType
fun transformValueParameterType(irValueParameter: IrValueParameter): WasmType
fun transformResultType(irType: IrType): WasmType?
fun transformBlockResultType(irType: IrType): WasmType?
fun getStructFieldRef(field: IrField): WasmSymbol<Int>
fun getClassMetadata(irClass: IrClassSymbol): ClassMetadata
fun getInterfaceMetadata(irClass: IrClassSymbol): InterfaceMetadata
}
@@ -1,36 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.wasm.ir2wasm
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.wasm.ir.WasmExpressionBuilder
import org.jetbrains.kotlin.wasm.ir.WasmLocal
enum class LoopLabelType { BREAK, CONTINUE }
enum class SyntheticLocalType { IS_INTERFACE_PARAMETER, TABLE_SWITCH_SELECTOR }
interface WasmFunctionCodegenContext : WasmBaseCodegenContext {
val irFunction: IrFunction
fun defineLocal(irValueDeclaration: IrValueSymbol)
fun referenceLocal(irValueDeclaration: IrValueSymbol): WasmLocal
fun referenceLocal(index: Int): WasmLocal
fun referenceLocal(type: SyntheticLocalType): WasmLocal
fun defineNonLocalReturnLevel(block: IrReturnableBlockSymbol, level: Int)
fun referenceNonLocalReturnLevel(block: IrReturnableBlockSymbol): Int
fun defineLoopLevel(irLoop: IrLoop, labelType: LoopLabelType, level: Int)
fun referenceLoopLevel(irLoop: IrLoop, labelType: LoopLabelType): Int
// So far always a single tag
val tagIdx: Int
val bodyGen: WasmExpressionBuilder
}
@@ -14,17 +14,19 @@ import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.wasm.ir.*
enum class LoopLabelType { BREAK, CONTINUE }
enum class SyntheticLocalType { IS_INTERFACE_PARAMETER, TABLE_SWITCH_SELECTOR }
class WasmFunctionCodegenContextImpl(
override val irFunction: IrFunction,
val irFunction: IrFunction,
private val wasmFunction: WasmFunction.Defined,
override val backendContext: WasmBackendContext,
private val referencing: WasmBaseCodegenContext
) : WasmBaseCodegenContext by referencing,
WasmFunctionCodegenContext {
override val bodyGen: WasmExpressionBuilder =
val backendContext: WasmBackendContext,
val context: WasmModuleCodegenContextImpl,
) {
val bodyGen: WasmExpressionBuilder =
WasmIrExpressionBuilder(wasmFunction.instructions)
override val tagIdx: Int
val tagIdx: Int
get() = 0
private val wasmLocals = LinkedHashMap<IrValueSymbol, WasmLocal>()
@@ -32,14 +34,14 @@ class WasmFunctionCodegenContextImpl(
private val loopLevels = LinkedHashMap<Pair<IrLoop, LoopLabelType>, Int>()
private val nonLocalReturnLevels = LinkedHashMap<IrReturnableBlockSymbol, Int>()
override fun defineLocal(irValueDeclaration: IrValueSymbol) {
fun defineLocal(irValueDeclaration: IrValueSymbol) {
assert(irValueDeclaration !in wasmLocals) { "Redefinition of local" }
val owner = irValueDeclaration.owner
val wasmLocal = WasmLocal(
wasmFunction.locals.size,
owner.name.asString(),
if (owner is IrValueParameter) transformValueParameterType(owner) else transformType(owner.type),
if (owner is IrValueParameter) context.transformValueParameterType(owner) else context.transformType(owner.type),
isParameter = irValueDeclaration is IrValueParameterSymbol
)
@@ -47,21 +49,22 @@ class WasmFunctionCodegenContextImpl(
wasmFunction.locals += wasmLocal
}
override fun referenceLocal(irValueDeclaration: IrValueSymbol): WasmLocal {
fun referenceLocal(irValueDeclaration: IrValueSymbol): WasmLocal {
return wasmLocals.getValue(irValueDeclaration)
}
override fun referenceLocal(index: Int): WasmLocal {
fun referenceLocal(index: Int): WasmLocal {
return wasmFunction.locals[index]
}
private val SyntheticLocalType.wasmType
get() = when (this) {
SyntheticLocalType.IS_INTERFACE_PARAMETER -> WasmRefNullType(WasmHeapType.Type(referenceGcType(backendContext.irBuiltIns.anyClass)))
SyntheticLocalType.IS_INTERFACE_PARAMETER ->
WasmRefNullType(WasmHeapType.Type(context.referenceGcType(backendContext.irBuiltIns.anyClass)))
SyntheticLocalType.TABLE_SWITCH_SELECTOR -> WasmI32
}
override fun referenceLocal(type: SyntheticLocalType): WasmLocal = wasmSyntheticLocals.getOrPut(type) {
fun referenceLocal(type: SyntheticLocalType): WasmLocal = wasmSyntheticLocals.getOrPut(type) {
WasmLocal(
wasmFunction.locals.size,
type.name,
@@ -72,21 +75,21 @@ class WasmFunctionCodegenContextImpl(
}
}
override fun defineNonLocalReturnLevel(block: IrReturnableBlockSymbol, level: Int) {
fun defineNonLocalReturnLevel(block: IrReturnableBlockSymbol, level: Int) {
nonLocalReturnLevels[block] = level
}
override fun referenceNonLocalReturnLevel(block: IrReturnableBlockSymbol): Int {
fun referenceNonLocalReturnLevel(block: IrReturnableBlockSymbol): Int {
return nonLocalReturnLevels.getValue(block)
}
override fun defineLoopLevel(irLoop: IrLoop, labelType: LoopLabelType, level: Int) {
fun defineLoopLevel(irLoop: IrLoop, labelType: LoopLabelType, level: Int) {
val loopKey = Pair(irLoop, labelType)
assert(loopKey !in loopLevels) { "Redefinition of loop" }
loopLevels[loopKey] = level
}
override fun referenceLoopLevel(irLoop: IrLoop, labelType: LoopLabelType): Int {
fun referenceLoopLevel(irLoop: IrLoop, labelType: LoopLabelType): Int {
return loopLevels.getValue(Pair(irLoop, labelType))
}
}
@@ -1,28 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.wasm.ir2wasm
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.wasm.ir.*
/**
* Interface for generating WebAssembly module.
*/
interface WasmModuleCodegenContext : WasmBaseCodegenContext {
fun defineFunction(irFunction: IrFunctionSymbol, wasmFunction: WasmFunction)
fun defineGlobalField(irField: IrFieldSymbol, wasmGlobal: WasmGlobal)
fun defineGlobalVTable(irClass: IrClassSymbol, wasmGlobal: WasmGlobal)
fun defineGlobalClassITable(irClass: IrClassSymbol, wasmGlobal: WasmGlobal)
fun defineGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration)
fun defineVTableGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration)
fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType)
fun addJsFun(importName: String, jsCode: String)
fun registerInitFunction(wasmFunction: WasmFunction, priority: String)
fun addExport(wasmExport: WasmExport<*>)
fun generateTypeInfo(irClass: IrClassSymbol, typeInfo: ConstantDataElement)
}
@@ -16,34 +16,34 @@ import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.wasm.ir.*
class WasmModuleCodegenContextImpl(
override val backendContext: WasmBackendContext,
val backendContext: WasmBackendContext,
private val wasmFragment: WasmCompiledModuleFragment
) : WasmModuleCodegenContext {
) {
private val typeTransformer =
WasmTypeTransformer(this, backendContext.irBuiltIns)
override val scratchMemAddr: WasmSymbol<Int>
val scratchMemAddr: WasmSymbol<Int>
get() = wasmFragment.scratchMemAddr
override val stringPoolSize: WasmSymbol<Int>
val stringPoolSize: WasmSymbol<Int>
get() = wasmFragment.stringPoolSize
override val scratchMemSizeInBytes: Int
val scratchMemSizeInBytes: Int
get() = wasmFragment.scratchMemSizeInBytes
override fun transformType(irType: IrType): WasmType {
fun transformType(irType: IrType): WasmType {
return with(typeTransformer) { irType.toWasmValueType() }
}
override fun transformFieldType(irType: IrType): WasmType {
fun transformFieldType(irType: IrType): WasmType {
return with(typeTransformer) { irType.toWasmFieldType() }
}
override fun transformBoxedType(irType: IrType): WasmType {
fun transformBoxedType(irType: IrType): WasmType {
return with(typeTransformer) { irType.toBoxedInlineClassType() }
}
override fun transformValueParameterType(irValueParameter: IrValueParameter): WasmType {
fun transformValueParameterType(irValueParameter: IrValueParameter): WasmType {
return with(typeTransformer) {
if (context.backendContext.inlineClassesUtils.shouldValueParameterBeBoxed(irValueParameter)) {
irValueParameter.type.toBoxedInlineClassType()
@@ -53,65 +53,65 @@ class WasmModuleCodegenContextImpl(
}
}
override fun transformResultType(irType: IrType): WasmType? {
fun transformResultType(irType: IrType): WasmType? {
return with(typeTransformer) { irType.toWasmResultType() }
}
override fun transformBlockResultType(irType: IrType): WasmType? {
fun transformBlockResultType(irType: IrType): WasmType? {
return with(typeTransformer) { irType.toWasmBlockResultType() }
}
override fun referenceStringLiteralAddressAndId(string: String): Pair<WasmSymbol<Int>, WasmSymbol<Int>> {
fun referenceStringLiteralAddressAndId(string: String): Pair<WasmSymbol<Int>, WasmSymbol<Int>> {
val address = wasmFragment.stringLiteralAddress.reference(string)
val id = wasmFragment.stringLiteralPoolId.reference(string)
return address to id
}
override fun referenceConstantArray(resource: Pair<List<Long>, WasmType>): WasmSymbol<Int> =
fun referenceConstantArray(resource: Pair<List<Long>, WasmType>): WasmSymbol<Int> =
wasmFragment.constantArrayDataSegmentId.reference(resource)
override fun generateTypeInfo(irClass: IrClassSymbol, typeInfo: ConstantDataElement) {
fun generateTypeInfo(irClass: IrClassSymbol, typeInfo: ConstantDataElement) {
wasmFragment.typeInfo.define(irClass, typeInfo)
}
override fun registerInitFunction(wasmFunction: WasmFunction, priority: String) {
fun registerInitFunction(wasmFunction: WasmFunction, priority: String) {
wasmFragment.initFunctions += WasmCompiledModuleFragment.FunWithPriority(wasmFunction, priority)
}
override fun addExport(wasmExport: WasmExport<*>) {
fun addExport(wasmExport: WasmExport<*>) {
wasmFragment.exports += wasmExport
}
override fun defineFunction(irFunction: IrFunctionSymbol, wasmFunction: WasmFunction) {
fun defineFunction(irFunction: IrFunctionSymbol, wasmFunction: WasmFunction) {
wasmFragment.functions.define(irFunction, wasmFunction)
}
override fun defineGlobalField(irField: IrFieldSymbol, wasmGlobal: WasmGlobal) {
fun defineGlobalField(irField: IrFieldSymbol, wasmGlobal: WasmGlobal) {
wasmFragment.globalFields.define(irField, wasmGlobal)
}
override fun defineGlobalVTable(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
fun defineGlobalVTable(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
wasmFragment.globalVTables.define(irClass, wasmGlobal)
}
override fun defineGlobalClassITable(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
fun defineGlobalClassITable(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
wasmFragment.globalClassITables.define(irClass, wasmGlobal)
}
override fun defineGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration) {
fun defineGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration) {
wasmFragment.gcTypes.define(irClass, wasmType)
}
override fun defineVTableGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration) {
fun defineVTableGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration) {
wasmFragment.vTableGcTypes.define(irClass, wasmType)
}
override fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType) {
fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType) {
wasmFragment.functionTypes.define(irFunction, wasmFunctionType)
}
private val classMetadataCache = mutableMapOf<IrClassSymbol, ClassMetadata>()
override fun getClassMetadata(irClass: IrClassSymbol): ClassMetadata =
fun getClassMetadata(irClass: IrClassSymbol): ClassMetadata =
classMetadataCache.getOrPut(irClass) {
val superClass = irClass.owner.getSuperClass(backendContext.irBuiltIns)
val superClassMetadata = superClass?.let { getClassMetadata(it.symbol) }
@@ -123,19 +123,19 @@ class WasmModuleCodegenContextImpl(
}
private val interfaceMetadataCache = mutableMapOf<IrClassSymbol, InterfaceMetadata>()
override fun getInterfaceMetadata(irClass: IrClassSymbol): InterfaceMetadata =
fun getInterfaceMetadata(irClass: IrClassSymbol): InterfaceMetadata =
interfaceMetadataCache.getOrPut(irClass) { InterfaceMetadata(irClass.owner, backendContext.irBuiltIns) }
override fun referenceFunction(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunction> =
fun referenceFunction(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunction> =
wasmFragment.functions.reference(irFunction)
override fun referenceGlobalField(irField: IrFieldSymbol): WasmSymbol<WasmGlobal> =
fun referenceGlobalField(irField: IrFieldSymbol): WasmSymbol<WasmGlobal> =
wasmFragment.globalFields.reference(irField)
override fun referenceGlobalVTable(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> =
fun referenceGlobalVTable(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> =
wasmFragment.globalVTables.reference(irClass)
override fun referenceGlobalClassITable(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> =
fun referenceGlobalClassITable(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> =
wasmFragment.globalClassITables.reference(irClass)
private fun referenceNonNothingType(
@@ -149,23 +149,23 @@ class WasmModuleCodegenContextImpl(
return from.reference(irClass)
}
override fun referenceGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> =
fun referenceGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> =
referenceNonNothingType(irClass, wasmFragment.gcTypes)
override fun referenceVTableGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> =
fun referenceVTableGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> =
referenceNonNothingType(irClass, wasmFragment.vTableGcTypes)
override fun referenceClassITableGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> =
fun referenceClassITableGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> =
referenceNonNothingType(irClass, wasmFragment.classITableGcType)
override fun defineClassITableGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration) {
fun defineClassITableGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration) {
wasmFragment.classITableGcType.define(irClass, wasmType)
}
override fun isAlreadyDefinedClassITableGcType(irClass: IrClassSymbol): Boolean =
fun isAlreadyDefinedClassITableGcType(irClass: IrClassSymbol): Boolean =
wasmFragment.classITableGcType.defined.keys.contains(irClass)
override fun referenceClassITableInterfaceSlot(irClass: IrClassSymbol): WasmSymbol<Int> {
fun referenceClassITableInterfaceSlot(irClass: IrClassSymbol): WasmSymbol<Int> {
val type = irClass.defaultType
require(!type.isNothing()) {
"Can't reference Nothing type"
@@ -173,28 +173,28 @@ class WasmModuleCodegenContextImpl(
return wasmFragment.classITableInterfaceSlot.reference(irClass)
}
override fun defineClassITableInterfaceSlot(irClass: IrClassSymbol, slot: Int) {
fun defineClassITableInterfaceSlot(irClass: IrClassSymbol, slot: Int) {
wasmFragment.classITableInterfaceSlot.define(irClass, slot)
}
override fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType> =
fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType> =
wasmFragment.functionTypes.reference(irFunction)
override fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int> =
fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int> =
wasmFragment.classIds.reference(irClass)
override fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int> {
fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int> {
return wasmFragment.interfaceId.reference(irInterface)
}
override fun getStructFieldRef(field: IrField): WasmSymbol<Int> {
fun getStructFieldRef(field: IrField): WasmSymbol<Int> {
val klass = field.parentAsClass
val metadata = getClassMetadata(klass.symbol)
val fieldId = metadata.fields.indexOf(field) + 2 //Implicit vtable and vtable field
return WasmSymbol(fieldId)
}
override fun addJsFun(importName: String, jsCode: String) {
fun addJsFun(importName: String, jsCode: String) {
wasmFragment.jsFuns +=
WasmCompiledModuleFragment.JsCodeSnippet(importName = importName, jsCode = jsCode)
}