diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2019-12-11 17:12:37 -0800 |
---|---|---|
committer | Alon Zakai <azakai@google.com> | 2019-12-11 17:12:37 -0800 |
commit | 759c485a9f35bd859d43b86b02e1397a669fa469 (patch) | |
tree | a5c7475002b406e35c6d1e5c2d843000947ef192 /src/passes/Print.cpp | |
parent | acd786dbd1e59f9d105c4ec8603c2ff46f233649 (diff) | |
download | binaryen-759c485a9f35bd859d43b86b02e1397a669fa469.tar.gz binaryen-759c485a9f35bd859d43b86b02e1397a669fa469.tar.bz2 binaryen-759c485a9f35bd859d43b86b02e1397a669fa469.zip |
Remove FunctionType (#2510)
Function signatures were previously redundantly stored on Function
objects as well as on FunctionType objects. These two signature
representations had to always be kept in sync, which was error-prone
and needlessly complex. This PR takes advantage of the new ability of
Type to represent multiple value types by consolidating function
signatures as a pair of Types (params and results) stored on the
Function object.
Since there are no longer module-global named function types,
significant changes had to be made to the printing and emitting of
function types, as well as their parsing and manipulation in various
passes.
The C and JS APIs and their tests also had to be updated to remove
named function types.
Diffstat (limited to 'src/passes/Print.cpp')
-rw-r--r-- | src/passes/Print.cpp | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 2ec92a086..f8e913079 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -27,14 +27,16 @@ namespace wasm { -static bool isFullForced() { +namespace { + +bool isFullForced() { if (getenv("BINARYEN_PRINT_FULL")) { return std::stoi(getenv("BINARYEN_PRINT_FULL")) != 0; } return false; } -static std::ostream& printName(Name name, std::ostream& o) { +std::ostream& printName(Name name, std::ostream& o) { // we need to quote names if they have tricky chars if (!name.str || !strpbrk(name.str, "()")) { o << '$' << name.str; @@ -55,6 +57,36 @@ static std::ostream& printLocal(Index index, Function* func, std::ostream& o) { return printName(name, o); } +// Wrapper for printing signature names +struct SigName { + Signature sig; + SigName(Signature sig) : sig(sig) {} +}; + +std::ostream& operator<<(std::ostream& os, SigName sigName) { + auto printType = [&](Type type) { + if (type == Type::none) { + os << "none"; + } else { + const std::vector<Type>& types = type.expand(); + for (size_t i = 0; i < types.size(); ++i) { + if (i != 0) { + os << '_'; + } + os << types[i]; + } + } + }; + + os << '$'; + printType(sigName.sig.params); + os << "_=>_"; + printType(sigName.sig.results); + return os; +} + +} // anonymous namespace + // Printing "unreachable" as a instruction prefix type is not valid in wasm text // format. Print something else to make it pass. static Type forceConcrete(Type type) { return type.isConcrete() ? type : i32; } @@ -126,7 +158,7 @@ struct PrintExpressionContents } else { printMedium(o, "call_indirect (type "); } - printName(curr->fullType, o) << ')'; + o << SigName(curr->sig) << ')'; } void visitLocalGet(LocalGet* curr) { printMedium(o, "local.get "); @@ -1869,19 +1901,18 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { o << ')'; } // Module-level visitors - void visitFunctionType(FunctionType* curr, Name* internalName = nullptr) { + void handleSignature(Signature curr, Name* funcName = nullptr) { o << "(func"; - if (internalName) { - o << ' '; - printName(*internalName, o); + if (funcName) { + o << " $" << *funcName; } - if (curr->params.size() > 0) { + if (curr.params.size() > 0) { o << maybeSpace; - o << ParamType(Type(curr->params)); + o << ParamType(curr.params); } - if (curr->result != none) { + if (curr.results.size() > 0) { o << maybeSpace; - o << ResultType(curr->result); + o << ResultType(curr.results); } o << ")"; } @@ -1963,12 +1994,7 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { lastPrintedLocation = {0, 0, 0}; o << '('; emitImportHeader(curr); - if (curr->type.is()) { - visitFunctionType(currModule->getFunctionType(curr->type), &curr->name); - } else { - auto functionType = sigToFunctionType(getSig(curr)); - visitFunctionType(&functionType, &curr->name); - } + handleSignature(curr->sig, &curr->name); o << ')'; o << maybeNewLine; } @@ -1993,21 +2019,19 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { if (!printStackIR && curr->stackIR && !minify) { o << " (; has Stack IR ;)"; } - if (curr->type.is()) { - o << maybeSpace << "(type "; - printName(curr->type, o) << ')'; - } - if (curr->params.size() > 0) { - for (size_t i = 0; i < curr->params.size(); i++) { + const std::vector<Type>& params = curr->sig.params.expand(); + if (params.size() > 0) { + for (size_t i = 0; i < params.size(); i++) { o << maybeSpace; o << '('; printMinor(o, "param "); - printLocal(i, currFunction, o) << ' ' << curr->getLocalType(i) << ')'; + printLocal(i, currFunction, o); + o << ' ' << params[i] << ')'; } } - if (curr->result != none) { + if (curr->sig.results != Type::none) { o << maybeSpace; - o << ResultType(curr->result); + o << ResultType(curr->sig.results); } incIndent(); for (size_t i = curr->getVarIndexBase(); i < curr->getNumLocals(); i++) { @@ -2204,12 +2228,15 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { o << '('; printMajor(o, "module"); incIndent(); - for (auto& child : curr->functionTypes) { + std::vector<Signature> signatures; + std::unordered_map<Signature, Index> indices; + ModuleUtils::collectSignatures(*curr, signatures, indices); + for (auto sig : signatures) { doIndent(o, indent); o << '('; printMedium(o, "type") << ' '; - printName(child->name, o) << ' '; - visitFunctionType(child.get()); + o << SigName(sig) << ' '; + handleSignature(sig); o << ")" << maybeNewLine; } ModuleUtils::iterImportedMemories( |