diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-08-28 10:33:09 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-09-07 09:55:56 -0700 |
commit | 28767f631cfdae86ff16ca112bc5b1855b1368c4 (patch) | |
tree | e7b1e1605c62fc8d588dd2735ac8610eb1b793df /src | |
parent | 42ad2cdbe5baa32dd1b0aea143a4e45f81e8b9b5 (diff) | |
download | binaryen-28767f631cfdae86ff16ca112bc5b1855b1368c4.tar.gz binaryen-28767f631cfdae86ff16ca112bc5b1855b1368c4.tar.bz2 binaryen-28767f631cfdae86ff16ca112bc5b1855b1368c4.zip |
import table
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 8 | ||||
-rw-r--r-- | src/js/wasm.js-post.js | 5 | ||||
-rw-r--r-- | src/wasm-js.cpp | 51 |
3 files changed, 47 insertions, 17 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 306a953a7..e27c5d9e2 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -832,6 +832,14 @@ void Asm2WasmBuilder::processAsm(Ref ast) { memoryImport->base = MEMORY; memoryImport->kind = Import::Memory; wasm.addImport(memoryImport.release()); + + // import table + auto tableImport = make_unique<Import>(); + tableImport->name = TABLE; + tableImport->module = ENV; + tableImport->base = TABLE; + tableImport->kind = Import::Table; + wasm.addImport(tableImport.release()); #endif #if 0 // enable asm2wasm i64 optimizations when browsers have consistent i64 support in wasm diff --git a/src/js/wasm.js-post.js b/src/js/wasm.js-post.js index dcffb1ee8..d691c22f2 100644 --- a/src/js/wasm.js-post.js +++ b/src/js/wasm.js-post.js @@ -274,10 +274,13 @@ function integrateWasmJS(Module) { global = fixImports(global); env = fixImports(env); - // import memory + // import memory and table if (!env['memory']) { env['memory'] = providedBuffer; } + if (!env['table']) { + env['table'] = new Array(1024); + } // try the methods. each should return the exports if it succeeded diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index 31448d2a0..7d71cec3c 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -145,14 +145,16 @@ extern "C" void EMSCRIPTEN_KEEPALIVE instantiate() { Module['asmExports'] = {}; }); for (auto& curr : module->exports) { - EM_ASM_({ - var name = Pointer_stringify($0); - Module['asmExports'][name] = function() { - Module['tempArguments'] = Array.prototype.slice.call(arguments); - Module['_call_from_js']($0); - return Module['tempReturn']; - }; - }, curr->name.str); + if (curr->kind == Export::Function) { + EM_ASM_({ + var name = Pointer_stringify($0); + Module['asmExports'][name] = function() { + Module['tempArguments'] = Array.prototype.slice.call(arguments); + Module['_call_from_js']($0); + return Module['tempReturn']; + }; + }, curr->name.str); + } } // verify imports are provided @@ -177,7 +179,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE instantiate() { assert(import->kind == Import::Memory); // memory is imported EM_ASM({ - Module['outside']['tempBuffer'] = Module['lookupImport']('env', 'memory'); + Module['asmExports']['memory'] = Module['lookupImport']('env', 'memory'); }); found = true; } @@ -185,25 +187,42 @@ extern "C" void EMSCRIPTEN_KEEPALIVE instantiate() { if (!found) { // no memory import; create a new buffer here, just like native wasm support would. EM_ASM_({ - Module['outside']['tempBuffer'] = Module['outside']['newBuffer'] = new ArrayBuffer($0); + Module['asmExports']['memory'] = Module['outside']['newBuffer'] = new ArrayBuffer($0); }, wasm.memory.initial * Memory::kPageSize); } } for (auto segment : wasm.memory.segments) { EM_ASM_({ var source = Module['HEAP8'].subarray($1, $1 + $2); - var target = new Int8Array(Module['outside']['tempBuffer']); + var target = new Int8Array(Module['asmExports']['memory']); target.set(source, $0); }, ConstantExpressionRunner(instance.globals).visit(segment.offset).value.geti32(), &segment.data[0], segment.data.size()); } + // look for imported table + { + bool found = false; + for (auto& import : wasm.imports) { + if (import->module == ENV && import->base == TABLE) { + assert(import->kind == Import::Table); + // table is imported + EM_ASM({ + Module['outside']['wasmTable'] = Module['lookupImport']('env', 'table'); + }); + found = true; + } + } + if (!found) { + // no table import; create a new one here, just like native wasm support would. + EM_ASM_({ + Module['outside']['wasmTable'] = new Array($0); + }, wasm.table.initial); + } + } EM_ASM({ - Module['outside']['tempBuffer'] = null; + Module['asmExports']['table'] = Module['outside']['wasmTable']; }); - // Table support is in a JS array. If the entry is a number, it's a function pointer. If not, it's a JS method to be called directly + // Emulated table support is in a JS array. If the entry is a number, it's a function pointer. If not, it's a JS method to be called directly // TODO: make them all JS methods, wrapping a dynCall where necessary? - EM_ASM_({ - Module['outside']['wasmTable'] = new Array($0); - }, wasm.table.initial); for (auto segment : wasm.table.segments) { Address offset = ConstantExpressionRunner(instance.globals).visit(segment.offset).value.geti32(); assert(offset + segment.data.size() <= wasm.table.initial); |