diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/js/post.js | 8 | ||||
-rw-r--r-- | src/wasm-js.cpp | 24 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/js/post.js b/src/js/post.js index c2552c5a8..3c7bd05a4 100644 --- a/src/js/post.js +++ b/src/js/post.js @@ -20,6 +20,12 @@ var theBuffer = Module['buffer'] = new ArrayBuffer(Module['providedTotalMemory'] || 64*1024*1024); wasmJS['providedTotalMemory'] = theBuffer.byteLength; + Module['reallocBuffer'] = function(size) { + var old = Module['buffer'] + Module['__growWasmMemory'](size); // tiny wasm method that just does grow_memory + return Module['buffer'] !== old ? Module['buffer'] : null; // if it was reallocated, it changed + }; + var temp = wasmJS._malloc(code.length + 1); wasmJS.writeAsciiToMemory(code, temp); wasmJS._load_asm(temp); @@ -61,7 +67,7 @@ // The asm.js function, called to "link" the asm.js module. Module['asm'] = function(global, env, buffer) { - assert(buffer === theBuffer); // we should not even need to pass it as a 3rd arg for wasm, but that's the asm.js way. + assert(buffer === Module['buffer']); // we should not even need to pass it as a 3rd arg for wasm, but that's the asm.js way. // write the provided data to a location the wasm instance can get at it. info.global = global; info.env = env; diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index 2f9ac639f..3de6319cb 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -14,6 +14,9 @@ using namespace cashew; using namespace wasm; +IString GROW_WASM_MEMORY("_growWasmMemory"), + NEW_SIZE("newSize"); + // global singletons Asm2WasmBuilder* asm2wasm = nullptr; ModuleInstance* instance = nullptr; @@ -82,14 +85,32 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { Ref asmjs = builder.parseToplevel(input); module = new Module(); - module->memory.initial = module->memory.max = EM_ASM_INT_V({ + module->memory.initial = EM_ASM_INT_V({ return Module['providedTotalMemory']; // we receive the size of memory from emscripten }); + module->memory.max = memoryGrowth ? -1 : module->memory.initial; if (wasmJSDebug) std::cerr << "wasming...\n"; asm2wasm = new Asm2WasmBuilder(*module); asm2wasm->processAsm(asmjs); + if (memoryGrowth) { + // create and export a function that just calls memory growth + auto growWasmMemory = new Function(); + growWasmMemory->name = GROW_WASM_MEMORY; + growWasmMemory->params.emplace_back(NEW_SIZE, i32); // the new size + auto get = new GetLocal(); + get->name = NEW_SIZE; + auto grow = new Host(); + grow->op = GrowMemory; + grow->operands.push_back(get); + growWasmMemory->body = grow; + module->addFunction(growWasmMemory); + auto export_ = new Export(); + export_->name = export_->value = GROW_WASM_MEMORY; + module->addExport(export_); + } + if (wasmJSDebug) std::cerr << "optimizing...\n"; asm2wasm->optimize(); @@ -207,6 +228,7 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { } void growMemory(size_t oldSize, size_t newSize) override { + // never called from compiled asm.js directly, we have special support for it as the request arrives from outside js abort(); } |