diff options
-rw-r--r-- | src/wasm-binary.h | 13 | ||||
-rw-r--r-- | src/wasm.h | 2 | ||||
-rw-r--r-- | src/wasm2asm-main.cpp | 67 | ||||
-rw-r--r-- | src/wasm2asm.h | 9 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.wast.fromBinary | 16 | ||||
-rw-r--r-- | test/emcc_hello_world.wast.fromBinary | 14 | ||||
-rw-r--r-- | test/hello_world.wast.fromBinary | 2 | ||||
-rw-r--r-- | test/min.2asm.js | 11 | ||||
-rw-r--r-- | test/min.wast | 5 | ||||
-rw-r--r-- | test/min.wast.fromBinary | 6 |
10 files changed, 87 insertions, 58 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 76e5fc348..235a0e772 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -436,6 +436,7 @@ public: mappedLocals[name] = index + currLocalsByType[f64] - 1; continue; } + abort(); } } @@ -464,12 +465,14 @@ public: (BinaryConsts::Export * (wasm->exportsMap.count(name) > 0))); o << getFunctionTypeIndex(type); emitString(name.str); - if (function && function->locals.size() > 0) { + if (function) { mapLocals(function); - o << uint16_t(numLocalsByType[i32]) - << uint16_t(numLocalsByType[i64]) - << uint16_t(numLocalsByType[f32]) - << uint16_t(numLocalsByType[f64]); + if (function->locals.size() > 0) { + o << uint16_t(numLocalsByType[i32]) + << uint16_t(numLocalsByType[i64]) + << uint16_t(numLocalsByType[f32]) + << uint16_t(numLocalsByType[f64]); + } } if (function) { size_t sizePos = o.size(); diff --git a/src/wasm.h b/src/wasm.h index b36d4f3ed..5a8d57fd1 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -69,7 +69,7 @@ namespace wasm { struct Name : public cashew::IString { Name() : cashew::IString() {} - Name(const char *str) : cashew::IString(str) {} + Name(const char *str) : cashew::IString(str, false) {} Name(cashew::IString str) : cashew::IString(str) {} Name(const std::string &str) : cashew::IString(str.c_str(), false) {} diff --git a/src/wasm2asm-main.cpp b/src/wasm2asm-main.cpp index 12a802107..c75272b8d 100644 --- a/src/wasm2asm-main.cpp +++ b/src/wasm2asm-main.cpp @@ -18,58 +18,57 @@ // wasm2asm console tool // -#include "wasm2asm.h" + +#include "support/colors.h" +#include "support/command-line.h" +#include "support/file.h" #include "wasm-s-parser.h" +#include "wasm2asm.h" using namespace cashew; using namespace wasm; -namespace wasm { -int debug = 0; -} - -int main(int argc, char **argv) { - debug = getenv("WASM2ASM_DEBUG") ? getenv("WASM2ASM_DEBUG")[0] - '0' : 0; - - char *infile = argv[1]; +int main(int argc, const char *argv[]) { + Options options("wasm2asm", "Transform .wast files to asm.js"); + 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_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; + auto input( + read_file<std::vector<char>>(options.extra["infile"], options.debug)); - if (debug) std::cerr << "s-parsing...\n"; - SExpressionParser parser(input); - Element& root = *parser.root; + if (options.debug) std::cerr << "s-parsing..." << std::endl; + SExpressionParser parser(input.data()); + Element &root = *parser.root; - if (debug) std::cerr << "w-parsing...\n"; + if (options.debug) std::cerr << "w-parsing..." << std::endl; AllocatingModule wasm; SExpressionWasmBuilder builder(wasm, *root[0], [&]() { abort(); }); - if (debug) std::cerr << "asming...\n"; - Wasm2AsmBuilder wasm2asm; + if (options.debug) std::cerr << "asming..." << std::endl; + Wasm2AsmBuilder wasm2asm(options.debug); Ref asmjs = wasm2asm.processWasm(&wasm); - if (debug) { - std::cerr << "a-printing...\n"; + if (options.debug) { + std::cerr << "a-printing..." << std::endl; asmjs->stringify(std::cout, true); std::cout << '\n'; } - if (debug) std::cerr << "j-printing...\n"; + if (options.debug) std::cerr << "j-printing..." << std::endl; JSPrinter jser(true, true, asmjs); jser.printAst(); - std::cout << jser.buffer << "\n"; + Output output(options.extra["output"], options.debug); + output << jser.buffer << std::endl; - if (debug) std::cerr << "done.\n"; + if (options.debug) std::cerr << "done." << std::endl; } diff --git a/src/wasm2asm.h b/src/wasm2asm.h index ad73159e6..69abf9c3f 100644 --- a/src/wasm2asm.h +++ b/src/wasm2asm.h @@ -32,8 +32,6 @@ namespace wasm { -extern int debug; - using namespace cashew; IString ASM_FUNC("asmFunc"), @@ -106,6 +104,8 @@ void flattenAppend(Ref ast, Ref extra) { class Wasm2AsmBuilder { public: + Wasm2AsmBuilder(bool debug) : debug(debug), tableSize(-1) {} + Ref processWasm(Module* wasm); Ref processFunction(Function* func); @@ -171,6 +171,7 @@ public: } private: + bool debug; // How many temp vars we need std::vector<size_t> temps; // type => num temps // Which are currently free to use @@ -186,6 +187,10 @@ private: void addImport(Ref ast, Import *import); void addTables(Ref ast, Module *wasm); void addExports(Ref ast, Module *wasm); + + Wasm2AsmBuilder() = delete; + Wasm2AsmBuilder(const Wasm2AsmBuilder &) = delete; + Wasm2AsmBuilder &operator=(const Wasm2AsmBuilder &) = delete; }; Ref Wasm2AsmBuilder::processWasm(Module* wasm) { diff --git a/test/emcc_O2_hello_world.wast.fromBinary b/test/emcc_O2_hello_world.wast.fromBinary index 2a52ddeca..f940c50e8 100644 --- a/test/emcc_O2_hello_world.wast.fromBinary +++ b/test/emcc_O2_hello_world.wast.fromBinary @@ -12488,9 +12488,9 @@ ) (i32.const 2) ) - (get_local $var$0) - (get_local $var$0) - (get_local $var$0) + (get_local $var$1) + (get_local $var$2) + (get_local $var$3) ) ) (func $stackAlloc (param $var$0 i32) @@ -12565,7 +12565,7 @@ ) (i32.store align=4 (i32.const 48) - (get_local $var$0) + (get_local $var$1) ) ) ) @@ -12578,7 +12578,7 @@ (get_local $var$0) ) (i32.const 1) - (get_local $var$0) + (get_local $var$1) ) (i32.const 255) ) @@ -12592,7 +12592,7 @@ ) (i32.const 0) ) - (get_local $var$0) + (get_local $var$1) ) ) (func $_cleanup_418 (param $var$0 i32) @@ -12622,7 +12622,7 @@ ) (i32.store align=4 (i32.const 16) - (get_local $var$0) + (get_local $var$1) ) ) ) @@ -12635,7 +12635,7 @@ ) (i32.const 10) ) - (get_local $var$0) + (get_local $var$1) ) ) (func $b1 (param $var$0 i32) (param $var$1 i32) (param $var$2 i32) diff --git a/test/emcc_hello_world.wast.fromBinary b/test/emcc_hello_world.wast.fromBinary index 0fe343afe..3fc91d625 100644 --- a/test/emcc_hello_world.wast.fromBinary +++ b/test/emcc_hello_world.wast.fromBinary @@ -117,7 +117,7 @@ ) (i32.store align=4 (i32.const 16) - (get_local $var$0) + (get_local $var$1) ) ) ) @@ -136,7 +136,7 @@ ) (i32.store align=4 (i32.const 56) - (get_local $var$0) + (get_local $var$1) ) ) ) @@ -34059,7 +34059,7 @@ ) (i32.const 0) ) - (get_local $var$0) + (get_local $var$1) ) ) (func $dynCall_iiii (param $var$0 i32) (param $var$1 i32) (param $var$2 i32) (param $var$3 i32) @@ -34071,9 +34071,9 @@ ) (i32.const 2) ) - (get_local $var$0) - (get_local $var$0) - (get_local $var$0) + (get_local $var$1) + (get_local $var$2) + (get_local $var$3) ) ) (func $dynCall_vi (param $var$0 i32) (param $var$1 i32) @@ -34085,7 +34085,7 @@ ) (i32.const 10) ) - (get_local $var$0) + (get_local $var$1) ) ) (func $b0 (param $var$0 i32) diff --git a/test/hello_world.wast.fromBinary b/test/hello_world.wast.fromBinary index 4027521a1..98e66d0da 100644 --- a/test/hello_world.wast.fromBinary +++ b/test/hello_world.wast.fromBinary @@ -5,7 +5,7 @@ (func $add (param $var$0 i32) (param $var$1 i32) (i32.add (get_local $var$0) - (get_local $var$0) + (get_local $var$1) ) ) ) diff --git a/test/min.2asm.js b/test/min.2asm.js index 4bf4cb610..ea1d2d83f 100644 --- a/test/min.2asm.js +++ b/test/min.2asm.js @@ -49,6 +49,17 @@ function asmFunc(global, env, buffer) { return wasm2asm_i32$0 | 0; } + function f1(i1, i2, i3) { + i1 = i1 | 0; + i2 = i2 | 0; + i3 = i3 | 0; + var wasm2asm_i32$0 = 0; + topmost : { + wasm2asm_i32$0 = i3; + } + return wasm2asm_i32$0 | 0; + } + return { floats: floats }; diff --git a/test/min.wast b/test/min.wast index f765b64e8..86caf3cd2 100644 --- a/test/min.wast +++ b/test/min.wast @@ -46,4 +46,9 @@ (i32.const 0) ) ) + (func $f1 (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) + (block $topmost + (get_local $i3) + ) + ) ) diff --git a/test/min.wast.fromBinary b/test/min.wast.fromBinary index 6945bcd54..d8023d88c 100644 --- a/test/min.wast.fromBinary +++ b/test/min.wast.fromBinary @@ -3,6 +3,7 @@ (type $0 (func (param f32) (result f32))) (type $1 (func (param i32 i32))) (type $2 (func (param i32) (result i32))) + (type $3 (func (param i32 i32 i32) (result i32))) (export "floats" $floats) (func $floats (param $var$0 f32) (local $var$1 f32) @@ -49,5 +50,10 @@ (i32.const 0) ) ) + (func $f1 (param $var$0 i32) (param $var$1 i32) (param $var$2 i32) + (block $label$0 + (get_local $var$2) + ) + ) ) |