summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-08-28 10:33:09 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-09-07 09:55:56 -0700
commit28767f631cfdae86ff16ca112bc5b1855b1368c4 (patch)
treee7b1e1605c62fc8d588dd2735ac8610eb1b793df /src
parent42ad2cdbe5baa32dd1b0aea143a4e45f81e8b9b5 (diff)
downloadbinaryen-28767f631cfdae86ff16ca112bc5b1855b1368c4.tar.gz
binaryen-28767f631cfdae86ff16ca112bc5b1855b1368c4.tar.bz2
binaryen-28767f631cfdae86ff16ca112bc5b1855b1368c4.zip
import table
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h8
-rw-r--r--src/js/wasm.js-post.js5
-rw-r--r--src/wasm-js.cpp51
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);