@@ -47,7 +47,7 @@ class WasmTextWriter {
47
47
private def writeTypeDefinition (subType : WasmSubType )(implicit b : WatBuilder ): Unit = {
48
48
b.newLineList(
49
49
" type" , {
50
- b.appendElement (subType.name.show )
50
+ b.appendName (subType.name)
51
51
subType match {
52
52
case WasmSubType (_, true , None , compositeType) =>
53
53
writeCompositeType(compositeType)
@@ -57,7 +57,7 @@ class WasmTextWriter {
57
57
if (subType.isFinal)
58
58
b.appendElement(" final" )
59
59
for (superType <- subType.superType)
60
- b.appendElement (superType.show )
60
+ b.appendName (superType)
61
61
writeCompositeType(subType.compositeType)
62
62
}
63
63
)
@@ -70,7 +70,7 @@ class WasmTextWriter {
70
70
def writeField (field : WasmStructField ): Unit = {
71
71
b.sameLineList(
72
72
" field" , {
73
- b.appendElement (field.name.show )
73
+ b.appendName (field.name)
74
74
if (field.isMutable)
75
75
b.sameLineList(
76
76
" mut" , {
@@ -127,14 +127,14 @@ class WasmTextWriter {
127
127
case WasmImportDesc .Func (id, typeName) =>
128
128
b.sameLineList(
129
129
" func" , {
130
- b.appendElement (id.show )
130
+ b.appendName (id)
131
131
writeTypeUse(typeName)
132
132
}
133
133
)
134
134
case WasmImportDesc .Global (id, typ, isMutable) =>
135
135
b.sameLineList(
136
136
" global" , {
137
- b.appendElement (id.show )
137
+ b.appendName (id)
138
138
if (isMutable)
139
139
b.sameLineList(" mut" , writeType(typ))
140
140
else
@@ -144,7 +144,7 @@ class WasmTextWriter {
144
144
case WasmImportDesc .Tag (id, typeName) =>
145
145
b.sameLineList(
146
146
" tag" , {
147
- b.appendElement (id.show )
147
+ b.appendName (id)
148
148
writeTypeUse(typeName)
149
149
}
150
150
)
@@ -164,7 +164,7 @@ class WasmTextWriter {
164
164
def writeParam (l : WasmLocal )(implicit b : WatBuilder ): Unit = {
165
165
b.sameLineList(
166
166
" param" , {
167
- b.appendElement (l.name.show )
167
+ b.appendName (l.name)
168
168
writeType(l.typ)
169
169
}
170
170
)
@@ -173,7 +173,7 @@ class WasmTextWriter {
173
173
def writeLocal (l : WasmLocal )(implicit b : WatBuilder ): Unit = {
174
174
b.sameLineList(
175
175
" local" , {
176
- b.appendElement (l.name.show )
176
+ b.appendName (l.name)
177
177
writeType(l.typ)
178
178
}
179
179
)
@@ -182,7 +182,7 @@ class WasmTextWriter {
182
182
b.newLineList(
183
183
" func" , {
184
184
val (params, nonParams) = f.locals.partition(_.isParameter)
185
- b.appendElement (f.name.show )
185
+ b.appendName (f.name)
186
186
writeTypeUse(f.typeName)
187
187
188
188
b.newLine()
@@ -201,7 +201,7 @@ class WasmTextWriter {
201
201
private def writeTag (tag : WasmTag )(implicit b : WatBuilder ): Unit = {
202
202
b.newLineList(
203
203
" tag" , {
204
- b.appendElement (tag.name.show )
204
+ b.appendName (tag.name)
205
205
writeTypeUse(tag.typ)
206
206
}
207
207
)
@@ -210,7 +210,7 @@ class WasmTextWriter {
210
210
private def writeGlobal (g : WasmGlobal )(implicit b : WatBuilder ) =
211
211
b.newLineList(
212
212
" global" , {
213
- b.appendElement (g.name.show )
213
+ b.appendName (g.name)
214
214
if (g.isMutable)
215
215
b.sameLineList(" mut" , writeType(g.typ))
216
216
else writeType(g.typ)
@@ -227,12 +227,12 @@ class WasmTextWriter {
227
227
case WasmExport .Function (_, funcName) =>
228
228
b.sameLineList(
229
229
" func" ,
230
- { b.appendElement (funcName.show ) }
230
+ { b.appendName (funcName) }
231
231
)
232
232
case WasmExport .Global (_, globalName) =>
233
233
b.sameLineList(
234
234
" global" ,
235
- { b.appendElement (globalName.show ) }
235
+ { b.appendName (globalName) }
236
236
)
237
237
}
238
238
}
@@ -241,7 +241,7 @@ class WasmTextWriter {
241
241
private def writeStart (startFunction : WasmFunctionName )(implicit b : WatBuilder ): Unit = {
242
242
b.newLineList(
243
243
" start" , {
244
- b.appendElement (startFunction.show )
244
+ b.appendName (startFunction)
245
245
}
246
246
)
247
247
}
@@ -267,7 +267,7 @@ class WasmTextWriter {
267
267
private def writeData (data : WasmData )(implicit b : WatBuilder ): Unit = {
268
268
b.newLineList(
269
269
" data" , {
270
- b.appendElement (data.name.show )
270
+ b.appendName (data.name)
271
271
data.mode match {
272
272
case WasmData .Mode .Passive => ()
273
273
}
@@ -277,7 +277,7 @@ class WasmTextWriter {
277
277
}
278
278
279
279
private def writeTypeUse (typeName : WasmTypeName )(implicit b : WatBuilder ): Unit = {
280
- b.sameLineListOne (" type" , typeName.show )
280
+ b.sameLineList (" type" , b.appendName(typeName) )
281
281
}
282
282
283
283
private def writeType (typ : WasmStorageType )(implicit b : WatBuilder ): Unit = {
@@ -301,7 +301,7 @@ class WasmTextWriter {
301
301
302
302
private def writeHeapType (heapType : WasmHeapType )(implicit b : WatBuilder ): Unit = {
303
303
heapType match {
304
- case WasmHeapType .Type (typeName) => b.appendElement (typeName.show )
304
+ case WasmHeapType .Type (typeName) => b.appendName (typeName)
305
305
case heapType : WasmHeapType .AbsHeapType => b.appendElement(heapType.textName)
306
306
}
307
307
}
@@ -317,15 +317,15 @@ class WasmTextWriter {
317
317
private def writeBlockType (blockType : BlockType )(implicit b : WatBuilder ): Unit = {
318
318
blockType match {
319
319
case BlockType .FunctionType (name) =>
320
- b.appendElement( s " (type ${ name.show} ) " )
320
+ writeTypeUse( name)
321
321
case BlockType .ValueType (optTy) =>
322
322
for (ty <- optTy)
323
323
b.sameLineList(" result" , writeType(ty))
324
324
}
325
325
}
326
326
327
327
private def writeLabelIdx (labelIdx : WasmLabelName )(implicit b : WatBuilder ): Unit =
328
- b.appendElement (labelIdx.show )
328
+ b.appendName (labelIdx)
329
329
330
330
private def writeInstr (instr : WasmInstr )(implicit b : WatBuilder ): Unit = {
331
331
instr match {
@@ -367,21 +367,21 @@ class WasmTextWriter {
367
367
case instr : WasmLabelInstr =>
368
368
writeLabelIdx(instr.labelArgument)
369
369
case instr : WasmFuncInstr =>
370
- b.appendElement (instr.funcArgument.show )
370
+ b.appendName (instr.funcArgument)
371
371
case instr : WasmTypeInstr =>
372
- b.appendElement (instr.typeArgument.show )
372
+ b.appendName (instr.typeArgument)
373
373
case instr : WasmTagInstr =>
374
- b.appendElement (instr.tagArgument.show )
374
+ b.appendName (instr.tagArgument)
375
375
case instr : WasmLocalInstr =>
376
- b.appendElement (instr.localArgument.show )
376
+ b.appendName (instr.localArgument)
377
377
case instr : WasmGlobalInstr =>
378
- b.appendElement (instr.globalArgument.show )
378
+ b.appendName (instr.globalArgument)
379
379
case instr : WasmHeapTypeInstr =>
380
380
writeHeapType(instr.heapTypeArgument)
381
381
case instr : WasmRefTypeInstr =>
382
382
writeType(instr.refTypeArgument)
383
383
case instr : WasmStructFieldInstr =>
384
- b.appendElement (instr.structTypeName.show )
384
+ b.appendName (instr.structTypeName)
385
385
b.appendElement(instr.fieldIdx.value.toString())
386
386
387
387
// Specific instructions with unique-ish shapes
@@ -400,23 +400,23 @@ class WasmTextWriter {
400
400
for (clause <- clauses) {
401
401
b.sameLineList(
402
402
clause.mnemonic, {
403
- clause.tag.foreach(tag => b.appendElement (tag.show ))
403
+ clause.tag.foreach(tag => b.appendName (tag))
404
404
writeLabelIdx(clause.label)
405
405
}
406
406
)
407
407
}
408
408
409
409
case ARRAY_NEW_DATA (typeIdx, dataIdx) =>
410
- b.appendElement (typeIdx.show )
411
- b.appendElement (dataIdx.show )
410
+ b.appendName (typeIdx)
411
+ b.appendName (dataIdx)
412
412
413
413
case ARRAY_NEW_FIXED (typeIdx, length) =>
414
- b.appendElement (typeIdx.show )
414
+ b.appendName (typeIdx)
415
415
b.appendElement(Integer .toUnsignedString(length))
416
416
417
417
case ARRAY_COPY (destType, srcType) =>
418
- b.appendElement (destType.show )
419
- b.appendElement (srcType.show )
418
+ b.appendName (destType)
419
+ b.appendName (srcType)
420
420
421
421
case BR_ON_CAST (labelIdx, from, to) =>
422
422
writeLabelIdx(labelIdx)
@@ -474,6 +474,22 @@ object WasmTextWriter {
474
474
builder.append(value)
475
475
}
476
476
477
+ def appendName (name : WasmName ): Unit =
478
+ appendElement(" $" + sanitizeWatIdentifier(name.name))
479
+
480
+ /** @see https://webassembly.github.io/spec/core/text/values.html#text-id */
481
+ private def sanitizeWatIdentifier (name : String ): String = {
482
+ if (name.isEmpty) " _"
483
+ else if (name.forall(isValidWatIdentifierChar)) name
484
+ else name.map(c => if (isValidWatIdentifierChar(c)) c else '_' ).mkString
485
+ }
486
+
487
+ private def isValidWatIdentifierChar (c : Char ): Boolean = {
488
+ c.isDigit || c.isLetter ||
489
+ " !#$%&'*+-./:<=>?@\\ ^_`|~" .contains(c) ||
490
+ " $.@_" .contains(c)
491
+ }
492
+
477
493
override def toString : String =
478
494
builder.toString()
479
495
}
0 commit comments