diff options
author | JF Bastien <jfb@chromium.org> | 2016-01-11 17:23:27 -0800 |
---|---|---|
committer | JF Bastien <jfb@chromium.org> | 2016-01-11 17:23:27 -0800 |
commit | 1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810 (patch) | |
tree | 606226cd0b851f09999647643476c492a80a93a3 /src | |
parent | 75a562190a9f4588c8ffb19b8304f76c15a850c6 (diff) | |
download | binaryen-1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810.tar.gz binaryen-1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810.tar.bz2 binaryen-1b3600b0aca6a8f23b6d9e8ae33dcd75c9493810.zip |
asm2wasm: use support's command-line
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm-main.cpp | 81 | ||||
-rw-r--r-- | src/asm2wasm.h | 17 | ||||
-rw-r--r-- | src/s2wasm-main.cpp | 2 | ||||
-rw-r--r-- | src/support/command-line.cpp | 25 | ||||
-rw-r--r-- | src/support/command-line.h | 4 | ||||
-rw-r--r-- | src/support/file.cpp | 9 | ||||
-rw-r--r-- | src/support/file.h | 9 | ||||
-rw-r--r-- | src/wasm-js.cpp | 2 |
8 files changed, 91 insertions, 58 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp index 6a784bd76..1fd1273c0 100644 --- a/src/asm2wasm-main.cpp +++ b/src/asm2wasm-main.cpp @@ -18,64 +18,71 @@ // asm2wasm console tool // +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" + #include "asm2wasm.h" using namespace cashew; using namespace wasm; -namespace wasm { -int debug = 0; -} - -int main(int argc, char **argv) { - debug = getenv("ASM2WASM_DEBUG") ? getenv("ASM2WASM_DEBUG")[0] - '0' : 0; - - char *infile = argv[1]; - char *mappedGlobals = argc < 3 ? nullptr : argv[2]; +int main(int argc, const char *argv[]) { + Options options("asm2wasm", "Translate asm.js files to .wast files"); + options + .add("--output", "-o", "Output file (stdout if not specified)", + Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["output"] = argument; + Colors::disable(); + }) + .add("--mapped-globals", "-m", "Mapped globals", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["mapped globals"] = argument; + }) + .add_positional("INFILE", Options::Arguments::One, + [](Options *o, const std::string &argument) { + o->extra["infile"] = argument; + }); + options.parse(argc, argv); - if (debug) std::cerr << "loading '" << infile << "'...\n"; - FILE *f = fopen(argv[1], "r"); - assert(f); - fseek(f, 0, SEEK_END); - int size = ftell(f); - char *input = new char[size+1]; - rewind(f); - int num = fread(input, 1, size, f); - // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when - // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one), - // so return value of fread can be less than size reported by ftell, and that is normal. - assert((num > 0 || size == 0) && num <= size); - fclose(f); - input[num] = 0; + const auto &mg_it = options.extra.find("mapped globals"); + const char *mappedGlobals = + mg_it == options.extra.end() ? nullptr : mg_it->second.c_str(); Asm2WasmPreProcessor pre; - input = pre.process(input); + auto input( + read_file<std::vector<char>>(options.extra["infile"], options.debug)); + char *start = pre.process(input.data()); - if (debug) std::cerr << "parsing...\n"; + if (options.debug) std::cerr << "parsing..." << std::endl; cashew::Parser<Ref, DotZeroValueBuilder> builder; - Ref asmjs = builder.parseToplevel(input); - if (debug) { - std::cerr << "parsed:\n"; + Ref asmjs = builder.parseToplevel(start); + if (options.debug) { + std::cerr << "parsed:" << std::endl; asmjs->stringify(std::cerr, true); - std::cerr << '\n'; + std::cerr << std::endl; } - if (debug) std::cerr << "wasming...\n"; + if (options.debug) std::cerr << "wasming..." << std::endl; AllocatingModule wasm; - wasm.memory.initial = wasm.memory.max = 16*1024*1024; // we would normally receive this from the compiler - Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth); + wasm.memory.initial = wasm.memory.max = + 16 * 1024 * 1024; // we would normally receive this from the compiler + Asm2WasmBuilder asm2wasm(wasm, pre.memoryGrowth, options.debug); asm2wasm.processAsm(asmjs); - if (debug) std::cerr << "optimizing...\n"; + if (options.debug) std::cerr << "optimizing..." << std::endl; asm2wasm.optimize(); - if (debug) std::cerr << "printing...\n"; - std::cout << wasm; + if (options.debug) std::cerr << "printing..." << std::endl; + Output output(options.extra["output"], options.debug); + output << wasm; if (mappedGlobals) { - if (debug) std::cerr << "serializing mapped globals...\n"; + if (options.debug) + std::cerr << "serializing mapped globals..." << std::endl; asm2wasm.serializeMappedGlobals(mappedGlobals); } - if (debug) std::cerr << "done.\n"; + if (options.debug) std::cerr << "done." << std::endl; } diff --git a/src/asm2wasm.h b/src/asm2wasm.h index db7cc1ae0..11cb75b30 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -33,8 +33,6 @@ namespace wasm { using namespace cashew; -extern int debug; // wasm::debug is set in main(), typically from an env var - // Utilities static void abort_on(std::string why, Ref element) { @@ -151,6 +149,7 @@ class Asm2WasmBuilder { std::map<CallIndirect*, IString> callIndirects; // track these, as we need to fix them after we know the functionTableStarts. this maps call => its function table bool memoryGrowth; + int debug; public: std::map<IString, MappedGlobal> mappedGlobals; @@ -267,10 +266,16 @@ private: } public: - Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth) : wasm(wasm), allocator(wasm.allocator), nextGlobal(8), maxGlobal(1000), memoryGrowth(memoryGrowth) {} - - void processAsm(Ref ast); - void optimize(); + Asm2WasmBuilder(AllocatingModule& wasm, bool memoryGrowth, int debug) + : wasm(wasm), + allocator(wasm.allocator), + nextGlobal(8), + maxGlobal(1000), + memoryGrowth(memoryGrowth), + debug(debug) {} + + void processAsm(Ref ast); + void optimize(); private: AsmType detectAsmType(Ref ast, AsmData *data) { diff --git a/src/s2wasm-main.cpp b/src/s2wasm-main.cpp index 277cee365..d0dd60bbf 100644 --- a/src/s2wasm-main.cpp +++ b/src/s2wasm-main.cpp @@ -45,7 +45,7 @@ int main(int argc, const char *argv[]) { }); options.parse(argc, argv); - std::string input(read_file(options.extra["infile"], options.debug)); + auto input(read_file<std::string>(options.extra["infile"], options.debug)); if (options.debug) std::cerr << "Parsing and wasming..." << std::endl; AllocatingModule wasm; diff --git a/src/support/command-line.cpp b/src/support/command-line.cpp index 659c055c9..c078ef45f 100644 --- a/src/support/command-line.cpp +++ b/src/support/command-line.cpp @@ -19,7 +19,7 @@ using namespace wasm; Options::Options(const std::string &command, const std::string &description) - : debug(false), positional(Arguments::Zero) { + : debug(0), positional(Arguments::Zero) { add("--help", "-h", "Show this help message and exit", Arguments::Zero, [this, command, description](Options *o, const std::string &) { std::cerr << command; @@ -39,8 +39,10 @@ Options::Options(const std::string &command, const std::string &description) std::cerr << '\n'; exit(EXIT_SUCCESS); }); - add("--debug", "-d", "Print debug information to stderr", Arguments::Zero, - [](Options *o, const std::string &) { o->debug = true; }); + add("--debug", "-d", "Print debug information to stderr", Arguments::Optional, + [](Options *o, const std::string &arguments) { + o->debug = arguments.size() ? std::stoi(arguments) : 1; + }); } Options::~Options() {} @@ -79,6 +81,7 @@ void Options::parse(int argc, const char *argv[]) { << "'\n"; exit(EXIT_FAILURE); case Arguments::One: + case Arguments::Optional: if (positionalsSeen) { std::cerr << "Unexpected second positional argument '" << currentOption << "' for " << positionalName << '\n'; @@ -88,6 +91,7 @@ void Options::parse(int argc, const char *argv[]) { case Arguments::N: positionalAction(this, currentOption); ++positionalsSeen; + break; } continue; } @@ -110,8 +114,8 @@ void Options::parse(int argc, const char *argv[]) { switch (option->arguments) { case Arguments::Zero: if (argument.size()) { - std::cerr << "Unexpected argument '" << argument - << "' for option '" << currentOption << "'\n"; + std::cerr << "Unexpected argument '" << argument << "' for option '" + << currentOption << "'\n"; exit(EXIT_FAILURE); } break; @@ -121,15 +125,22 @@ void Options::parse(int argc, const char *argv[]) { << currentOption << "'\n"; exit(EXIT_FAILURE); } - // Fallthrough. + // Fallthrough. case Arguments::N: if (!argument.size()) { if (i + 1 == e) { - std::cerr << "Couldn't find expected argument for '" << currentOption << "'\n"; + std::cerr << "Couldn't find expected argument for '" + << currentOption << "'\n"; exit(EXIT_FAILURE); } argument = argv[++i]; } + break; + case Arguments::Optional: + if (!argument.size()) { + if (i + 1 != e) argument = argv[++i]; + } + break; } option->action(this, argument); ++option->seen; diff --git a/src/support/command-line.h b/src/support/command-line.h index 14dbce57f..6e0af846e 100644 --- a/src/support/command-line.h +++ b/src/support/command-line.h @@ -35,9 +35,9 @@ namespace wasm { class Options { public: typedef std::function<void(Options *, const std::string &)> Action; - enum class Arguments { Zero, One, N }; + enum class Arguments { Zero, One, N, Optional }; - bool debug; + int debug; std::map<std::string, std::string> extra; Options(const std::string &command, const std::string &description); diff --git a/src/support/file.cpp b/src/support/file.cpp index 470d07737..8813750d4 100644 --- a/src/support/file.cpp +++ b/src/support/file.cpp @@ -18,7 +18,8 @@ #include <cstdlib> -std::string wasm::read_file(const std::string &filename, bool debug) { +template <typename T> +T wasm::read_file(const std::string &filename, bool debug) { if (debug) std::cerr << "Loading '" << filename << "'..." << std::endl; std::ifstream infile(filename); if (!infile.is_open()) { @@ -27,12 +28,16 @@ std::string wasm::read_file(const std::string &filename, bool debug) { } infile.seekg(0, std::ios::end); size_t insize = infile.tellg(); - std::string input(insize + 1, '\0'); + T input(insize + 1, '\0'); infile.seekg(0); infile.read(&input[0], insize); return input; } +// Explicit instantiations for the explicit specializations. +template std::string wasm::read_file<>(const std::string &, bool); +template std::vector<char> wasm::read_file<>(const std::string &, bool); + wasm::Output::Output(const std::string &filename, bool debug) : outfile(), out([this, filename, debug]() { std::streambuf *buffer; diff --git a/src/support/file.h b/src/support/file.h index e9c35f5f3..5e464d6c1 100644 --- a/src/support/file.h +++ b/src/support/file.h @@ -25,9 +25,14 @@ #include <iostream> #include <string> #include <utility> +#include <vector> namespace wasm { -std::string read_file(const std::string &filename, bool debug); +template <typename T> +T read_file(const std::string &filename, bool debug); +// Declare the valid explicit specializations. +extern template std::string read_file<>(const std::string &, bool); +extern template std::vector<char> read_file<>(const std::string &, bool); class Output { public: @@ -48,4 +53,4 @@ class Output { }; } -#endif // wasm_support_file_h +#endif // wasm_support_file_h diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index 760f00c46..fdb157319 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -72,7 +72,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm2wasm(char *input) { module->memory.max = pre.memoryGrowth ? -1 : module->memory.initial; if (wasmJSDebug) std::cerr << "wasming...\n"; - asm2wasm = new Asm2WasmBuilder(*module, pre.memoryGrowth); + asm2wasm = new Asm2WasmBuilder(*module, pre.memoryGrowth, debug); asm2wasm->processAsm(asmjs); if (wasmJSDebug) std::cerr << "optimizing...\n"; |