diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-11-01 20:54:46 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-11-01 20:55:30 -0800 |
commit | d8c2d69dd253bd6f67e1f3c374be2c20d43dfc03 (patch) | |
tree | 39cfe002d1ff5d58f462a8472ac79c28ead43a2e /src | |
parent | bb6f33c9f19581e2ea60b46653bb1a10ced4a2eb (diff) | |
download | binaryen-d8c2d69dd253bd6f67e1f3c374be2c20d43dfc03.tar.gz binaryen-d8c2d69dd253bd6f67e1f3c374be2c20d43dfc03.tar.bz2 binaryen-d8c2d69dd253bd6f67e1f3c374be2c20d43dfc03.zip |
save module and base of mapped imported globals, and fix writing of mapped imported globals
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 12 | ||||
-rw-r--r-- | src/js/post.js | 4 | ||||
-rw-r--r-- | src/wasm-js.cpp | 26 |
3 files changed, 31 insertions, 11 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 2bb76610b..e5ba3a499 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -79,14 +79,18 @@ class Asm2WasmBuilder { unsigned address; WasmType type; bool import; // if true, this is an import - we should read the value, not just set a zero + IString module, base; MappedGlobal() : address(0), type(none), import(false) {} - MappedGlobal(unsigned address, WasmType type, bool import) : address(address), type(type), import(import) {} + MappedGlobal(unsigned address, WasmType type, bool import, IString module, IString base) : address(address), type(type), import(import), module(module), base(base) {} }; + +public: std::map<IString, MappedGlobal> mappedGlobals; - void allocateGlobal(IString name, WasmType type, bool import) { +private: + void allocateGlobal(IString name, WasmType type, bool import, IString module = IString(), IString base = IString()) { assert(mappedGlobals.find(name) == mappedGlobals.end()); - mappedGlobals.emplace(name, MappedGlobal(nextGlobal, type, import)); + mappedGlobals.emplace(name, MappedGlobal(nextGlobal, type, import, module, base)); nextGlobal += 8; assert(nextGlobal < maxGlobal); } @@ -369,7 +373,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { } if (type != WasmType::none) { // wasm has no imported constants, so allocate a global, and we need to write the value into that - allocateGlobal(name, type, true); + allocateGlobal(name, type, true, import.module, import.base); } else { wasm.imports.emplace(name, import); } diff --git a/src/js/post.js b/src/js/post.js index c9e29f6e8..2ecec51aa 100644 --- a/src/js/post.js +++ b/src/js/post.js @@ -41,8 +41,8 @@ lookup = (lookup || {})[parts[1]]; } lookup = (lookup || {})[base]; - if (!lookup) { - abort('bad CallImport to (' + mod + ').' + base); + if (lookup === undefined) { + abort('bad lookupImport to (' + mod + ').' + base); } return lookup; } diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index bedc65d48..14dfa563c 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -15,7 +15,10 @@ using namespace cashew; using namespace wasm; +// global singletons +Asm2WasmBuilder* asm2wasm = nullptr; ModuleInstance* instance = nullptr; +Module* module = nullptr; // receives asm.js code, parses into wasm and returns an instance handle. // this creates a module, an external interface, a builder, and a module instance, @@ -49,22 +52,22 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { cashew::Parser<Ref, DotZeroValueBuilder> builder; Ref asmjs = builder.parseToplevel(input); - Module* wasm = new Module(); + module = new Module(); if (debug) std::cerr << "wasming...\n"; - Asm2WasmBuilder* asm2wasm = new Asm2WasmBuilder(*wasm); + asm2wasm = new Asm2WasmBuilder(*module); asm2wasm->processAsm(asmjs); if (debug) std::cerr << "optimizing...\n"; asm2wasm->optimize(); - //std::cerr << *wasm << '\n'; + //std::cerr << *module << '\n'; if (debug) std::cerr << "generating exports...\n"; EM_ASM({ Module['asmExports'] = {}; }); - for (auto& curr : wasm->exports) { + for (auto& curr : module->exports) { EM_ASM_({ var name = Pointer_stringify($0); Module['asmExports'][name] = function() { @@ -159,11 +162,24 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { } }; - instance = new ModuleInstance(*wasm, new JSExternalInterface()); + instance = new ModuleInstance(*module, new JSExternalInterface()); } // Ready the provided imported globals, copying them to their mapped locations. extern "C" void EMSCRIPTEN_KEEPALIVE load_mapped_globals() { + for (auto& pair : asm2wasm->mappedGlobals) { + auto name = pair.first; + auto& global = pair.second; + if (!global.import) continue; // non-imports are initialized to zero in the typed array anyhow, so nothing to do here + double value = EM_ASM_DOUBLE({ return Module['lookupImport'](Pointer_stringify($0), Pointer_stringify($1)) }, global.module.str, global.base.str); + unsigned address = global.address; + switch (global.type) { + case i32: EM_ASM_({ Module['info'].parent['HEAP32'][$0] = $1 }, address, value); break; + case f32: EM_ASM_({ Module['info'].parent['HEAPF32'][$0] = $1 }, address, value); break; + case f64: EM_ASM_({ Module['info'].parent['HEAPF64'][$0] = $1 }, address, value); break; + default: abort(); + } + } } // Does a call from js into an export of the module. |