[Wasm] Remove Wasm*CodegenContext interfaces
Use classes instead
This commit is contained in:
+27
-26
@@ -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)
|
||||
|
||||
+4
-3
@@ -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
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-55
@@ -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
|
||||
}
|
||||
-36
@@ -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
|
||||
}
|
||||
+20
-17
@@ -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))
|
||||
}
|
||||
}
|
||||
-28
@@ -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)
|
||||
}
|
||||
+41
-41
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user