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

Commit 2eecaeb

Browse files
authored
Merge pull request #109 from sjrd/cleanup-module-structure
Refactor the module structure and type definitions.
2 parents 1f19bad + 46c436b commit 2eecaeb

12 files changed

+448
-502
lines changed

Diff for: wasm/src/main/scala/converters/WasmBinaryWriter.scala

+38-58
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,8 @@ import wasm.wasm4s.WasmInstr.{BlockType, END}
1414
final class WasmBinaryWriter(module: WasmModule, emitDebugInfo: Boolean) {
1515
import WasmBinaryWriter._
1616

17-
private val allTypeDefinitions: List[WasmTypeDefinition[_ <: WasmTypeName]] = {
18-
module.recGroupTypes :::
19-
module.functionTypes :::
20-
module.arrayTypes
21-
}
22-
23-
private val importTypeDefinitions: List[WasmFunctionType] = {
24-
module.imports.flatMap { imprt =>
25-
imprt.desc match {
26-
case WasmImportDesc.Func(id, typ) => List(typ)
27-
case WasmImportDesc.Global(_, _, _) => Nil
28-
case WasmImportDesc.Tag(id, typ) => List(typ)
29-
}
30-
}
31-
}
32-
3317
private val typeIdxValues: Map[WasmTypeName, Int] =
34-
allTypeDefinitions.map(_.name).zipWithIndex.toMap
18+
module.recTypes.flatMap(_.subTypes).map(_.name).zipWithIndex.toMap
3519

3620
private val dataIdxValues: Map[WasmDataName, Int] =
3721
module.data.map(_.name).zipWithIndex.toMap
@@ -122,42 +106,45 @@ final class WasmBinaryWriter(module: WasmModule, emitDebugInfo: Boolean) {
122106
}
123107

124108
private def writeTypeSection(buf: Buffer): Unit = {
125-
buf.u32(1 + importTypeDefinitions.size) // a single `rectype` + the import type definitions
126-
127-
// the big rectype
109+
buf.vec(module.recTypes) { recType =>
110+
recType.subTypes match {
111+
case singleSubType :: Nil =>
112+
writeSubType(buf, singleSubType)
113+
case subTypes =>
114+
buf.byte(0x4E) // `rectype`
115+
buf.vec(subTypes)(writeSubType(buf, _))
116+
}
117+
}
118+
}
128119

129-
buf.byte(0x4E) // `rectype` tag
130-
buf.u32(typeIdxValues.size) // number of `subtype`s in our single `rectype`
120+
private def writeSubType(buf: Buffer, subType: WasmSubType): Unit = {
121+
subType match {
122+
case WasmSubType(_, true, None, compositeType) =>
123+
writeCompositeType(buf, compositeType)
124+
case _ =>
125+
buf.byte(if (subType.isFinal) 0x4F else 0x50)
126+
buf.opt(subType.superType)(writeTypeIdx(buf, _))
127+
writeCompositeType(buf, subType.compositeType)
128+
}
129+
}
131130

131+
private def writeCompositeType(buf: Buffer, compositeType: WasmCompositeType): Unit = {
132132
def writeFieldType(field: WasmStructField): Unit = {
133133
writeType(buf, field.typ)
134134
buf.boolean(field.isMutable)
135135
}
136136

137-
for (typeDef <- allTypeDefinitions) {
138-
typeDef match {
139-
case WasmArrayType(name, field) =>
140-
buf.byte(0x5E) // array
141-
writeFieldType(field)
142-
case WasmStructType(name, fields, superType) =>
143-
buf.byte(0x50) // sub
144-
buf.opt(superType)(writeTypeIdx(buf, _))
145-
buf.byte(0x5F) // struct
146-
buf.vec(fields)(writeFieldType(_))
147-
case WasmFunctionType(name, params, results) =>
148-
buf.byte(0x60) // func
149-
writeResultType(buf, params)
150-
writeResultType(buf, results)
151-
}
152-
}
153-
154-
// the import type definitions, outside the rectype
155-
156-
for (typeDef <- importTypeDefinitions) {
157-
val WasmFunctionType(name, params, results) = typeDef
158-
buf.byte(0x60) // func
159-
writeResultType(buf, params)
160-
writeResultType(buf, results)
137+
compositeType match {
138+
case WasmArrayType(field) =>
139+
buf.byte(0x5E) // array
140+
writeFieldType(field)
141+
case WasmStructType(fields) =>
142+
buf.byte(0x5F) // struct
143+
buf.vec(fields)(writeFieldType(_))
144+
case WasmFunctionType(params, results) =>
145+
buf.byte(0x60) // func
146+
writeResultType(buf, params)
147+
writeResultType(buf, results)
161148
}
162149
}
163150

@@ -166,32 +153,25 @@ final class WasmBinaryWriter(module: WasmModule, emitDebugInfo: Boolean) {
166153
buf.name(imprt.module)
167154
buf.name(imprt.name)
168155

169-
val indexBase = allTypeDefinitions.size
170-
val importedFunTypeIdx =
171-
importTypeDefinitions.map(_.name).zipWithIndex.map(kv => (kv._1, kv._2 + indexBase)).toMap
172-
173-
def writeImportedTypeIdx(typeName: WasmTypeName.WasmFunctionTypeName): Unit =
174-
buf.u32(importedFunTypeIdx(typeName))
175-
176156
imprt.desc match {
177-
case WasmImportDesc.Func(id, typ) =>
157+
case WasmImportDesc.Func(id, typeName) =>
178158
buf.byte(0x00) // func
179-
writeImportedTypeIdx(typ.name)
159+
writeTypeIdx(buf, typeName)
180160
case WasmImportDesc.Global(id, typ, isMutable) =>
181161
buf.byte(0x03) // global
182162
writeType(buf, typ)
183163
buf.boolean(isMutable)
184-
case WasmImportDesc.Tag(id, typ) =>
164+
case WasmImportDesc.Tag(id, typeName) =>
185165
buf.byte(0x04) // tag
186166
buf.byte(0x00) // exception kind (that is the only valid kind for now)
187-
writeImportedTypeIdx(typ.name)
167+
writeTypeIdx(buf, typeName)
188168
}
189169
}
190170
}
191171

192172
private def writeFunctionSection(buf: Buffer): Unit = {
193173
buf.vec(module.definedFunctions) { fun =>
194-
writeTypeIdx(buf, fun.typ.name)
174+
writeTypeIdx(buf, fun.typeName)
195175
}
196176
}
197177

Diff for: wasm/src/main/scala/converters/WasmTextWriter.scala

+76-65
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,7 @@ class WasmTextWriter {
1818
private def writeModule(module: WasmModule)(implicit b: WatBuilder): Unit = {
1919
b.newLineList(
2020
"module", {
21-
b.newLineList(
22-
"rec", {
23-
module.recGroupTypes.foreach(writeGCTypeDefinition)
24-
module.functionTypes.foreach(writeFunctionType)
25-
module.arrayTypes.foreach(writeGCTypeDefinition)
26-
}
27-
)
21+
module.recTypes.foreach(writeRecType)
2822
module.imports.foreach(writeImport)
2923
module.definedFunctions.foreach(writeFunction)
3024
module.tags.foreach(writeTag)
@@ -37,9 +31,42 @@ class WasmTextWriter {
3731
)
3832
}
3933

40-
private def writeGCTypeDefinition(
41-
t: WasmGCTypeDefinition
42-
)(implicit b: WatBuilder): Unit = {
34+
private def writeRecType(recType: WasmRecType)(implicit b: WatBuilder): Unit = {
35+
recType.subTypes match {
36+
case singleSubType :: Nil =>
37+
writeTypeDefinition(singleSubType)
38+
case subTypes =>
39+
b.newLineList(
40+
"rec", {
41+
subTypes.foreach(writeTypeDefinition)
42+
}
43+
)
44+
}
45+
}
46+
47+
private def writeTypeDefinition(subType: WasmSubType)(implicit b: WatBuilder): Unit = {
48+
b.newLineList(
49+
"type", {
50+
b.appendElement(subType.name.show)
51+
subType match {
52+
case WasmSubType(_, true, None, compositeType) =>
53+
writeCompositeType(compositeType)
54+
case _ =>
55+
b.sameLineList(
56+
"sub", {
57+
if (subType.isFinal)
58+
b.appendElement("final")
59+
for (superType <- subType.superType)
60+
b.appendElement(superType.show)
61+
writeCompositeType(subType.compositeType)
62+
}
63+
)
64+
}
65+
}
66+
)
67+
}
68+
69+
private def writeCompositeType(t: WasmCompositeType)(implicit b: WatBuilder): Unit = {
4370
def writeField(field: WasmStructField): Unit = {
4471
b.sameLineList(
4572
"field", {
@@ -55,60 +82,40 @@ class WasmTextWriter {
5582
)
5683
}
5784

58-
b.newLineList(
59-
"type", {
60-
b.appendElement(t.name.show)
61-
t match {
62-
case WasmArrayType(name, field) =>
63-
b.sameLineList(
64-
"array", {
65-
if (field.isMutable)
66-
b.sameLineList(
67-
"mut", {
68-
writeType(field.typ)
69-
}
70-
)
71-
else writeType(field.typ)
72-
73-
}
74-
)
75-
// (type $kotlin.Any___type_13 (struct (field (ref $kotlin.Any.vtable___type_12)) (field (ref null struct)) (field (mut i32)) (field (mut i32))))
76-
case WasmStructType(name, fields, superType) =>
77-
b.sameLineList(
78-
"sub", {
79-
superType.foreach(s => b.appendElement(s.show))
80-
b.sameLineList(
81-
"struct", {
82-
fields.foreach(writeField)
83-
}
84-
)
85-
}
86-
)
87-
}
88-
}
89-
)
90-
}
91-
92-
private def writeFunctionType(
93-
functionType: WasmFunctionType
94-
)(implicit b: WatBuilder): Unit =
95-
// (type type-name (func (param ty) (param ty) (result ty)))
96-
b.newLineList(
97-
"type", {
98-
b.appendElement(functionType.name.show)
85+
t match {
86+
case WasmFunctionType(params, results) =>
9987
b.sameLineList(
10088
"func", {
101-
functionType.params.foreach { ty =>
89+
params.foreach { ty =>
10290
b.sameLineList("param", writeType(ty))
10391
}
104-
if (functionType.results.nonEmpty)
105-
functionType.results.foreach { ty =>
106-
b.sameLineList("result", writeType(ty))
107-
}
92+
results.foreach { ty =>
93+
b.sameLineList("result", writeType(ty))
94+
}
10895
}
10996
)
110-
}
111-
)
97+
98+
case WasmArrayType(field) =>
99+
b.sameLineList(
100+
"array", {
101+
if (field.isMutable)
102+
b.sameLineList(
103+
"mut", {
104+
writeType(field.typ)
105+
}
106+
)
107+
else writeType(field.typ)
108+
}
109+
)
110+
111+
case WasmStructType(fields) =>
112+
b.sameLineList(
113+
"struct", {
114+
fields.foreach(writeField)
115+
}
116+
)
117+
}
118+
}
112119

113120
private def writeImport(i: WasmImport)(implicit b: WatBuilder): Unit = {
114121
b.newLineList(
@@ -117,11 +124,11 @@ class WasmTextWriter {
117124
b.appendElement("\"" + i.name + "\"")
118125

119126
i.desc match {
120-
case WasmImportDesc.Func(id, typ) =>
127+
case WasmImportDesc.Func(id, typeName) =>
121128
b.sameLineList(
122129
"func", {
123130
b.appendElement(id.show)
124-
writeSig(typ.params, typ.results)
131+
writeTypeUse(typeName)
125132
}
126133
)
127134
case WasmImportDesc.Global(id, typ, isMutable) =>
@@ -134,11 +141,11 @@ class WasmTextWriter {
134141
writeType(typ)
135142
}
136143
)
137-
case WasmImportDesc.Tag(id, typ) =>
144+
case WasmImportDesc.Tag(id, typeName) =>
138145
b.sameLineList(
139146
"tag", {
140147
b.appendElement(id.show)
141-
writeSig(typ.params, typ.results)
148+
writeTypeUse(typeName)
142149
}
143150
)
144151
}
@@ -176,11 +183,11 @@ class WasmTextWriter {
176183
"func", {
177184
val (params, nonParams) = f.locals.partition(_.isParameter)
178185
b.appendElement(f.name.show)
179-
b.sameLineListOne("type", f.typ.name.show)
186+
writeTypeUse(f.typeName)
180187

181188
b.newLine()
182189
params.foreach(writeParam)
183-
f.typ.results.foreach(r => { b.sameLineList("result", writeType(r)) })
190+
f.results.foreach(r => { b.sameLineList("result", writeType(r)) })
184191

185192
b.newLine()
186193
if (nonParams.nonEmpty) {
@@ -195,7 +202,7 @@ class WasmTextWriter {
195202
b.newLineList(
196203
"tag", {
197204
b.appendElement(tag.name.show)
198-
b.sameLineListOne("type", tag.typ.show)
205+
writeTypeUse(tag.typ)
199206
}
200207
)
201208
}
@@ -269,6 +276,10 @@ class WasmTextWriter {
269276
)
270277
}
271278

279+
private def writeTypeUse(typeName: WasmTypeName)(implicit b: WatBuilder): Unit = {
280+
b.sameLineListOne("type", typeName.show)
281+
}
282+
272283
private def writeType(typ: WasmStorageType)(implicit b: WatBuilder): Unit = {
273284
typ match {
274285
case typ: WasmSimpleType => b.appendElement(typ.textName)

0 commit comments

Comments
 (0)