summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-binary.h13
-rw-r--r--src/wasm.h2
-rw-r--r--src/wasm2asm-main.cpp67
-rw-r--r--src/wasm2asm.h9
-rw-r--r--test/emcc_O2_hello_world.wast.fromBinary16
-rw-r--r--test/emcc_hello_world.wast.fromBinary14
-rw-r--r--test/hello_world.wast.fromBinary2
-rw-r--r--test/min.2asm.js11
-rw-r--r--test/min.wast5
-rw-r--r--test/min.wast.fromBinary6
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)
+ )
+ )
)