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);