[Wasm] Use final Wasm structs for types without subtypes
A version of PR https://github.com/JetBrains/kotlin/pull/5175 contributed by Yair Morgenstern, modified by Slava Kuzmich ^KT-60505 Fixed
This commit is contained in:
committed by
Space Team
parent
2b4d1b0fb1
commit
88e35fafd9
+10
-4
@@ -215,7 +215,8 @@ class DeclarationGenerator(
|
|||||||
val struct = WasmStructDeclaration(
|
val struct = WasmStructDeclaration(
|
||||||
name = "classITable",
|
name = "classITable",
|
||||||
fields = fields,
|
fields = fields,
|
||||||
superType = null
|
superType = null,
|
||||||
|
isFinal = true,
|
||||||
)
|
)
|
||||||
|
|
||||||
iFacesUnion.forEach {
|
iFacesUnion.forEach {
|
||||||
@@ -227,6 +228,7 @@ class DeclarationGenerator(
|
|||||||
methods: List<VirtualMethodMetadata>,
|
methods: List<VirtualMethodMetadata>,
|
||||||
name: String,
|
name: String,
|
||||||
superType: WasmSymbolReadOnly<WasmTypeDeclaration>? = null,
|
superType: WasmSymbolReadOnly<WasmTypeDeclaration>? = null,
|
||||||
|
isFinal: Boolean,
|
||||||
): WasmStructDeclaration {
|
): WasmStructDeclaration {
|
||||||
val tableFields = methods.map {
|
val tableFields = methods.map {
|
||||||
WasmStructFieldDeclaration(
|
WasmStructFieldDeclaration(
|
||||||
@@ -240,6 +242,7 @@ class DeclarationGenerator(
|
|||||||
name = name,
|
name = name,
|
||||||
fields = tableFields,
|
fields = tableFields,
|
||||||
superType = superType,
|
superType = superType,
|
||||||
|
isFinal = isFinal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +253,8 @@ class DeclarationGenerator(
|
|||||||
val vtableStruct = createVirtualTableStruct(
|
val vtableStruct = createVirtualTableStruct(
|
||||||
metadata.virtualMethods,
|
metadata.virtualMethods,
|
||||||
vtableName,
|
vtableName,
|
||||||
superType = metadata.superClass?.klass?.symbol?.let(context::referenceVTableGcType)
|
superType = metadata.superClass?.klass?.symbol?.let(context::referenceVTableGcType),
|
||||||
|
isFinal = klass.modality == Modality.FINAL
|
||||||
)
|
)
|
||||||
context.defineVTableGcType(metadata.klass.symbol, vtableStruct)
|
context.defineVTableGcType(metadata.klass.symbol, vtableStruct)
|
||||||
|
|
||||||
@@ -357,7 +361,8 @@ class DeclarationGenerator(
|
|||||||
if (symbol in hierarchyDisjointUnions) {
|
if (symbol in hierarchyDisjointUnions) {
|
||||||
val vtableStruct = createVirtualTableStruct(
|
val vtableStruct = createVirtualTableStruct(
|
||||||
methods = context.getInterfaceMetadata(symbol).methods,
|
methods = context.getInterfaceMetadata(symbol).methods,
|
||||||
name = "$nameStr.itable"
|
name = "$nameStr.itable",
|
||||||
|
isFinal = true,
|
||||||
)
|
)
|
||||||
context.defineVTableGcType(symbol, vtableStruct)
|
context.defineVTableGcType(symbol, vtableStruct)
|
||||||
}
|
}
|
||||||
@@ -384,7 +389,8 @@ class DeclarationGenerator(
|
|||||||
val structType = WasmStructDeclaration(
|
val structType = WasmStructDeclaration(
|
||||||
name = nameStr,
|
name = nameStr,
|
||||||
fields = fields,
|
fields = fields,
|
||||||
superType = superClass?.let { context.referenceGcType(superClass.klass.symbol) }
|
superType = superClass?.let { context.referenceGcType(superClass.klass.symbol) },
|
||||||
|
isFinal = declaration.modality == Modality.FINAL
|
||||||
)
|
)
|
||||||
context.defineGcType(symbol, structType)
|
context.defineGcType(symbol, structType)
|
||||||
context.generateTypeInfo(symbol, binaryDataStruct(metadata))
|
context.generateTypeInfo(symbol, binaryDataStruct(metadata))
|
||||||
|
|||||||
@@ -155,7 +155,8 @@ data class WasmFunctionType(
|
|||||||
class WasmStructDeclaration(
|
class WasmStructDeclaration(
|
||||||
name: String,
|
name: String,
|
||||||
val fields: List<WasmStructFieldDeclaration>,
|
val fields: List<WasmStructFieldDeclaration>,
|
||||||
val superType: WasmSymbolReadOnly<WasmTypeDeclaration>?
|
val superType: WasmSymbolReadOnly<WasmTypeDeclaration>?,
|
||||||
|
val isFinal: Boolean
|
||||||
) : WasmTypeDeclaration(name)
|
) : WasmTypeDeclaration(name)
|
||||||
|
|
||||||
class WasmArrayDeclaration(
|
class WasmArrayDeclaration(
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ class WasmIrToBinary(
|
|||||||
private var b: ByteWriter = ByteWriter.OutputStream(outputStream)
|
private var b: ByteWriter = ByteWriter.OutputStream(outputStream)
|
||||||
|
|
||||||
// "Stack" of offsets waiting initialization.
|
// "Stack" of offsets waiting initialization.
|
||||||
// Since blocks has as a prefix variable length number encoding its size we can't calculate absolute offsets inside those blocks
|
// Since blocks have as a prefix variable length number encoding its size, we can't calculate absolute offsets inside those blocks
|
||||||
// until we generate whole block and generate size. So, we put them into "stack" and initialize as soo as we have all required data.
|
// until we generate the whole block and generate size. So, we put them into "stack" and initialize as soon as we have all required data.
|
||||||
private var offsets = persistentListOf<Box>()
|
private var offsets = persistentListOf<Box>()
|
||||||
|
|
||||||
fun appendWasmModule() {
|
fun appendWasmModule() {
|
||||||
@@ -76,7 +76,7 @@ class WasmIrToBinary(
|
|||||||
val numRecGroups = if (recGroupTypes.isEmpty()) 0 else 1
|
val numRecGroups = if (recGroupTypes.isEmpty()) 0 else 1
|
||||||
appendVectorSize(functionTypes.size + numRecGroups)
|
appendVectorSize(functionTypes.size + numRecGroups)
|
||||||
functionTypes.forEach { appendFunctionTypeDeclaration(it) }
|
functionTypes.forEach { appendFunctionTypeDeclaration(it) }
|
||||||
if (!recGroupTypes.isEmpty()) {
|
if (recGroupTypes.isNotEmpty()) {
|
||||||
b.writeVarInt7(WasmBinary.REC_GROUP)
|
b.writeVarInt7(WasmBinary.REC_GROUP)
|
||||||
appendVectorSize(recGroupTypes.size)
|
appendVectorSize(recGroupTypes.size)
|
||||||
recGroupTypes.forEach {
|
recGroupTypes.forEach {
|
||||||
@@ -361,14 +361,26 @@ class WasmIrToBinary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun appendStructTypeDeclaration(type: WasmStructDeclaration) {
|
private fun appendStructTypeDeclaration(type: WasmStructDeclaration) {
|
||||||
b.writeVarInt7(WasmBinary.SUB_TYPE)
|
|
||||||
|
|
||||||
val superType = type.superType
|
val superType = type.superType
|
||||||
if (superType != null) {
|
|
||||||
appendVectorSize(1)
|
// https://webassembly.github.io/gc/core/binary/types.html#binary-subtype
|
||||||
appendModuleFieldReference(superType.owner)
|
if (superType == null && type.isFinal) {
|
||||||
|
// Short encoding form for final types without subtypes.
|
||||||
} else {
|
} else {
|
||||||
appendVectorSize(0)
|
// General encoding
|
||||||
|
b.writeVarInt7(
|
||||||
|
if (type.isFinal)
|
||||||
|
WasmBinary.SUB_FINAL_TYPE
|
||||||
|
else
|
||||||
|
WasmBinary.SUB_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
if (superType != null) {
|
||||||
|
appendVectorSize(1)
|
||||||
|
appendModuleFieldReference(superType.owner)
|
||||||
|
} else {
|
||||||
|
appendVectorSize(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b.writeVarInt7(WasmBinary.STRUCT_TYPE)
|
b.writeVarInt7(WasmBinary.STRUCT_TYPE)
|
||||||
|
|||||||
Reference in New Issue
Block a user