WIP: filter wasm-dis to only disassemble certain specified functions
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 51c7e9f..5d277f8 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp
@@ -423,11 +423,16 @@ const char *maybeSpace; const char *maybeNewLine; - bool full = false; // whether to not elide nodes in output when possible - // (like implicit blocks) and to emit types - bool printStackIR = false; // whether to print stack IR if it is present - // (if false, and Stack IR is there, we just - // note it exists) + // whether to not elide nodes in output when possible + // (like implicit blocks) and to emit types + bool full = false; + // whether to print stack IR if it is present + // (if false, and Stack IR is there, we just + // note it exists) + bool printStackIR = false; + // if null, print the entire module, otherwise print only + // the single function with this name + Name singleFunctionName; Module* currModule = nullptr; Function* currFunction = nullptr; @@ -474,6 +479,8 @@ void setFull(bool full_) { full = full_; } + void setSingleFunction(Name const& name) { singleFunctionName = name; } + void incIndent() { if (minify) return; o << '\n'; @@ -1059,53 +1066,59 @@ o << '('; printMajor(o, "module"); incIndent(); - for (auto& child : curr->functionTypes) { - doIndent(o, indent); - o << '('; - printMedium(o, "type") << ' '; - printName(child->name, o) << ' '; - visitFunctionType(child.get()); - o << ")" << maybeNewLine; - } - ModuleUtils::iterImportedMemories(*curr, [&](Memory* memory) { - visitMemory(memory); - }); - ModuleUtils::iterImportedTables(*curr, [&](Table* table) { - visitTable(table); - }); - ModuleUtils::iterImportedGlobals(*curr, [&](Global* global) { - visitGlobal(global); - }); - ModuleUtils::iterImportedFunctions(*curr, [&](Function* func) { - visitFunction(func); - }); - ModuleUtils::iterDefinedMemories(*curr, [&](Memory* memory) { - visitMemory(memory); - }); - ModuleUtils::iterDefinedTables(*curr, [&](Table* table) { - visitTable(table); - }); - ModuleUtils::iterDefinedGlobals(*curr, [&](Global* global) { - visitGlobal(global); - }); - for (auto& child : curr->exports) { - doIndent(o, indent); - visitExport(child.get()); - o << maybeNewLine; - } - if (curr->start.is()) { - doIndent(o, indent); - o << '('; - printMedium(o, "start") << ' ' << curr->start << ')'; - o << maybeNewLine; + if (singleFunctionName.isNull()) { + for (auto& child : curr->functionTypes) { + doIndent(o, indent); + o << '('; + printMedium(o, "type") << ' '; + printName(child->name, o) << ' '; + visitFunctionType(child.get()); + o << ")" << maybeNewLine; + } + ModuleUtils::iterImportedMemories(*curr, [&](Memory* memory) { + visitMemory(memory); + }); + ModuleUtils::iterImportedTables(*curr, [&](Table* table) { + visitTable(table); + }); + ModuleUtils::iterImportedGlobals(*curr, [&](Global* global) { + visitGlobal(global); + }); + ModuleUtils::iterImportedFunctions(*curr, [&](Function* func) { + visitFunction(func); + }); + ModuleUtils::iterDefinedMemories(*curr, [&](Memory* memory) { + visitMemory(memory); + }); + ModuleUtils::iterDefinedTables(*curr, [&](Table* table) { + visitTable(table); + }); + ModuleUtils::iterDefinedGlobals(*curr, [&](Global* global) { + visitGlobal(global); + }); + for (auto& child : curr->exports) { + doIndent(o, indent); + visitExport(child.get()); + o << maybeNewLine; + } + if (curr->start.is()) { + doIndent(o, indent); + o << '('; + printMedium(o, "start") << ' ' << curr->start << ')'; + o << maybeNewLine; + } } ModuleUtils::iterDefinedFunctions(*curr, [&](Function* func) { - visitFunction(func); + if (singleFunctionName.is() && func->name.hasSubstring(singleFunctionName)) { + visitFunction(func); + } }); - for (auto& section : curr->userSections) { - doIndent(o, indent); - o << ";; custom section \"" << section.name << "\", size " << section.data.size(); - o << maybeNewLine; + if (singleFunctionName.isNull()) { + for (auto& section : curr->userSections) { + doIndent(o, indent); + o << ";; custom section \"" << section.name << "\", size " << section.data.size(); + o << maybeNewLine; + } } decIndent(); o << maybeNewLine; @@ -1203,6 +1216,14 @@ return printModule(module, std::cout); } +std::ostream& WasmPrinter::printSingleFunction(Module* module, Name const& name, std::ostream& o) { + PrintSExpression print(o); + print.setMinify(false); + print.setSingleFunction(name); + print.visitModule(module); + return o; +} + std::ostream& WasmPrinter::printExpression(Expression* expression, std::ostream& o, bool minify, bool full) { if (!expression) { o << "(null expression)";
diff --git a/src/tools/wasm-dis.cpp b/src/tools/wasm-dis.cpp index 3ff6819..22fd125 100644 --- a/src/tools/wasm-dis.cpp +++ b/src/tools/wasm-dis.cpp
@@ -29,6 +29,7 @@ int main(int argc, const char *argv[]) { std::string sourceMapFilename; + std::string singleFunctionName; Options options("wasm-dis", "Un-assemble a .wasm (WebAssembly binary format) into a .wast (WebAssembly text format)"); options.add("--output", "-o", "Output file (stdout if not specified)", Options::Arguments::One, @@ -39,6 +40,11 @@ .add("--source-map", "-sm", "Consume source map from the specified file to add location information", Options::Arguments::One, [&sourceMapFilename](Options *o, const std::string& argument) { sourceMapFilename = argument; }) + .add("--func", "-f", "Only disassemble a single function", + Options::Arguments::One, + [&singleFunctionName](Options *o, const std::string& argument) { + singleFunctionName = argument; + }) .add_positional("INFILE", Options::Arguments::One, [](Options *o, const std::string& argument) { o->extra["infile"] = argument; @@ -61,7 +67,11 @@ if (options.debug) std::cerr << "Printing..." << std::endl; Output output(options.extra["output"], Flags::Text, options.debug ? Flags::Debug : Flags::Release); - WasmPrinter::printModule(&wasm, output.getStream()); + if (singleFunctionName == "") { + WasmPrinter::printModule(&wasm, output.getStream()); + } else { + WasmPrinter::printSingleFunction(&wasm, Name(singleFunctionName.c_str()), output.getStream()); + } output << '\n'; if (options.debug) std::cerr << "Done." << std::endl;
diff --git a/src/wasm-printing.h b/src/wasm-printing.h index d3327aa..ae61659 100644 --- a/src/wasm-printing.h +++ b/src/wasm-printing.h
@@ -21,6 +21,7 @@ #include "wasm.h" #include "pass.h" +#include "support/name.h" namespace wasm { @@ -29,6 +30,8 @@ static std::ostream& printModule(Module* module); + static std::ostream& printSingleFunction(Module* module, Name const& name, std::ostream& o); + static std::ostream& printExpression(Expression* expression, std::ostream& o, bool minify = false, bool full = false); static std::ostream& printStackInst(StackInst* inst, std::ostream& o, Function* func=nullptr);