[Wasm] Support Wasm GC milestone 5
This commit is contained in:
+2
-1
@@ -45,7 +45,8 @@ internal class WasmUsefulDeclarationProcessor(
|
|||||||
}
|
}
|
||||||
context.wasmSymbols.wasmClassId,
|
context.wasmSymbols.wasmClassId,
|
||||||
context.wasmSymbols.wasmInterfaceId,
|
context.wasmSymbols.wasmInterfaceId,
|
||||||
context.wasmSymbols.wasmRefCast -> {
|
context.wasmSymbols.wasmRefCast,
|
||||||
|
context.wasmSymbols.refTest -> {
|
||||||
call.getTypeArgument(0)?.getClass()?.enqueue(from, "generic intrinsic ${call.symbol.owner.name}")
|
call.getTypeArgument(0)?.getClass()?.enqueue(from, "generic intrinsic ${call.symbol.owner.name}")
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-4
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.backend.js.utils.isDispatchReceiver
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
|
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
@@ -213,7 +214,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
generateDefaultInitializerForType(context.transformType(field.type), body)
|
generateDefaultInitializerForType(context.transformType(field.type), body)
|
||||||
}
|
}
|
||||||
|
|
||||||
body.buildGetGlobal(context.referenceClassRTT(klass.symbol))
|
generateClassRTT(klass.symbol)
|
||||||
body.buildStructNew(wasmGcType)
|
body.buildStructNew(wasmGcType)
|
||||||
generateCall(expression)
|
generateCall(expression)
|
||||||
}
|
}
|
||||||
@@ -243,7 +244,7 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
body.buildConstI32Symbol(klassId)
|
body.buildConstI32Symbol(klassId)
|
||||||
body.buildConstI32(0) // Any::_hashCode
|
body.buildConstI32(0) // Any::_hashCode
|
||||||
generateExpression(call.getValueArgument(0)!!)
|
generateExpression(call.getValueArgument(0)!!)
|
||||||
body.buildGetGlobal(context.referenceClassRTT(klass.symbol))
|
generateClassRTT(klass.symbol)
|
||||||
body.buildStructNew(structTypeName)
|
body.buildStructNew(structTypeName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -322,8 +323,12 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateTypeRTT(type: IrType) {
|
private fun generateTypeRTT(type: IrType) {
|
||||||
val rtClass = type.getRuntimeClass?.symbol ?: context.backendContext.irBuiltIns.anyClass
|
val klass = type.getRuntimeClass?.symbol ?: context.backendContext.irBuiltIns.anyClass
|
||||||
body.buildGetGlobal(context.referenceClassRTT(rtClass))
|
generateClassRTT(klass)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateClassRTT(klass: IrClassSymbol) {
|
||||||
|
body.buildRttCanon(context.referenceGcType(klass))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if generated.
|
// Return true if generated.
|
||||||
@@ -357,6 +362,12 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
body.buildRefCast()
|
body.buildRefCast()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wasmSymbols.refTest -> {
|
||||||
|
val toType = call.getTypeArgument(0)!!
|
||||||
|
generateTypeRTT(toType)
|
||||||
|
body.buildInstr(WasmOp.REF_TEST)
|
||||||
|
}
|
||||||
|
|
||||||
wasmSymbols.unboxIntrinsic -> {
|
wasmSymbols.unboxIntrinsic -> {
|
||||||
val fromType = call.getTypeArgument(0)!!
|
val fromType = call.getTypeArgument(0)!!
|
||||||
|
|
||||||
@@ -581,6 +592,9 @@ class BodyGenerator(val context: WasmFunctionCodegenContext) : IrElementVisitorV
|
|||||||
WasmImmediate.MemArg(0u, 0u)
|
WasmImmediate.MemArg(0u, 0u)
|
||||||
WasmImmediateKind.STRUCT_TYPE_IDX ->
|
WasmImmediateKind.STRUCT_TYPE_IDX ->
|
||||||
WasmImmediate.GcType(context.referenceGcType(function.dispatchReceiverParameter!!.type.classOrNull!!))
|
WasmImmediate.GcType(context.referenceGcType(function.dispatchReceiverParameter!!.type.classOrNull!!))
|
||||||
|
WasmImmediateKind.TYPE_IDX ->
|
||||||
|
WasmImmediate.TypeIdx(context.referenceGcType(function.dispatchReceiverParameter!!.type.classOrNull!!))
|
||||||
|
|
||||||
else ->
|
else ->
|
||||||
error("Immediate $imm is unsupported")
|
error("Immediate $imm is unsupported")
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-35
@@ -85,7 +85,6 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext, private val al
|
|||||||
|
|
||||||
val wasmFunctionType =
|
val wasmFunctionType =
|
||||||
WasmFunctionType(
|
WasmFunctionType(
|
||||||
name = watName,
|
|
||||||
parameterTypes = irParameters.map { context.transformValueParameterType(it) },
|
parameterTypes = irParameters.map { context.transformValueParameterType(it) },
|
||||||
resultTypes = listOfNotNull(resultType)
|
resultTypes = listOfNotNull(resultType)
|
||||||
)
|
)
|
||||||
@@ -104,17 +103,19 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext, private val al
|
|||||||
"Sanity check that $declaration is a real function that can be used in calls"
|
"Sanity check that $declaration is a real function that can be used in calls"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val functionTypeSymbol = context.referenceFunctionType(declaration.symbol)
|
||||||
|
|
||||||
if (importedName != null) {
|
if (importedName != null) {
|
||||||
// Imported functions don't have bodies. Declaring the signature:
|
// Imported functions don't have bodies. Declaring the signature:
|
||||||
context.defineFunction(
|
context.defineFunction(
|
||||||
declaration.symbol,
|
declaration.symbol,
|
||||||
WasmFunction.Imported(watName, wasmFunctionType, importedName)
|
WasmFunction.Imported(watName, functionTypeSymbol, importedName)
|
||||||
)
|
)
|
||||||
// TODO: Support re-export of imported functions.
|
// TODO: Support re-export of imported functions.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val function = WasmFunction.Defined(watName, wasmFunctionType)
|
val function = WasmFunction.Defined(watName, functionTypeSymbol)
|
||||||
val functionCodegenContext = WasmFunctionCodegenContextImpl(
|
val functionCodegenContext = WasmFunctionCodegenContextImpl(
|
||||||
declaration,
|
declaration,
|
||||||
function,
|
function,
|
||||||
@@ -200,6 +201,8 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext, private val al
|
|||||||
context.registerInterface(symbol)
|
context.registerInterface(symbol)
|
||||||
} else {
|
} else {
|
||||||
val nameStr = declaration.fqNameWhenAvailable.toString()
|
val nameStr = declaration.fqNameWhenAvailable.toString()
|
||||||
|
val metadata = context.getClassMetadata(symbol)
|
||||||
|
val superClass = metadata.superClass
|
||||||
val structType = WasmStructDeclaration(
|
val structType = WasmStructDeclaration(
|
||||||
name = nameStr,
|
name = nameStr,
|
||||||
fields = declaration.allFields(irBuiltIns).map {
|
fields = declaration.allFields(irBuiltIns).map {
|
||||||
@@ -208,40 +211,11 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext, private val al
|
|||||||
type = context.transformFieldType(it.type),
|
type = context.transformFieldType(it.type),
|
||||||
isMutable = true
|
isMutable = true
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
|
superClass?.let { context.referenceGcType(superClass.klass.symbol) }
|
||||||
)
|
)
|
||||||
|
|
||||||
context.defineGcType(symbol, structType)
|
context.defineGcType(symbol, structType)
|
||||||
|
|
||||||
var depth = 0
|
|
||||||
val metadata = context.getClassMetadata(symbol)
|
|
||||||
var subMetadata = metadata
|
|
||||||
while (true) {
|
|
||||||
subMetadata = subMetadata.superClass ?: break
|
|
||||||
depth++
|
|
||||||
}
|
|
||||||
|
|
||||||
val initBody = mutableListOf<WasmInstr>()
|
|
||||||
val wasmExpressionGenerator = WasmIrExpressionBuilder(initBody)
|
|
||||||
|
|
||||||
val wasmGcType = context.referenceGcType(symbol)
|
|
||||||
val superClass = metadata.superClass
|
|
||||||
if (superClass != null) {
|
|
||||||
val superRTT = context.referenceClassRTT(superClass.klass.symbol)
|
|
||||||
wasmExpressionGenerator.buildGetGlobal(superRTT)
|
|
||||||
wasmExpressionGenerator.buildRttSub(wasmGcType)
|
|
||||||
} else {
|
|
||||||
wasmExpressionGenerator.buildRttCanon(wasmGcType)
|
|
||||||
}
|
|
||||||
|
|
||||||
val rtt = WasmGlobal(
|
|
||||||
name = "rtt_of_$nameStr",
|
|
||||||
isMutable = false,
|
|
||||||
type = WasmRtt(depth, WasmSymbol(structType)),
|
|
||||||
init = initBody
|
|
||||||
)
|
|
||||||
|
|
||||||
context.defineRTT(symbol, rtt)
|
|
||||||
context.registerClass(symbol)
|
context.registerClass(symbol)
|
||||||
context.generateTypeInfo(symbol, binaryDataStruct(metadata))
|
context.generateTypeInfo(symbol, binaryDataStruct(metadata))
|
||||||
|
|
||||||
@@ -394,7 +368,7 @@ fun generateDefaultInitializerForType(type: WasmType, g: WasmExpressionBuilder)
|
|||||||
WasmF32 -> g.buildConstF32(0f)
|
WasmF32 -> g.buildConstF32(0f)
|
||||||
WasmF64 -> g.buildConstF64(0.0)
|
WasmF64 -> g.buildConstF64(0.0)
|
||||||
is WasmRefNullType -> g.buildRefNull(type.heapType)
|
is WasmRefNullType -> g.buildRefNull(type.heapType)
|
||||||
is WasmExternRef, is WasmAnyRef -> g.buildRefNull(WasmHeapType.Simple.Extern)
|
is WasmAnyRef -> g.buildRefNull(WasmHeapType.Simple.Extern)
|
||||||
WasmUnreachableType -> error("Unreachable type can't be initialized")
|
WasmUnreachableType -> error("Unreachable type can't be initialized")
|
||||||
else -> error("Unknown value type ${type.name}")
|
else -> error("Unknown value type ${type.name}")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -82,11 +82,11 @@ class WasmTypeTransformer(
|
|||||||
WasmF64
|
WasmF64
|
||||||
|
|
||||||
builtIns.nothingNType ->
|
builtIns.nothingNType ->
|
||||||
WasmExternRef
|
WasmAnyRef
|
||||||
|
|
||||||
// Value will not be created. Just using a random Wasm type.
|
// Value will not be created. Just using a random Wasm type.
|
||||||
builtIns.nothingType ->
|
builtIns.nothingType ->
|
||||||
WasmExternRef
|
WasmAnyRef
|
||||||
|
|
||||||
symbols.voidType ->
|
symbols.voidType ->
|
||||||
error("Void type can't be used as a value")
|
error("Void type can't be used as a value")
|
||||||
|
|||||||
-1
@@ -29,7 +29,6 @@ interface WasmBaseCodegenContext {
|
|||||||
fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int>
|
fun referenceClassId(irClass: IrClassSymbol): WasmSymbol<Int>
|
||||||
fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int>
|
fun referenceInterfaceId(irInterface: IrClassSymbol): WasmSymbol<Int>
|
||||||
fun referenceVirtualFunctionId(irFunction: IrSimpleFunctionSymbol): WasmSymbol<Int>
|
fun referenceVirtualFunctionId(irFunction: IrSimpleFunctionSymbol): WasmSymbol<Int>
|
||||||
fun referenceClassRTT(irClass: IrClassSymbol): WasmSymbol<WasmGlobal>
|
|
||||||
|
|
||||||
fun referenceSignatureId(signature: WasmSignature): WasmSymbol<Int>
|
fun referenceSignatureId(signature: WasmSignature): WasmSymbol<Int>
|
||||||
|
|
||||||
|
|||||||
+28
-14
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.wasm.ir2wasm
|
package org.jetbrains.kotlin.backend.wasm.ir2wasm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.push
|
|
||||||
import org.jetbrains.kotlin.backend.wasm.lower.WasmSignature
|
import org.jetbrains.kotlin.backend.wasm.lower.WasmSignature
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
|
||||||
@@ -35,11 +34,7 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
|||||||
val stringLiteralId =
|
val stringLiteralId =
|
||||||
ReferencableElements<String, Int>()
|
ReferencableElements<String, Int>()
|
||||||
|
|
||||||
val runtimeTypes =
|
|
||||||
ReferencableAndDefinable<IrClassSymbol, WasmGlobal>()
|
|
||||||
|
|
||||||
val tagFuncType = WasmFunctionType(
|
val tagFuncType = WasmFunctionType(
|
||||||
"ex_handling_tag",
|
|
||||||
listOf(
|
listOf(
|
||||||
WasmRefNullType(WasmHeapType.Type(gcTypes.reference(irBuiltIns.throwableClass)))
|
WasmRefNullType(WasmHeapType.Type(gcTypes.reference(irBuiltIns.throwableClass)))
|
||||||
),
|
),
|
||||||
@@ -123,9 +118,18 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
|||||||
fun linkWasmCompiledFragments(): WasmModule {
|
fun linkWasmCompiledFragments(): WasmModule {
|
||||||
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(gcTypes.unbound, gcTypes.defined)
|
bind(gcTypes.unbound, gcTypes.defined)
|
||||||
bind(runtimeTypes.unbound, runtimeTypes.defined)
|
|
||||||
|
// Associate function types to a single canonical function type
|
||||||
|
val canonicalFunctionTypes =
|
||||||
|
functionTypes.elements.associateWithTo(LinkedHashMap()) { it }
|
||||||
|
|
||||||
|
functionTypes.unbound.forEach { (irSymbol, wasmSymbol) ->
|
||||||
|
if (irSymbol !in functionTypes.defined)
|
||||||
|
error("Can't link symbol ${irSymbolDebugDump(irSymbol)}")
|
||||||
|
wasmSymbol.bind(canonicalFunctionTypes.getValue(functionTypes.defined.getValue(irSymbol)))
|
||||||
|
}
|
||||||
|
|
||||||
val klassIds = mutableMapOf<IrClassSymbol, Int>()
|
val klassIds = mutableMapOf<IrClassSymbol, Int>()
|
||||||
var currentDataSectionAddress = 0
|
var currentDataSectionAddress = 0
|
||||||
@@ -260,8 +264,8 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val masterInitFunctionType = WasmFunctionType("__init_t", emptyList(), emptyList())
|
val masterInitFunctionType = WasmFunctionType(emptyList(), emptyList())
|
||||||
val masterInitFunction = WasmFunction.Defined("__init", masterInitFunctionType)
|
val masterInitFunction = WasmFunction.Defined("__init", WasmSymbol(masterInitFunctionType))
|
||||||
with(WasmIrExpressionBuilder(masterInitFunction.instructions)) {
|
with(WasmIrExpressionBuilder(masterInitFunction.instructions)) {
|
||||||
initFunctions.sortedBy { it.priority }.forEach {
|
initFunctions.sortedBy { it.priority }.forEach {
|
||||||
buildCall(WasmSymbol(it.function))
|
buildCall(WasmSymbol(it.function))
|
||||||
@@ -283,18 +287,28 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
|
|||||||
|
|
||||||
val importedFunctions = functions.elements.filterIsInstance<WasmFunction.Imported>()
|
val importedFunctions = functions.elements.filterIsInstance<WasmFunction.Imported>()
|
||||||
|
|
||||||
// Sorting by depth for a valid init order
|
fun wasmTypeDeclarationOrderKey(declaration: WasmTypeDeclaration): Int {
|
||||||
val sortedRttGlobals = runtimeTypes.elements.sortedBy { (it.type as WasmRtt).depth }
|
return when (declaration) {
|
||||||
|
is WasmArrayDeclaration -> 0
|
||||||
|
is WasmFunctionType -> 0
|
||||||
|
is WasmStructDeclaration ->
|
||||||
|
// Subtype depth
|
||||||
|
declaration.superType?.let { wasmTypeDeclarationOrderKey(it.owner) + 1 } ?: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val sortedGcTypes = gcTypes.elements.sortedBy(::wasmTypeDeclarationOrderKey)
|
||||||
|
|
||||||
val module = WasmModule(
|
val module = WasmModule(
|
||||||
functionTypes = functionTypes.elements + tagFuncType + masterInitFunctionType,
|
functionTypes = canonicalFunctionTypes.values.toList() + tagFuncType + masterInitFunctionType,
|
||||||
gcTypes = gcTypes.elements,
|
gcTypes = sortedGcTypes,
|
||||||
|
gcTypesInRecursiveGroup = true,
|
||||||
importsInOrder = importedFunctions,
|
importsInOrder = importedFunctions,
|
||||||
importedFunctions = importedFunctions,
|
importedFunctions = importedFunctions,
|
||||||
definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>() + masterInitFunction,
|
definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>() + masterInitFunction,
|
||||||
tables = listOf(table) + interfaceMethodTables.elements,
|
tables = listOf(table) + interfaceMethodTables.elements,
|
||||||
memories = listOf(memory),
|
memories = listOf(memory),
|
||||||
globals = globals.elements + sortedRttGlobals,
|
globals = globals.elements,
|
||||||
exports = exports,
|
exports = exports,
|
||||||
startFunction = null, // Module is initialized via export call
|
startFunction = null, // Module is initialized via export call
|
||||||
elements = listOf(elements) + interfaceTableElements,
|
elements = listOf(elements) + interfaceTableElements,
|
||||||
|
|||||||
-1
@@ -18,7 +18,6 @@ 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 defineGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration)
|
fun defineGcType(irClass: IrClassSymbol, wasmType: WasmTypeDeclaration)
|
||||||
fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal)
|
|
||||||
fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType)
|
fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType)
|
||||||
fun defineInterfaceMethodTable(irFunction: IrFunctionSymbol, wasmTable: WasmTable)
|
fun defineInterfaceMethodTable(irFunction: IrFunctionSymbol, wasmTable: WasmTable)
|
||||||
fun addJsFun(importName: String, jsCode: String)
|
fun addJsFun(importName: String, jsCode: String)
|
||||||
|
|||||||
-7
@@ -106,10 +106,6 @@ class WasmModuleCodegenContextImpl(
|
|||||||
wasmFragment.gcTypes.define(irClass, wasmType)
|
wasmFragment.gcTypes.define(irClass, wasmType)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun defineRTT(irClass: IrClassSymbol, wasmGlobal: WasmGlobal) {
|
|
||||||
wasmFragment.runtimeTypes.define(irClass, wasmGlobal)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType) {
|
override fun defineFunctionType(irFunction: IrFunctionSymbol, wasmFunctionType: WasmFunctionType) {
|
||||||
wasmFragment.functionTypes.define(irFunction, wasmFunctionType)
|
wasmFragment.functionTypes.define(irFunction, wasmFunctionType)
|
||||||
}
|
}
|
||||||
@@ -157,9 +153,6 @@ class WasmModuleCodegenContextImpl(
|
|||||||
return wasmFragment.gcTypes.reference(irClass)
|
return wasmFragment.gcTypes.reference(irClass)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun referenceClassRTT(irClass: IrClassSymbol): WasmSymbol<WasmGlobal> =
|
|
||||||
wasmFragment.runtimeTypes.reference(irClass)
|
|
||||||
|
|
||||||
override fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType> =
|
override fun referenceFunctionType(irFunction: IrFunctionSymbol): WasmSymbol<WasmFunctionType> =
|
||||||
wasmFragment.functionTypes.reference(irFunction)
|
wasmFragment.functionTypes.reference(irFunction)
|
||||||
|
|
||||||
|
|||||||
-8
@@ -51,9 +51,6 @@ class GenericReturnTypeLowering(val context: WasmBackendContext) : FileLoweringP
|
|||||||
val function: IrSimpleFunction =
|
val function: IrSimpleFunction =
|
||||||
call.symbol.owner as? IrSimpleFunction ?: return call
|
call.symbol.owner as? IrSimpleFunction ?: return call
|
||||||
|
|
||||||
if (!function.realOverrideTarget.returnType.isTypeParameter())
|
|
||||||
return call
|
|
||||||
|
|
||||||
val erasedReturnType: IrType =
|
val erasedReturnType: IrType =
|
||||||
function.realOverrideTarget.returnType.eraseUpperBoundType()
|
function.realOverrideTarget.returnType.eraseUpperBoundType()
|
||||||
|
|
||||||
@@ -72,11 +69,6 @@ class GenericReturnTypeLowering(val context: WasmBackendContext) : FileLoweringP
|
|||||||
)
|
)
|
||||||
|
|
||||||
context.createIrBuilder(scopeOwnerSymbol).apply {
|
context.createIrBuilder(scopeOwnerSymbol).apply {
|
||||||
if (call.type.isUnit()) {
|
|
||||||
return irComposite(call) {
|
|
||||||
+newCall
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return irImplicitCast(newCall, call.type)
|
return irImplicitCast(newCall, call.type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: FAKE_OVERRIDE_ISSUES
|
|
||||||
// On wasm this will produce conflicting return types, foo will return Any but we will try to interpret it as String.
|
|
||||||
// Before wasm native strings this worked by chance because we added unbox intrinsic for strings.
|
|
||||||
|
|
||||||
open class Foo {
|
open class Foo {
|
||||||
open fun foo(x: CharSequence = "O"): CharSequence = x
|
open fun foo(x: CharSequence = "O"): CharSequence = x
|
||||||
|
|||||||
-4
@@ -1,7 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: FAKE_OVERRIDE_ISSUES
|
|
||||||
// On wasm this will produce conflicting return types, foo will return Any but we will try to interpret it as String.
|
|
||||||
// Before wasm native strings this worked by chance because we added unbox intrinsic for strings.
|
|
||||||
|
|
||||||
open class Foo {
|
open class Foo {
|
||||||
open fun foo(x: CharSequence = "O"): CharSequence = x
|
open fun foo(x: CharSequence = "O"): CharSequence = x
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
fun <T> myRun(action: () -> T): T = action()
|
fun <T> myRun(action: () -> T): T = action()
|
||||||
fun foo(): String = "foo"
|
fun foo(): String = "foo"
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// V8 fail: https://bugs.chromium.org/p/v8/issues/detail?id=12834
|
||||||
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
// Char issues
|
// Char issues
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ val v8osString = when (currentOsType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val v8edition = "rel" // rel or dbg
|
val v8edition = "rel" // rel or dbg
|
||||||
val v8version = "9.2.212"
|
val v8version = "10.2.9"
|
||||||
val v8fileName = "v8-${v8osString}-${v8edition}-${v8version}"
|
val v8fileName = "v8-${v8osString}-${v8edition}-${v8version}"
|
||||||
val v8url = "https://storage.googleapis.com/chromium-v8/official/canary/$v8fileName.zip"
|
val v8url = "https://storage.googleapis.com/chromium-v8/official/canary/$v8fileName.zip"
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,6 @@ abstract class BasicWasmBoxTest(
|
|||||||
File(dir, "test.js").writeText(testJs)
|
File(dir, "test.js").writeText(testJs)
|
||||||
ExternalTool(System.getProperty("javascript.engine.path.V8"))
|
ExternalTool(System.getProperty("javascript.engine.path.V8"))
|
||||||
.run(
|
.run(
|
||||||
"--experimental-wasm-typed-funcref",
|
|
||||||
"--experimental-wasm-gc",
|
"--experimental-wasm-gc",
|
||||||
"--experimental-wasm-eh",
|
"--experimental-wasm-eh",
|
||||||
*jsFilesBefore.map { File(it).absolutePath }.toTypedArray(),
|
*jsFilesBefore.map { File(it).absolutePath }.toTypedArray(),
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// V8 fail: https://bugs.chromium.org/p/v8/issues/detail?id=12834
|
||||||
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1281
|
// EXPECTED_REACHABLE_NODES: 1281
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// V8 fail: https://bugs.chromium.org/p/v8/issues/detail?id=12834
|
||||||
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1283
|
// EXPECTED_REACHABLE_NODES: 1283
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// V8 fail: https://bugs.chromium.org/p/v8/issues/detail?id=12834
|
||||||
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1284
|
// EXPECTED_REACHABLE_NODES: 1284
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package org.jetbrains.kotlin.wasm.ir
|
|||||||
class WasmModule(
|
class WasmModule(
|
||||||
val functionTypes: List<WasmFunctionType> = emptyList(),
|
val functionTypes: List<WasmFunctionType> = emptyList(),
|
||||||
val gcTypes: List<WasmTypeDeclaration> = emptyList(),
|
val gcTypes: List<WasmTypeDeclaration> = emptyList(),
|
||||||
|
val gcTypesInRecursiveGroup: Boolean,
|
||||||
|
|
||||||
val importsInOrder: List<WasmNamedModuleField> = emptyList(),
|
val importsInOrder: List<WasmNamedModuleField> = emptyList(),
|
||||||
val importedFunctions: List<WasmFunction.Imported> = emptyList(),
|
val importedFunctions: List<WasmFunction.Imported> = emptyList(),
|
||||||
@@ -38,18 +39,18 @@ sealed class WasmNamedModuleField {
|
|||||||
|
|
||||||
sealed class WasmFunction(
|
sealed class WasmFunction(
|
||||||
override val name: String,
|
override val name: String,
|
||||||
val type: WasmFunctionType
|
val type: WasmSymbolReadOnly<WasmFunctionType>
|
||||||
) : WasmNamedModuleField() {
|
) : WasmNamedModuleField() {
|
||||||
class Defined(
|
class Defined(
|
||||||
name: String,
|
name: String,
|
||||||
type: WasmFunctionType,
|
type: WasmSymbolReadOnly<WasmFunctionType>,
|
||||||
val locals: MutableList<WasmLocal> = mutableListOf(),
|
val locals: MutableList<WasmLocal> = mutableListOf(),
|
||||||
val instructions: MutableList<WasmInstr> = mutableListOf()
|
val instructions: MutableList<WasmInstr> = mutableListOf()
|
||||||
) : WasmFunction(name, type)
|
) : WasmFunction(name, type)
|
||||||
|
|
||||||
class Imported(
|
class Imported(
|
||||||
name: String,
|
name: String,
|
||||||
type: WasmFunctionType,
|
type: WasmSymbolReadOnly<WasmFunctionType>,
|
||||||
val importPair: WasmImportPair
|
val importPair: WasmImportPair
|
||||||
) : WasmFunction(name, type)
|
) : WasmFunction(name, type)
|
||||||
}
|
}
|
||||||
@@ -146,15 +147,15 @@ sealed class WasmTypeDeclaration(
|
|||||||
override val name: String
|
override val name: String
|
||||||
) : WasmNamedModuleField()
|
) : WasmNamedModuleField()
|
||||||
|
|
||||||
class WasmFunctionType(
|
data class WasmFunctionType(
|
||||||
name: String,
|
|
||||||
val parameterTypes: List<WasmType>,
|
val parameterTypes: List<WasmType>,
|
||||||
val resultTypes: List<WasmType>
|
val resultTypes: List<WasmType>
|
||||||
) : WasmTypeDeclaration(name)
|
) : WasmTypeDeclaration("")
|
||||||
|
|
||||||
class WasmStructDeclaration(
|
class WasmStructDeclaration(
|
||||||
name: String,
|
name: String,
|
||||||
val fields: List<WasmStructFieldDeclaration>
|
val fields: List<WasmStructFieldDeclaration>,
|
||||||
|
val superType: WasmSymbolReadOnly<WasmTypeDeclaration>?
|
||||||
) : WasmTypeDeclaration(name)
|
) : WasmTypeDeclaration(name)
|
||||||
|
|
||||||
class WasmArrayDeclaration(
|
class WasmArrayDeclaration(
|
||||||
|
|||||||
@@ -343,6 +343,8 @@ enum class WasmOp(
|
|||||||
// GC
|
// GC
|
||||||
STRUCT_NEW_WITH_RTT("struct.new_with_rtt", 0xFB_01, STRUCT_TYPE_IDX),
|
STRUCT_NEW_WITH_RTT("struct.new_with_rtt", 0xFB_01, STRUCT_TYPE_IDX),
|
||||||
STRUCT_NEW_DEFAULT_WITH_RTT("struct.new_default_with_rtt", 0xFB_02, STRUCT_TYPE_IDX),
|
STRUCT_NEW_DEFAULT_WITH_RTT("struct.new_default_with_rtt", 0xFB_02, STRUCT_TYPE_IDX),
|
||||||
|
STRUCT_NEW("struct.new", 0xFB_07, STRUCT_TYPE_IDX),
|
||||||
|
STRUCT_NEW_DEFAULT("struct.new_default", 0xFB_08, STRUCT_TYPE_IDX),
|
||||||
STRUCT_GET("struct.get", 0xFB_03, listOf(STRUCT_TYPE_IDX, STRUCT_FIELD_IDX)),
|
STRUCT_GET("struct.get", 0xFB_03, listOf(STRUCT_TYPE_IDX, STRUCT_FIELD_IDX)),
|
||||||
STRUCT_GET_S("struct.get_s", 0xFB_04, listOf(STRUCT_TYPE_IDX, STRUCT_FIELD_IDX)),
|
STRUCT_GET_S("struct.get_s", 0xFB_04, listOf(STRUCT_TYPE_IDX, STRUCT_FIELD_IDX)),
|
||||||
STRUCT_GET_U("struct.get_u", 0xFB_05, listOf(STRUCT_TYPE_IDX, STRUCT_FIELD_IDX)),
|
STRUCT_GET_U("struct.get_u", 0xFB_05, listOf(STRUCT_TYPE_IDX, STRUCT_FIELD_IDX)),
|
||||||
@@ -350,6 +352,8 @@ enum class WasmOp(
|
|||||||
|
|
||||||
ARRAY_NEW_WITH_RTT("array.new_with_rtt", 0xFB_11, STRUCT_TYPE_IDX),
|
ARRAY_NEW_WITH_RTT("array.new_with_rtt", 0xFB_11, STRUCT_TYPE_IDX),
|
||||||
ARRAY_NEW_DEFAULT_WITH_RTT("array.new_default_with_rtt", 0xFB_12, STRUCT_TYPE_IDX),
|
ARRAY_NEW_DEFAULT_WITH_RTT("array.new_default_with_rtt", 0xFB_12, STRUCT_TYPE_IDX),
|
||||||
|
ARRAY_NEW("array.new", 0xFB_1B, STRUCT_TYPE_IDX),
|
||||||
|
ARRAY_NEW_DEFAULT("array.new_default", 0xFB_1C, STRUCT_TYPE_IDX),
|
||||||
ARRAY_GET("array.get", 0xFB_13, listOf(STRUCT_TYPE_IDX)),
|
ARRAY_GET("array.get", 0xFB_13, listOf(STRUCT_TYPE_IDX)),
|
||||||
ARRAY_GET_S("array.get_s", 0xFB_14, listOf(STRUCT_TYPE_IDX)),
|
ARRAY_GET_S("array.get_s", 0xFB_14, listOf(STRUCT_TYPE_IDX)),
|
||||||
ARRAY_GET_U("array.get_u", 0xFB_15, listOf(STRUCT_TYPE_IDX)),
|
ARRAY_GET_U("array.get_u", 0xFB_15, listOf(STRUCT_TYPE_IDX)),
|
||||||
@@ -362,9 +366,10 @@ enum class WasmOp(
|
|||||||
|
|
||||||
RTT_CANON("rtt.canon", 0xFB_30, TYPE_IDX),
|
RTT_CANON("rtt.canon", 0xFB_30, TYPE_IDX),
|
||||||
|
|
||||||
RTT_SUB("rtt.sub", 0xFB_31, TYPE_IDX),
|
|
||||||
REF_TEST("ref.test", 0xFB_40),
|
REF_TEST("ref.test", 0xFB_40),
|
||||||
|
REF_TEST_STATIC("ref.test_static", 0xFB_44, STRUCT_TYPE_IDX),
|
||||||
REF_CAST("ref.cast", 0xFB_41),
|
REF_CAST("ref.cast", 0xFB_41),
|
||||||
|
REF_CAST_STATIC("ref.cast_static", 0xFB_45, STRUCT_TYPE_IDX),
|
||||||
|
|
||||||
BR_ON_CAST("br_on_cast", 0xFB_42, listOf(LABEL_IDX)),
|
BR_ON_CAST("br_on_cast", 0xFB_42, listOf(LABEL_IDX)),
|
||||||
|
|
||||||
|
|||||||
@@ -26,18 +26,18 @@ object WasmExternRef : WasmType("externref", -0x11)
|
|||||||
object WasmAnyRef : WasmType("anyref", -0x12)
|
object WasmAnyRef : WasmType("anyref", -0x12)
|
||||||
object WasmEqRef : WasmType("eqref", -0x13)
|
object WasmEqRef : WasmType("eqref", -0x13)
|
||||||
|
|
||||||
class WasmRefNullType(val heapType: WasmHeapType) : WasmType("ref null", -0x14)
|
data class WasmRefNullType(val heapType: WasmHeapType) : WasmType("ref null", -0x14)
|
||||||
class WasmRefType(val heapType: WasmHeapType) : WasmType("ref", -0x15)
|
data class WasmRefType(val heapType: WasmHeapType) : WasmType("ref", -0x15)
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object WasmI31Ref : WasmType("i31ref", -0x16)
|
object WasmI31Ref : WasmType("i31ref", -0x16)
|
||||||
class WasmRtt(val depth: Int, val type: WasmSymbolReadOnly<WasmTypeDeclaration>) : WasmType("rtt", -0x17)
|
data class WasmRtt(val type: WasmSymbolReadOnly<WasmTypeDeclaration>) : WasmType("rtt", -0x18)
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object WasmDataRef : WasmType("dataref", -0x19)
|
object WasmDataRef : WasmType("dataref", -0x19)
|
||||||
|
|
||||||
sealed class WasmHeapType {
|
sealed class WasmHeapType {
|
||||||
class Type(val type: WasmSymbolReadOnly<WasmTypeDeclaration>) : WasmHeapType() {
|
data class Type(val type: WasmSymbolReadOnly<WasmTypeDeclaration>) : WasmHeapType() {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Type:$type"
|
return "Type:$type"
|
||||||
}
|
}
|
||||||
@@ -46,6 +46,7 @@ sealed class WasmHeapType {
|
|||||||
sealed class Simple(val name: String, val code: Byte) : WasmHeapType() {
|
sealed class Simple(val name: String, val code: Byte) : WasmHeapType() {
|
||||||
object Func : Simple("func", -0x10)
|
object Func : Simple("func", -0x10)
|
||||||
object Extern : Simple("extern", -0x11)
|
object Extern : Simple("extern", -0x11)
|
||||||
|
object Any : Simple("any", -0x12)
|
||||||
object Eq : Simple("eq", -0x13)
|
object Eq : Simple("eq", -0x13)
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@@ -70,7 +71,8 @@ fun WasmType.getHeapType(): WasmHeapType =
|
|||||||
is WasmRefType -> heapType
|
is WasmRefType -> heapType
|
||||||
is WasmRefNullType -> heapType
|
is WasmRefNullType -> heapType
|
||||||
is WasmEqRef -> WasmHeapType.Simple.Eq
|
is WasmEqRef -> WasmHeapType.Simple.Eq
|
||||||
is WasmExternRef -> WasmHeapType.Simple.Extern
|
is WasmAnyRef -> WasmHeapType.Simple.Any
|
||||||
is WasmFuncRef -> WasmHeapType.Simple.Func
|
is WasmFuncRef -> WasmHeapType.Simple.Func
|
||||||
|
is WasmExternRef -> WasmHeapType.Simple.Extern
|
||||||
else -> error("Unknown heap type for type $this")
|
else -> error("Unknown heap type for type $this")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,12 +142,12 @@ abstract class WasmExpressionBuilder {
|
|||||||
buildInstr(WasmOp.REF_CAST)
|
buildInstr(WasmOp.REF_CAST)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildRefNull(type: WasmHeapType) {
|
fun buildRefCastStatic(type: WasmSymbolReadOnly<WasmTypeDeclaration>) {
|
||||||
buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(WasmRefType(type)))
|
buildInstr(WasmOp.REF_CAST_STATIC, WasmImmediate.TypeIdx(type))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildRttSub(decl: WasmSymbol<WasmTypeDeclaration>) {
|
fun buildRefNull(type: WasmHeapType) {
|
||||||
buildInstr(WasmOp.RTT_SUB, WasmImmediate.TypeIdx(decl))
|
buildInstr(WasmOp.REF_NULL, WasmImmediate.HeapType(WasmRefType(type)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildRttCanon(decl: WasmSymbol<WasmTypeDeclaration>) {
|
fun buildRttCanon(decl: WasmSymbol<WasmTypeDeclaration>) {
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
|
|||||||
val type = functionTypes[b.readVarUInt32AsInt()]
|
val type = functionTypes[b.readVarUInt32AsInt()]
|
||||||
importedFunctions += WasmFunction.Imported(
|
importedFunctions += WasmFunction.Imported(
|
||||||
name = "",
|
name = "",
|
||||||
type = type,
|
type = WasmSymbol(type),
|
||||||
importPair = importPair,
|
importPair = importPair,
|
||||||
).also { importsInOrder.add(it) }
|
).also { importsInOrder.add(it) }
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
|
|||||||
definedFunctions.add(
|
definedFunctions.add(
|
||||||
WasmFunction.Defined(
|
WasmFunction.Defined(
|
||||||
"",
|
"",
|
||||||
functionType,
|
WasmSymbol(functionType),
|
||||||
locals = functionType.parameterTypes.mapIndexed { index, wasmType ->
|
locals = functionType.parameterTypes.mapIndexed { index, wasmType ->
|
||||||
WasmLocal(index, "", wasmType, true)
|
WasmLocal(index, "", wasmType, true)
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
@@ -330,6 +330,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
|
|||||||
return WasmModule(
|
return WasmModule(
|
||||||
functionTypes = functionTypes,
|
functionTypes = functionTypes,
|
||||||
gcTypes = gcTypes,
|
gcTypes = gcTypes,
|
||||||
|
gcTypesInRecursiveGroup = false,
|
||||||
importsInOrder = importsInOrder,
|
importsInOrder = importsInOrder,
|
||||||
importedFunctions = importedFunctions,
|
importedFunctions = importedFunctions,
|
||||||
importedMemories = importedMemories,
|
importedMemories = importedMemories,
|
||||||
@@ -450,7 +451,7 @@ class WasmBinaryToIR(val b: MyByteReader) {
|
|||||||
(-0x20).toByte() -> {
|
(-0x20).toByte() -> {
|
||||||
val types = mapVector { readValueType() }
|
val types = mapVector { readValueType() }
|
||||||
val returnTypes = mapVector { readValueType() }
|
val returnTypes = mapVector { readValueType() }
|
||||||
return WasmFunctionType("", types, returnTypes)
|
return WasmFunctionType(types, returnTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> TODO()
|
else -> TODO()
|
||||||
@@ -466,8 +467,8 @@ class WasmBinaryToIR(val b: MyByteReader) {
|
|||||||
WasmI8,
|
WasmI8,
|
||||||
WasmI16,
|
WasmI16,
|
||||||
WasmFuncRef,
|
WasmFuncRef,
|
||||||
WasmExternRef,
|
|
||||||
WasmAnyRef,
|
WasmAnyRef,
|
||||||
|
WasmExternRef,
|
||||||
WasmEqRef
|
WasmEqRef
|
||||||
).associateBy { it.code }
|
).associateBy { it.code }
|
||||||
|
|
||||||
|
|||||||
@@ -21,13 +21,17 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule, val mod
|
|||||||
with(module) {
|
with(module) {
|
||||||
// type section
|
// type section
|
||||||
appendSection(1u) {
|
appendSection(1u) {
|
||||||
|
if (module.gcTypesInRecursiveGroup) {
|
||||||
|
appendVectorSize(1)
|
||||||
|
b.writeByte(0x4f)
|
||||||
|
}
|
||||||
appendVectorSize(functionTypes.size + gcTypes.size)
|
appendVectorSize(functionTypes.size + gcTypes.size)
|
||||||
functionTypes.forEach { appendFunctionTypeDeclaration(it) }
|
functionTypes.forEach { appendFunctionTypeDeclaration(it) }
|
||||||
gcTypes.forEach {
|
gcTypes.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is WasmStructDeclaration -> appendStructTypeDeclaration(it)
|
is WasmStructDeclaration -> appendStructTypeDeclaration(it)
|
||||||
is WasmArrayDeclaration -> appendArrayTypeDeclaration(it)
|
is WasmArrayDeclaration -> appendArrayTypeDeclaration(it)
|
||||||
is WasmFunctionType -> {}
|
is WasmFunctionType -> error("Function type in GC types")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,6 +281,12 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule, val mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun appendStructTypeDeclaration(type: WasmStructDeclaration) {
|
private fun appendStructTypeDeclaration(type: WasmStructDeclaration) {
|
||||||
|
val superType = type.superType
|
||||||
|
if (superType != null) {
|
||||||
|
b.writeVarInt7(-0x30)
|
||||||
|
appendVectorSize(1)
|
||||||
|
appendModuleFieldReference(superType.owner)
|
||||||
|
}
|
||||||
b.writeVarInt7(-0x21)
|
b.writeVarInt7(-0x21)
|
||||||
b.writeVarUInt32(type.fields.size)
|
b.writeVarUInt32(type.fields.size)
|
||||||
type.fields.forEach {
|
type.fields.forEach {
|
||||||
@@ -290,7 +300,7 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule, val mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
val WasmFunctionType.index: Int
|
val WasmFunctionType.index: Int
|
||||||
get() = module.functionTypes.indexOf(this)
|
get() = id!!
|
||||||
|
|
||||||
private fun appendLimits(limits: WasmLimits) {
|
private fun appendLimits(limits: WasmLimits) {
|
||||||
b.writeVarUInt1(limits.maxSize != null)
|
b.writeVarUInt1(limits.maxSize != null)
|
||||||
@@ -303,11 +313,11 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule, val mod
|
|||||||
b.writeString(function.importPair.moduleName)
|
b.writeString(function.importPair.moduleName)
|
||||||
b.writeString(function.importPair.declarationName)
|
b.writeString(function.importPair.declarationName)
|
||||||
b.writeByte(0) // Function external kind.
|
b.writeByte(0) // Function external kind.
|
||||||
b.writeVarUInt32(function.type.index)
|
b.writeVarUInt32(function.type.owner.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun appendDefinedFunction(function: WasmFunction.Defined) {
|
private fun appendDefinedFunction(function: WasmFunction.Defined) {
|
||||||
b.writeVarUInt32(function.type.index)
|
b.writeVarUInt32(function.type.owner.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun appendTable(table: WasmTable) {
|
private fun appendTable(table: WasmTable) {
|
||||||
@@ -483,7 +493,6 @@ class WasmIrToBinary(outputStream: OutputStream, val module: WasmModule, val mod
|
|||||||
appendHeapType(type.heapType)
|
appendHeapType(type.heapType)
|
||||||
}
|
}
|
||||||
if (type is WasmRtt) {
|
if (type is WasmRtt) {
|
||||||
b.writeVarUInt32(type.depth)
|
|
||||||
appendModuleFieldReference(type.type.owner)
|
appendModuleFieldReference(type.type.owner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,12 +246,26 @@ class WasmIrToText : SExpressionBuilder() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun maybeSubType(superType: WasmTypeDeclaration?, body: () -> Unit) {
|
||||||
|
if (superType != null) {
|
||||||
|
sameLineList("sub") {
|
||||||
|
appendModuleFieldReference(superType)
|
||||||
|
body()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun appendStructTypeDeclaration(type: WasmStructDeclaration) {
|
private fun appendStructTypeDeclaration(type: WasmStructDeclaration) {
|
||||||
newLineList("type") {
|
newLineList("type") {
|
||||||
appendModuleFieldReference(type)
|
appendModuleFieldReference(type)
|
||||||
sameLineList("struct") {
|
maybeSubType(type.superType?.owner) {
|
||||||
type.fields.forEach {
|
sameLineList("struct") {
|
||||||
appendStructField(it)
|
type.fields.forEach {
|
||||||
|
appendStructField(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,9 +301,9 @@ class WasmIrToText : SExpressionBuilder() {
|
|||||||
appendModuleFieldReference(function)
|
appendModuleFieldReference(function)
|
||||||
sameLineList("type") { appendModuleFieldReference(function.type) }
|
sameLineList("type") { appendModuleFieldReference(function.type) }
|
||||||
function.locals.forEach { if (it.isParameter) appendLocal(it) }
|
function.locals.forEach { if (it.isParameter) appendLocal(it) }
|
||||||
if (function.type.resultTypes.isNotEmpty()) {
|
if (function.type.owner.resultTypes.isNotEmpty()) {
|
||||||
sameLineList("result") {
|
sameLineList("result") {
|
||||||
function.type.resultTypes.forEach { appendType(it) }
|
function.type.owner.resultTypes.forEach { appendType(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function.locals.forEach { if (!it.isParameter) appendLocal(it) }
|
function.locals.forEach { if (!it.isParameter) appendLocal(it) }
|
||||||
@@ -438,6 +452,7 @@ class WasmIrToText : SExpressionBuilder() {
|
|||||||
fun appendReferencedType(type: WasmType) {
|
fun appendReferencedType(type: WasmType) {
|
||||||
when (type) {
|
when (type) {
|
||||||
is WasmFuncRef -> appendElement("func")
|
is WasmFuncRef -> appendElement("func")
|
||||||
|
is WasmAnyRef -> appendElement("any")
|
||||||
is WasmExternRef -> appendElement("extern")
|
is WasmExternRef -> appendElement("extern")
|
||||||
else -> TODO()
|
else -> TODO()
|
||||||
}
|
}
|
||||||
@@ -457,7 +472,6 @@ class WasmIrToText : SExpressionBuilder() {
|
|||||||
|
|
||||||
is WasmRtt ->
|
is WasmRtt ->
|
||||||
sameLineList("rtt") {
|
sameLineList("rtt") {
|
||||||
appendElement(type.depth.toString())
|
|
||||||
appendModuleFieldReference(type.type.owner)
|
appendModuleFieldReference(type.type.owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,6 +503,10 @@ class WasmIrToText : SExpressionBuilder() {
|
|||||||
if (id != 0) appendElement(id.toString())
|
if (id != 0) appendElement(id.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun appendModuleFieldReference(field: WasmSymbolReadOnly<WasmNamedModuleField>) {
|
||||||
|
appendModuleFieldReference(field.owner)
|
||||||
|
}
|
||||||
|
|
||||||
fun appendModuleFieldReference(field: WasmNamedModuleField) {
|
fun appendModuleFieldReference(field: WasmNamedModuleField) {
|
||||||
val id = field.id
|
val id = field.id
|
||||||
?: error("${field::class} ${field.name} ID is unlinked")
|
?: error("${field::class} ${field.name} ID is unlinked")
|
||||||
|
|||||||
Reference in New Issue
Block a user