Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Store the name data of classes along with constant strings. #112

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions wasm/src/main/scala/ir2wasm/HelperFunctions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,17 @@ object HelperFunctions {
instrs += CALL(WasmFunctionName.stringConcat)
} {
// it is not an array; its name is stored in nameData
instrs += LOCAL_GET(typeDataParam)
instrs += STRUCT_GET(
WasmStructTypeName.typeData,
WasmFieldIdx.typeData.nameDataIdx
)
instrs += REF_AS_NOT_NULL
instrs += CALL(WasmFunctionName.createStringFromData)
for (
idx <- List(
WasmFieldIdx.typeData.nameOffsetIdx,
WasmFieldIdx.typeData.nameSizeIdx,
WasmFieldIdx.typeData.nameStringIndexIdx
)
) {
instrs += LOCAL_GET(typeDataParam)
instrs += STRUCT_GET(WasmStructTypeName.typeData, idx)
}
instrs += CALL(WasmFunctionName.stringLiteral)
}

// typeData.name := <top of stack> ; leave it on the stack
Expand Down Expand Up @@ -483,7 +487,9 @@ object HelperFunctions {
instrs += LOCAL_GET(typeDataParam)

// typeData := new typeData(...)
instrs += REF_NULL(WasmHeapType.None) // nameData
instrs += I32_CONST(0) // nameOffset
instrs += I32_CONST(0) // nameSize
instrs += I32_CONST(0) // nameStringIndex
instrs += I32_CONST(KindArray) // kind = KindArray
instrs += I32_CONST(0) // specialInstanceTypes = 0

Expand Down
8 changes: 1 addition & 7 deletions wasm/src/main/scala/ir2wasm/WasmBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,7 @@ class WasmBuilder(coreSpec: CoreSpec) {
)
}

val nameDataValueItems = nameStr.toList.map(c => I32_CONST(c.toInt))
val nameDataValueArrayNew =
ARRAY_NEW_FIXED(
WasmTypeName.WasmArrayTypeName.i16Array,
nameDataValueItems.size
)
val nameDataValue: List[WasmInstr] = nameDataValueItems :+ nameDataValueArrayNew
val nameDataValue: List[WasmInstr] = ctx.getConstantStringDataInstr(nameStr)

val strictAncestorsValue: List[WasmInstr] = {
typeRef match {
Expand Down
38 changes: 23 additions & 15 deletions wasm/src/main/scala/wasm4s/Names.scala
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,18 @@ object Names {
// Fields of the typeData structs
object typeData {

/** The name data as `(ref null (array u16))` so that it can be initialized as a constant.
/** The name data as the 3 arguments to `stringLiteral`.
*
* It is non-null for primitives and for classes. It is null for array types, as array types
* compute their `name` from the `name` of their component type.
* It is only meaningful for primitives and for classes. For array types, they are all 0, as
* array types compute their `name` from the `name` of their component type.
*/
val nameData = new WasmFieldName("nameData")
val nameOffset = new WasmFieldName("nameOffset")

/** See `nameOffset`. */
val nameSize = new WasmFieldName("nameSize")

/** See `nameOffset`. */
val nameStringIndex = new WasmFieldName("nameStringIndex")

/** The kind of type data, an `i32`.
*
Expand Down Expand Up @@ -410,17 +416,19 @@ object Names {
val uniqueRegularField = WasmFieldIdx(2)

object typeData {
val nameDataIdx = WasmFieldIdx(0)
val kindIdx = WasmFieldIdx(1)
val specialInstanceTypesIdx = WasmFieldIdx(2)
val strictAncestorsIdx = WasmFieldIdx(3)
val componentTypeIdx = WasmFieldIdx(4)
val nameIdx = WasmFieldIdx(5)
val classOfIdx = WasmFieldIdx(6)
val arrayOfIdx = WasmFieldIdx(7)
val cloneFunctionIdx = WasmFieldIdx(8)
val isJSClassInstanceIdx = WasmFieldIdx(9)
val reflectiveProxiesIdx = WasmFieldIdx(10)
val nameOffsetIdx = WasmFieldIdx(0)
val nameSizeIdx = WasmFieldIdx(1)
val nameStringIndexIdx = WasmFieldIdx(2)
val kindIdx = WasmFieldIdx(3)
val specialInstanceTypesIdx = WasmFieldIdx(4)
val strictAncestorsIdx = WasmFieldIdx(5)
val componentTypeIdx = WasmFieldIdx(6)
val nameIdx = WasmFieldIdx(7)
val classOfIdx = WasmFieldIdx(8)
val arrayOfIdx = WasmFieldIdx(9)
val cloneFunctionIdx = WasmFieldIdx(10)
val isJSClassInstanceIdx = WasmFieldIdx(11)
val reflectiveProxiesIdx = WasmFieldIdx(12)
}

object reflectiveProxy {
Expand Down
14 changes: 12 additions & 2 deletions wasm/src/main/scala/wasm4s/Wasm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,18 @@ object WasmStructType {
def typeData(implicit ctx: ReadOnlyWasmContext): WasmStructType = WasmStructType(
List(
WasmStructField(
WasmFieldName.typeData.nameData,
WasmRefType.nullable(WasmArrayTypeName.i16Array),
WasmFieldName.typeData.nameOffset,
WasmInt32,
isMutable = false
),
WasmStructField(
WasmFieldName.typeData.nameSize,
WasmInt32,
isMutable = false
),
WasmStructField(
WasmFieldName.typeData.nameStringIndex,
WasmInt32,
isMutable = false
),
WasmStructField(
Expand Down
8 changes: 5 additions & 3 deletions wasm/src/main/scala/wasm4s/WasmContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,18 @@ abstract class TypeDefinableWasmContext extends ReadOnlyWasmContext { this: Wasm
}
}

def getConstantStringInstr(str: String): List[WasmInstr] = {
def getConstantStringInstr(str: String): List[WasmInstr] =
getConstantStringDataInstr(str) :+ WasmInstr.CALL(WasmFunctionName.stringLiteral)

def getConstantStringDataInstr(str: String): List[WasmInstr.I32_CONST] = {
val data = addConstantStringGlobal(str)
List(
WasmInstr.I32_CONST(data.offset),
// Assuming that the stringLiteral method will instantiate the
// constant string from the data section using "array.newData $i16Array ..."
// The length of the array should be equal to the length of the WTF-16 encoded string
WasmInstr.I32_CONST(str.length()),
WasmInstr.I32_CONST(data.constantStringIndex),
WasmInstr.CALL(WasmFunctionName.stringLiteral)
WasmInstr.I32_CONST(data.constantStringIndex)
)
}

Expand Down