summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asm2wasm.h12
-rw-r--r--src/js/post.js4
-rw-r--r--src/wasm-js.cpp26
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.