[Wasm] Refactoring: replace "struct types" with "GC types"

In preparation for adding array types
This commit is contained in:
Svyatoslav Kuzmich
2020-12-05 18:18:39 +03:00
parent 4bb163fd1f
commit d15af70a3e
14 changed files with 46 additions and 35 deletions
@@ -78,7 +78,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
private fun generateInstanceFieldAccess(field: IrField) { private fun generateInstanceFieldAccess(field: IrField) {
body.buildStructGet( body.buildStructGet(
context.referenceStructType(field.parentAsClass.symbol), context.referenceGcType(field.parentAsClass.symbol),
context.getStructFieldRef(field) context.getStructFieldRef(field)
) )
} }
@@ -91,7 +91,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
generateExpression(receiver) generateExpression(receiver)
generateExpression(expression.value) generateExpression(expression.value)
body.buildStructSet( body.buildStructSet(
struct = context.referenceStructType(field.parentAsClass.symbol), struct = context.referenceGcType(field.parentAsClass.symbol),
fieldId = context.getStructFieldRef(field), fieldId = context.getStructFieldRef(field),
) )
} else { } else {
@@ -122,7 +122,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
return return
} }
val wasmStruct: WasmSymbol<WasmStructDeclaration> = context.referenceStructType(klass.symbol) val wasmStruct: WasmSymbol<WasmTypeDeclaration> = context.referenceGcType(klass.symbol)
val wasmClassId = context.referenceClassId(klass.symbol) val wasmClassId = context.referenceClassId(klass.symbol)
val irFields: List<IrField> = klass.allFields(backendContext.irBuiltIns) val irFields: List<IrField> = klass.allFields(backendContext.irBuiltIns)
@@ -157,7 +157,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
if (call.symbol == wasmSymbols.boxIntrinsic) { if (call.symbol == wasmSymbols.boxIntrinsic) {
val toType = call.getTypeArgument(0)!! val toType = call.getTypeArgument(0)!!
val klass = toType.erasedUpperBound!! val klass = toType.erasedUpperBound!!
val structTypeName = context.referenceStructType(klass.symbol) val structTypeName = context.referenceGcType(klass.symbol)
val klassId = context.referenceClassId(klass.symbol) val klassId = context.referenceClassId(klass.symbol)
body.buildConstI32Symbol(klassId) body.buildConstI32Symbol(klassId)
@@ -183,7 +183,7 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis
} }
) )
context.defineStructType(symbol, structType) context.defineGcType(symbol, structType)
var depth = 2 var depth = 2
val metadata = context.getClassMetadata(symbol) val metadata = context.getClassMetadata(symbol)
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType
@@ -47,7 +46,7 @@ class WasmTypeTransformer(
} }
fun IrType.toStructType(): WasmType = fun IrType.toStructType(): WasmType =
WasmRefNullType(WasmHeapType.Type(context.referenceStructType(erasedUpperBound?.symbol ?: builtIns.anyClass))) WasmRefNullType(WasmHeapType.Type(context.referenceGcType(erasedUpperBound?.symbol ?: builtIns.anyClass)))
fun IrType.toBoxedInlineClassType(): WasmType = fun IrType.toBoxedInlineClassType(): WasmType =
toStructType() toStructType()
@@ -21,7 +21,7 @@ interface WasmBaseCodegenContext {
fun referenceFunction(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunction> fun referenceFunction(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunction>
fun referenceGlobal(irField: IrFieldSymbol): WasmSymbol<WasmGlobal> fun referenceGlobal(irField: IrFieldSymbol): WasmSymbol<WasmGlobal>
fun referenceStructType(irClass: IrClassSymbol): WasmSymbol<WasmStructDeclaration> fun referenceGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration>
fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType> fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType>
fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int> fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int>
@@ -20,8 +20,8 @@ class WasmCompiledModuleFragment {
ReferencableAndDefinable<IrFieldSymbol, WasmGlobal>() ReferencableAndDefinable<IrFieldSymbol, WasmGlobal>()
val functionTypes = val functionTypes =
ReferencableAndDefinable<IrFunctionSymbol, WasmFunctionType>() ReferencableAndDefinable<IrFunctionSymbol, WasmFunctionType>()
val structTypes = val gcTypes =
ReferencableAndDefinable<IrClassSymbol, WasmStructDeclaration>() ReferencableAndDefinable<IrClassSymbol, WasmTypeDeclaration>()
val classIds = val classIds =
ReferencableElements<IrClassSymbol, Int>() ReferencableElements<IrClassSymbol, Int>()
val interfaceId = val interfaceId =
@@ -88,7 +88,7 @@ class WasmCompiledModuleFragment {
bind(functions.unbound, functions.defined) bind(functions.unbound, functions.defined)
bind(globals.unbound, globals.defined) bind(globals.unbound, globals.defined)
bind(functionTypes.unbound, functionTypes.defined) bind(functionTypes.unbound, functionTypes.defined)
bind(structTypes.unbound, structTypes.defined) bind(gcTypes.unbound, gcTypes.defined)
bind(runtimeTypes.unbound, runtimeTypes.defined) bind(runtimeTypes.unbound, runtimeTypes.defined)
val klassIds = mutableMapOf<IrClassSymbol, Int>() val klassIds = mutableMapOf<IrClassSymbol, Int>()
@@ -162,7 +162,7 @@ class WasmCompiledModuleFragment {
val module = WasmModule( val module = WasmModule(
functionTypes = functionTypes.elements, functionTypes = functionTypes.elements,
structs = structTypes.elements, gcTypes = gcTypes.elements,
importsInOrder = importedFunctions, importsInOrder = importedFunctions,
importedFunctions = importedFunctions, importedFunctions = importedFunctions,
definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>(), definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>(),
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
interface WasmModuleCodegenContext : WasmBaseCodegenContext { interface WasmModuleCodegenContext : WasmBaseCodegenContext {
fun defineFunction(irFunction: IrFunctionSymbol, wasmFunction: WasmFunction) fun defineFunction(irFunction: IrFunctionSymbol, wasmFunction: WasmFunction)
fun defineGlobal(irField: IrFieldSymbol, wasmGlobal: WasmGlobal) fun defineGlobal(irField: IrFieldSymbol, wasmGlobal: WasmGlobal)
fun defineStructType(irClass: IrClassSymbol, wasmStruct: WasmStructDeclaration) fun defineGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration)
fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal)
fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType) fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType)
fun addJsFun(importName: String, jsCode: String) fun addJsFun(importName: String, jsCode: String)
@@ -92,8 +92,8 @@ class WasmModuleCodegenContextImpl(
wasmFragment.globals.define(irField, wasmGlobal) wasmFragment.globals.define(irField, wasmGlobal)
} }
override fun defineStructType(irClass: IrClassSymbol, wasmStruct: WasmStructDeclaration) { override fun defineGcType(irClass: IrClassSymbol, wasmStruct: WasmTypeDeclaration) {
wasmFragment.structTypes.define(irClass, wasmStruct) wasmFragment.gcTypes.define(irClass, wasmStruct)
} }
override fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) { override fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
@@ -122,12 +122,12 @@ class WasmModuleCodegenContextImpl(
override fun referenceGlobal(irField: IrFieldSymbol): WasmSymbol<WasmGlobal> = override fun referenceGlobal(irField: IrFieldSymbol): WasmSymbol<WasmGlobal> =
wasmFragment.globals.reference(irField) wasmFragment.globals.reference(irField)
override fun referenceStructType(irClass: IrClassSymbol): WasmSymbol<WasmStructDeclaration> { override fun referenceGcType(irClass: IrClassSymbol): WasmSymbol<WasmTypeDeclaration> {
val type = irClass.defaultType val type = irClass.defaultType
require(!type.isNothing()) { require(!type.isNothing()) {
"Can't reference Nothing type" "Can't reference Nothing type"
} }
return wasmFragment.structTypes.reference(irClass) return wasmFragment.gcTypes.reference(irClass)
} }
override fun referenceClassRTT(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> = override fun referenceClassRTT(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> =
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.wasm.ir
class WasmModule( class WasmModule(
val functionTypes: List<WasmFunctionType> = emptyList(), val functionTypes: List<WasmFunctionType> = emptyList(),
val structs: List<WasmStructDeclaration> = emptyList(), val gcTypes: List<WasmTypeDeclaration> = emptyList(),
val importsInOrder: List<WasmNamedModuleField> = emptyList(), val importsInOrder: List<WasmNamedModuleField> = emptyList(),
val importedFunctions: List<WasmFunction.Imported> = emptyList(), val importedFunctions: List<WasmFunction.Imported> = emptyList(),
@@ -79,8 +79,8 @@ sealed class WasmImmediate {
class LabelIdxVector(val value: List<Int>) : WasmImmediate() class LabelIdxVector(val value: List<Int>) : WasmImmediate()
class ElemIdx(val value: WasmElement) : WasmImmediate() class ElemIdx(val value: WasmElement) : WasmImmediate()
class StructType(val value: WasmSymbol<WasmStructDeclaration>) : WasmImmediate() { class GcType(val value: WasmSymbol<WasmTypeDeclaration>) : WasmImmediate() {
constructor(value: WasmStructDeclaration) : this(WasmSymbol(value)) constructor(value: WasmTypeDeclaration) : this(WasmSymbol(value))
} }
class StructFieldIdx(val value: WasmSymbol<Int>) : WasmImmediate() class StructFieldIdx(val value: WasmSymbol<Int>) : WasmImmediate()
@@ -16,7 +16,7 @@ fun WasmModule.calculateIds() {
} }
functionTypes.calculateIds() functionTypes.calculateIds()
structs.calculateIds(startIndex = functionTypes.size) gcTypes.calculateIds(startIndex = functionTypes.size)
importedFunctions.calculateIds() importedFunctions.calculateIds()
importedMemories.calculateIds() importedMemories.calculateIds()
importedTables.calculateIds() importedTables.calculateIds()
@@ -106,22 +106,22 @@ abstract class WasmExpressionBuilder {
buildInstr(WasmOp.GLOBAL_SET, WasmImmediate.GlobalIdx(global)) buildInstr(WasmOp.GLOBAL_SET, WasmImmediate.GlobalIdx(global))
} }
fun buildStructGet(struct: WasmSymbol<WasmStructDeclaration>, fieldId: WasmSymbol<Int>) { fun buildStructGet(struct: WasmSymbol<WasmTypeDeclaration>, fieldId: WasmSymbol<Int>) {
buildInstr( buildInstr(
WasmOp.STRUCT_GET, WasmOp.STRUCT_GET,
WasmImmediate.StructType(struct), WasmImmediate.GcType(struct),
WasmImmediate.StructFieldIdx(fieldId) WasmImmediate.StructFieldIdx(fieldId)
) )
} }
fun buildStructNew(struct: WasmSymbol<WasmStructDeclaration>) { fun buildStructNew(struct: WasmSymbol<WasmTypeDeclaration>) {
buildInstr(WasmOp.STRUCT_NEW_WITH_RTT, WasmImmediate.StructType(struct)) buildInstr(WasmOp.STRUCT_NEW_WITH_RTT, WasmImmediate.GcType(struct))
} }
fun buildStructSet(struct: WasmSymbol<WasmStructDeclaration>, fieldId: WasmSymbol<Int>) { fun buildStructSet(struct: WasmSymbol<WasmTypeDeclaration>, fieldId: WasmSymbol<Int>) {
buildInstr( buildInstr(
WasmOp.STRUCT_SET, WasmOp.STRUCT_SET,
WasmImmediate.StructType(struct), WasmImmediate.GcType(struct),
WasmImmediate.StructFieldIdx(fieldId) WasmImmediate.StructFieldIdx(fieldId)
) )
} }
@@ -15,7 +15,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
val validVersion = 1u val validVersion = 1u
val functionTypes: MutableList<WasmFunctionType> = mutableListOf() val functionTypes: MutableList<WasmFunctionType> = mutableListOf()
val structs: MutableList<WasmStructDeclaration> = mutableListOf() val gcTypes: MutableList<WasmTypeDeclaration> = mutableListOf()
val importsInOrder: MutableList<WasmNamedModuleField> = mutableListOf() val importsInOrder: MutableList<WasmNamedModuleField> = mutableListOf()
val importedFunctions: MutableList<WasmFunction.Imported> = mutableListOf() val importedFunctions: MutableList<WasmFunction.Imported> = mutableListOf()
@@ -80,7 +80,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
is WasmFunctionType -> is WasmFunctionType ->
functionTypes += type functionTypes += type
is WasmStructDeclaration -> is WasmStructDeclaration ->
structs += type gcTypes += type
} }
} }
} }
@@ -313,7 +313,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
return WasmModule( return WasmModule(
functionTypes = functionTypes, functionTypes = functionTypes,
structs = structs, gcTypes = gcTypes,
importsInOrder = importsInOrder, importsInOrder = importsInOrder,
importedFunctions = importedFunctions, importedFunctions = importedFunctions,
importedMemories = importedMemories, importedMemories = importedMemories,
@@ -21,9 +21,14 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule) {
with(module) { with(module) {
// type section // type section
appendSection(1u) { appendSection(1u) {
appendVectorSize(functionTypes.size + structs.size) appendVectorSize(functionTypes.size + gcTypes.size)
functionTypes.forEach { appendFunctionTypeDeclaration(it) } functionTypes.forEach { appendFunctionTypeDeclaration(it) }
structs.forEach { appendStructTypeDeclaration(it) } gcTypes.forEach {
when (it) {
is WasmStructDeclaration -> appendStructTypeDeclaration(it)
else -> TODO("Support arrays")
}
}
} }
// import section // import section
@@ -148,7 +153,7 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule) {
appendType(type) appendType(type)
} }
} }
is WasmImmediate.StructType -> appendModuleFieldReference(x.value.owner) is WasmImmediate.GcType -> appendModuleFieldReference(x.value.owner)
is WasmImmediate.StructFieldIdx -> b.writeVarUInt32(x.value.owner) is WasmImmediate.StructFieldIdx -> b.writeVarUInt32(x.value.owner)
is WasmImmediate.HeapType -> appendHeapType(x.value) is WasmImmediate.HeapType -> appendHeapType(x.value)
} }
@@ -107,7 +107,7 @@ class WasmIrToText : SExpressionBuilder() {
is WasmImmediate.ValTypeVector -> sameLineList("result") { x.value.forEach { appendType(it) } } is WasmImmediate.ValTypeVector -> sameLineList("result") { x.value.forEach { appendType(it) } }
is WasmImmediate.StructType -> appendModuleFieldReference(x.value.owner) is WasmImmediate.GcType -> appendModuleFieldReference(x.value.owner)
is WasmImmediate.StructFieldIdx -> appendElement(x.value.owner.toString()) is WasmImmediate.StructFieldIdx -> appendElement(x.value.owner.toString())
is WasmImmediate.HeapType -> { is WasmImmediate.HeapType -> {
appendHeapType(x.value) appendHeapType(x.value)
@@ -197,7 +197,14 @@ class WasmIrToText : SExpressionBuilder() {
with(module) { with(module) {
newLineList("module") { newLineList("module") {
functionTypes.forEach { appendFunctionTypeDeclaration(it) } functionTypes.forEach { appendFunctionTypeDeclaration(it) }
structs.forEach { appendStructTypeDeclaration(it) } gcTypes.forEach {
when (it) {
is WasmStructDeclaration ->
appendStructTypeDeclaration(it)
else ->
TODO("Support arrays")
}
}
importsInOrder.forEach { importsInOrder.forEach {
when (it) { when (it) {
is WasmFunction.Imported -> appendImportedFunction(it) is WasmFunction.Imported -> appendImportedFunction(it)