Skip to content

Commit a276c7e

Browse files
authored
Support printing recursive types (WebAssembly#3624)
Also fixes a few locations in Print.cpp where types were being printed directly rather than going through the s-expression type printer and removes vestigial wrapper types that were no longer used.
1 parent 1ba4d25 commit a276c7e

5 files changed

Lines changed: 285 additions & 240 deletions

File tree

src/passes/Print.cpp

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -229,25 +229,15 @@ void TypeNamePrinter::print(const Rtt& rtt) {
229229

230230
} // anonymous namespace
231231

232-
// Unlike the default format, tuple types in s-expressions should not have
233-
// commas.
234-
struct SExprType {
235-
Type type;
236-
SExprType(Type type) : type(type){};
237-
};
238-
239-
static std::ostream& printSExprType(std::ostream& o,
240-
const SExprType& sType,
241-
Module* wasm = nullptr) {
242-
Type type = sType.type;
232+
static std::ostream& printType(std::ostream& o, Type type, Module* wasm) {
243233
if (type.isBasic()) {
244234
o << type;
245235
} else if (type.isTuple()) {
246236
o << '(';
247237
auto sep = "";
248238
for (const auto& t : type) {
249239
o << sep;
250-
printSExprType(o, t, wasm);
240+
printType(o, t, wasm);
251241
sep = " ";
252242
}
253243
o << ')';
@@ -272,32 +262,35 @@ static std::ostream& printSExprType(std::ostream& o,
272262
return o;
273263
}
274264

275-
// TODO: try to simplify or even remove this, as we may be able to do the same
276-
// things with SExprType
277-
struct ResultTypeName {
278-
Type type;
279-
ResultTypeName(Type type) : type(type) {}
280-
};
281-
282-
std::ostream& printResultTypeName(std::ostream& os,
283-
ResultTypeName typeName,
284-
Module* wasm = nullptr) {
285-
auto type = typeName.type;
286-
os << "(result ";
265+
static std::ostream& printPrefixedTypes(std::ostream& o,
266+
const char* prefix,
267+
Type type,
268+
Module* wasm) {
269+
o << '(' << prefix;
270+
if (type == Type::none) {
271+
return o << ')';
272+
}
287273
if (type.isTuple()) {
288274
// Tuple types are not printed in parens, we can just emit them one after
289275
// the other in the same list as the "result".
290-
auto sep = "";
291276
for (auto t : type) {
292-
os << sep;
293-
sep = " ";
294-
printSExprType(os, t, wasm);
277+
o << ' ';
278+
printType(o, t, wasm);
295279
}
296280
} else {
297-
printSExprType(os, type, wasm);
281+
o << ' ';
282+
printType(o, type, wasm);
298283
}
299-
os << ')';
300-
return os;
284+
o << ')';
285+
return o;
286+
}
287+
288+
static std::ostream& printResultType(std::ostream& o, Type type, Module* wasm) {
289+
return printPrefixedTypes(o, "result", type, wasm);
290+
}
291+
292+
static std::ostream& printParamType(std::ostream& o, Type type, Module* wasm) {
293+
return printPrefixedTypes(o, "param", type, wasm);
301294
}
302295

303296
// Generic processing of a struct's field, given an optional module. Calls func
@@ -352,14 +345,14 @@ struct PrintExpressionContents
352345
}
353346
if (curr->type.isConcrete()) {
354347
o << ' ';
355-
printResultTypeName(o, curr->type, wasm);
348+
printResultType(o, curr->type, wasm);
356349
}
357350
}
358351
void visitIf(If* curr) {
359352
printMedium(o, "if");
360353
if (curr->type.isConcrete()) {
361354
o << ' ';
362-
printResultTypeName(o, curr->type, wasm);
355+
printResultType(o, curr->type, wasm);
363356
}
364357
}
365358
void visitLoop(Loop* curr) {
@@ -370,7 +363,7 @@ struct PrintExpressionContents
370363
}
371364
if (curr->type.isConcrete()) {
372365
o << ' ';
373-
printResultTypeName(o, curr->type, wasm);
366+
printResultType(o, curr->type, wasm);
374367
}
375368
}
376369
void visitBreak(Break* curr) {
@@ -1840,7 +1833,7 @@ struct PrintExpressionContents
18401833
restoreNormalColor(o);
18411834
if (curr->type.isRef()) {
18421835
o << ' ';
1843-
printResultTypeName(o, curr->type, wasm);
1836+
printResultType(o, curr->type, wasm);
18441837
}
18451838
}
18461839
void visitDrop(Drop* curr) { printMedium(o, "drop"); }
@@ -1881,7 +1874,8 @@ struct PrintExpressionContents
18811874
printName(curr->name, o);
18821875
}
18831876
if (curr->type.isConcrete()) {
1884-
o << ' ' << ResultType(curr->type);
1877+
o << ' ';
1878+
printResultType(o, curr->type, wasm);
18851879
}
18861880
}
18871881
void visitThrow(Throw* curr) {
@@ -2401,7 +2395,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
24012395
auto sep = "";
24022396
for (auto type : curr.params) {
24032397
o << sep;
2404-
printSExprType(o, type, currModule);
2398+
printType(o, type, currModule);
24052399
sep = " ";
24062400
}
24072401
o << ')';
@@ -2412,7 +2406,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
24122406
auto sep = "";
24132407
for (auto type : curr.results) {
24142408
o << sep;
2415-
printSExprType(o, type, currModule);
2409+
printType(o, type, currModule);
24162410
sep = " ";
24172411
}
24182412
o << ')';
@@ -2432,7 +2426,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
24322426
WASM_UNREACHABLE("invalid packed type");
24332427
}
24342428
} else {
2435-
printSExprType(o, field.type, currModule);
2429+
printType(o, field.type, currModule);
24362430
}
24372431
if (field.mutable_) {
24382432
o << ')';
@@ -2513,9 +2507,9 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
25132507
void emitGlobalType(Global* curr) {
25142508
if (curr->mutable_) {
25152509
o << "(mut ";
2516-
printSExprType(o, curr->type, currModule) << ')';
2510+
printType(o, curr->type, currModule) << ')';
25172511
} else {
2518-
printSExprType(o, curr->type, currModule);
2512+
printType(o, curr->type, currModule);
25192513
}
25202514
}
25212515
void visitImportedGlobal(Global* curr) {
@@ -2576,21 +2570,21 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
25762570
printMinor(o, "param ");
25772571
printLocal(i, currFunction, o);
25782572
o << ' ';
2579-
printSExprType(o, param, currModule) << ')';
2573+
printType(o, param, currModule) << ')';
25802574
++i;
25812575
}
25822576
}
25832577
if (curr->sig.results != Type::none) {
25842578
o << maybeSpace;
2585-
printResultTypeName(o, curr->sig.results, currModule);
2579+
printResultType(o, curr->sig.results, currModule);
25862580
}
25872581
incIndent();
25882582
for (size_t i = curr->getVarIndexBase(); i < curr->getNumLocals(); i++) {
25892583
doIndent(o, indent);
25902584
o << '(';
25912585
printMinor(o, "local ");
25922586
printLocal(i, currFunction, o) << ' ';
2593-
printSExprType(o, curr->getLocalType(i), currModule) << ')';
2587+
printType(o, curr->getLocalType(i), currModule) << ')';
25942588
o << maybeNewLine;
25952589
}
25962590
// Print the body.
@@ -2641,7 +2635,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
26412635
o << "(event ";
26422636
printName(curr->name, o);
26432637
o << maybeSpace << "(attr " << curr->attribute << ')' << maybeSpace;
2644-
o << ParamType(curr->sig.params);
2638+
printParamType(o, curr->sig.params, currModule);
26452639
o << "))";
26462640
o << maybeNewLine;
26472641
}
@@ -2651,7 +2645,7 @@ struct PrintSExpression : public UnifiedExpressionVisitor<PrintSExpression> {
26512645
printMedium(o, "event ");
26522646
printName(curr->name, o);
26532647
o << maybeSpace << "(attr " << curr->attribute << ')' << maybeSpace;
2654-
o << ParamType(curr->sig.params);
2648+
printParamType(o, curr->sig.params, currModule);
26552649
o << ")" << maybeNewLine;
26562650
}
26572651
void printTableHeader(Table* curr) {

src/wasm-type.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -281,20 +281,6 @@ class Type {
281281
const Type& operator[](size_t i) const;
282282
};
283283

284-
// Wrapper type for formatting types as "(param i32 i64 f32)"
285-
struct ParamType {
286-
Type type;
287-
ParamType(Type type) : type(type) {}
288-
std::string toString() const;
289-
};
290-
291-
// Wrapper type for formatting types as "(result i32 i64 f32)"
292-
struct ResultType {
293-
Type type;
294-
ResultType(Type type) : type(type) {}
295-
std::string toString() const;
296-
};
297-
298284
class HeapType {
299285
// Unlike `Type`, which represents the types of values on the WebAssembly
300286
// stack, `HeapType` is used to describe the structures that reference types
@@ -509,14 +495,12 @@ struct TypeBuilder {
509495
};
510496

511497
std::ostream& operator<<(std::ostream&, Type);
512-
std::ostream& operator<<(std::ostream&, ParamType);
513-
std::ostream& operator<<(std::ostream&, ResultType);
498+
std::ostream& operator<<(std::ostream&, HeapType);
514499
std::ostream& operator<<(std::ostream&, Tuple);
515500
std::ostream& operator<<(std::ostream&, Signature);
516501
std::ostream& operator<<(std::ostream&, Field);
517502
std::ostream& operator<<(std::ostream&, Struct);
518503
std::ostream& operator<<(std::ostream&, Array);
519-
std::ostream& operator<<(std::ostream&, HeapType);
520504
std::ostream& operator<<(std::ostream&, Rtt);
521505

522506
} // namespace wasm

0 commit comments

Comments
 (0)