summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/test/wasm2js.py4
-rw-r--r--src/tools/wasm2js.cpp5
-rw-r--r--src/wasm2js.h65
-rw-r--r--test/wasm2js/emscripten.2asm.js78
-rw-r--r--test/wasm2js/emscripten.wast32
5 files changed, 180 insertions, 4 deletions
diff --git a/scripts/test/wasm2js.py b/scripts/test/wasm2js.py
index afa399da2..2892da278 100755
--- a/scripts/test/wasm2js.py
+++ b/scripts/test/wasm2js.py
@@ -52,6 +52,8 @@ def test_wasm2js_output():
print '..', wasm
cmd = WASM2JS + [os.path.join(options.binaryen_test, wasm)]
+ if 'emscripten' in wasm:
+ cmd += ['--emscripten']
out = run_command(cmd)
fail_if_not_identical_to_file(out, expected_file)
@@ -129,6 +131,8 @@ def update_wasm2js_tests():
print '..', wasm
cmd = WASM2JS + [os.path.join('test', wasm)]
+ if 'emscripten' in wasm:
+ cmd += ['--emscripten']
out = run_command(cmd)
with open(expected_file, 'w') as o:
o.write(out)
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp
index 76a724f86..8704dbf49 100644
--- a/src/tools/wasm2js.cpp
+++ b/src/tools/wasm2js.cpp
@@ -370,6 +370,11 @@ int main(int argc, const char *argv[]) {
[&](Options* o, const std::string& argument) {
flags.pedantic = true;
})
+ .add("--emscripten", "", "Emulate the glue in emscripten-compatible form (and not ES6 module form)",
+ Options::Arguments::Zero,
+ [&](Options* o, const std::string& argument) {
+ flags.emscripten = true;
+ })
.add_positional("INFILE", Options::Arguments::One,
[](Options *o, const std::string& argument) {
o->extra["infile"] = argument;
diff --git a/src/wasm2js.h b/src/wasm2js.h
index c6970e3e8..e93b3f273 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -142,6 +142,7 @@ public:
bool debug = false;
bool pedantic = false;
bool allowAsserts = false;
+ bool emscripten = false;
};
Wasm2JSBuilder(Flags f) : flags(f) {}
@@ -358,6 +359,9 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
generateFetchHighBits = true;
}
});
+ if (flags.emscripten) {
+ asmFunc[3]->push_back(ValueBuilder::makeName("// EMSCRIPTEN_START_FUNCS"));
+ }
// functions
ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
asmFunc[3]->push_back(processFunction(wasm, func));
@@ -379,6 +383,9 @@ Ref Wasm2JSBuilder::processWasm(Module* wasm, Name funcName) {
e->kind = ExternalKind::Function;
wasm->addExport(e);
}
+ if (flags.emscripten) {
+ asmFunc[3]->push_back(ValueBuilder::makeName("// EMSCRIPTEN_END_FUNCS"));
+ }
addTables(asmFunc[3], wasm);
// memory XXX
@@ -2002,9 +2009,26 @@ private:
Output& out;
Wasm2JSBuilder::Flags flags;
Name moduleName;
+
+ void emitPreEmscripten();
+ void emitPreES6();
+ void emitPostEmscripten();
+ void emitPostES6();
};
void Wasm2JSGlue::emitPre() {
+ if (flags.emscripten) {
+ emitPreEmscripten();
+ } else {
+ emitPreES6();
+ }
+}
+
+void Wasm2JSGlue::emitPreEmscripten() {
+ out << "function instantiate(asmLibraryArg, wasmMemory, wasmTable) {\n\n";
+}
+
+void Wasm2JSGlue::emitPreES6() {
std::unordered_map<Name, Name> baseModuleMap;
auto noteImport = [&](Name module, Name base) {
@@ -2018,10 +2042,10 @@ void Wasm2JSGlue::emitPre() {
baseModuleMap[base] = module;
out << "import { "
- << base.str
- << " } from '"
- << module.str
- << "';\n";
+ << base.str
+ << " } from '"
+ << module.str
+ << "';\n";
};
ImportInfo imports(wasm);
@@ -2038,6 +2062,39 @@ void Wasm2JSGlue::emitPre() {
}
void Wasm2JSGlue::emitPost() {
+ if (flags.emscripten) {
+ emitPostEmscripten();
+ } else {
+ emitPostES6();
+ }
+}
+
+void Wasm2JSGlue::emitPostEmscripten() {
+ out << "return asmFunc(\n"
+ << " {\n"
+ << " 'env': asmLibraryArg,\n"
+ << " 'global': {\n"
+ << " 'Int8Array': Int8Array,\n"
+ << " 'Int16Array': Int16Array,\n"
+ << " 'Int32Array': Int32Array,\n"
+ << " 'Uint8Array': Uint8Array,\n"
+ << " 'Uint16Array': Uint16Array,\n"
+ << " 'Uint32Array': Uint32Array,\n"
+ << " 'Float32Array': Float32Array,\n"
+ << " 'Float64Array': Float64Array,\n"
+ << " 'NaN': NaN,\n"
+ << " 'Infinity': Infinity,\n"
+ << " 'Math': Math\n"
+ << " }\n"
+ << " },\n"
+ << " wasmMemory.buffer\n"
+ << ")"
+ << "\n"
+ << "\n"
+ << "}";
+}
+
+void Wasm2JSGlue::emitPostES6() {
// Create an initial `ArrayBuffer` and populate it with static data.
// Currently we use base64 encoding to encode static data and we decode it at
// instantiation time.
diff --git a/test/wasm2js/emscripten.2asm.js b/test/wasm2js/emscripten.2asm.js
new file mode 100644
index 000000000..d1fe55ffd
--- /dev/null
+++ b/test/wasm2js/emscripten.2asm.js
@@ -0,0 +1,78 @@
+function instantiate(asmLibraryArg, wasmMemory, wasmTable) {
+
+function asmFunc(global, env, buffer) {
+ "use asm";
+ var HEAP8 = new global.Int8Array(buffer);
+ var HEAP16 = new global.Int16Array(buffer);
+ var HEAP32 = new global.Int32Array(buffer);
+ var HEAPU8 = new global.Uint8Array(buffer);
+ var HEAPU16 = new global.Uint16Array(buffer);
+ var HEAPU32 = new global.Uint32Array(buffer);
+ var HEAPF32 = new global.Float32Array(buffer);
+ var HEAPF64 = new global.Float64Array(buffer);
+ var Math_imul = global.Math.imul;
+ var Math_fround = global.Math.fround;
+ var Math_abs = global.Math.abs;
+ var Math_clz32 = global.Math.clz32;
+ var Math_min = global.Math.min;
+ var Math_max = global.Math.max;
+ var Math_floor = global.Math.floor;
+ var Math_ceil = global.Math.ceil;
+ var Math_sqrt = global.Math.sqrt;
+ var abort = env.abort;
+ var nan = global.NaN;
+ var infinity = global.Infinity;
+ var syscall$6 = env.__syscall6;
+ var syscall$54 = env.__syscall54;
+ var global$0 = 5243904;
+ var i64toi32_i32$HIGH_BITS = 0;
+ // EMSCRIPTEN_START_FUNCS;
+ function main() {
+ var wasm2js_i32$0 = 0;
+ syscall$6(1 | 0, 2 | 0) | 0;
+ syscall$54(3 | 0, 4 | 0) | 0;
+ wasm2js_i32$0 = HEAP32[(0 + 1030 | 0) >> 2] | 0;
+ FUNCTION_TABLE_v[wasm2js_i32$0 & 3]();
+ }
+
+ function other() {
+ main();
+ }
+
+ function foo() {
+ abort();
+ }
+
+ function bar() {
+
+ }
+
+ // EMSCRIPTEN_END_FUNCS;
+ var FUNCTION_TABLE_v = [foo, foo, bar, foo];
+ return {
+ main: main,
+ other: other
+ };
+}
+
+return asmFunc(
+ {
+ 'env': asmLibraryArg,
+ 'global': {
+ 'Int8Array': Int8Array,
+ 'Int16Array': Int16Array,
+ 'Int32Array': Int32Array,
+ 'Uint8Array': Uint8Array,
+ 'Uint16Array': Uint16Array,
+ 'Uint32Array': Uint32Array,
+ 'Float32Array': Float32Array,
+ 'Float64Array': Float64Array,
+ 'NaN': NaN,
+ 'Infinity': Infinity,
+ 'Math': Math
+ }
+ },
+ wasmMemory.buffer
+)
+
+} \ No newline at end of file
diff --git a/test/wasm2js/emscripten.wast b/test/wasm2js/emscripten.wast
new file mode 100644
index 000000000..82bf73548
--- /dev/null
+++ b/test/wasm2js/emscripten.wast
@@ -0,0 +1,32 @@
+(module
+ (type $0 (func))
+ (import "env" "memory" (memory $8 256 256))
+ (data (i32.const 1024) "hello, world!\n\00\00\9c\0c\00\00-+ 0X0x\00(null)\00\00\00\00\00\00\00\00\00\00\00\00\11\00\n\00\11\11\11\00\00\00\00\05\00\00\00\00\00\00\t\00\00\00\00\0b\00\00\00\00\00\00\00\00\11\00\0f\n\11\11\11\03\n\07\00\01\13\t\0b\0b\00\00\t\06\0b\00\00\0b\00\06\11\00\00\00\11\11\11\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\00\00\11\00\n\n\11\11\11\00\n\00\00\02\00\t\0b\00\00\00\t\00\0b\00\00\0b\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\0c\00\00\00\00\t\0c\00\00\00\00\00\0c\00\00\0c\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0e\00\00\00\00\00\00\00\00\00\00\00\0d\00\00\00\04\0d\00\00\00\00\t\0e\00\00\00\00\00\0e\00\00\0e\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\10\00\00\00\00\00\00\00\00\00\00\00\0f\00\00\00\00\0f\00\00\00\00\t\10\00\00\00\00\00\10\00\00\10\00\00\12\00\00\00\12\12\12\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\12\00\00\00\12\12\12\00\00\00\00\00\00\t\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0b\00\00\00\00\00\00\00\00\00\00\00\n\00\00\00\00\n\00\00\00\00\t\0b\00\00\00\00\00\0b\00\00\0b\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\0c\00\00\00\00\t\0c\00\00\00\00\00\0c\00\00\0c\00\000123456789ABCDEF-0X+0X 0X-0x+0x 0x\00inf\00INF\00nan\00NAN\00.\00")
+ (data (i32.const 1600) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
+ (import "env" "table" (table $timport$9 7 funcref))
+ (elem (i32.const 1) $foo $bar)
+ (import "env" "__syscall6" (func $syscall$6 (param i32 i32) (result i32)))
+ (import "env" "__syscall54" (func $syscall$54 (param i32 i32) (result i32)))
+ (global $global$0 (mut i32) (i32.const 5243904))
+ (export "main" (func $main))
+ (export "other" (func $other))
+ (func $main
+ (drop (call $syscall$6 (i32.const 1) (i32.const 2)))
+ (drop (call $syscall$54 (i32.const 3) (i32.const 4)))
+ (call_indirect (type $0)
+ (i32.load offset=1030
+ (i32.const 0)
+ )
+ )
+ )
+ (func $other
+ (call $main)
+ )
+ (func $foo
+ (unreachable)
+ )
+ (func $bar
+ (nop)
+ )
+)
+