diff options
-rw-r--r-- | src/asm2wasm-main.cpp | 20 | ||||
-rw-r--r-- | src/asm2wasm.h | 58 | ||||
-rw-r--r-- | src/wasm-js.cpp | 47 |
3 files changed, 63 insertions, 62 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp index 7c4d93052..1e9dc6680 100644 --- a/src/asm2wasm-main.cpp +++ b/src/asm2wasm-main.cpp @@ -27,24 +27,8 @@ int main(int argc, char **argv) { fclose(f); input[num] = 0; - // emcc --separate-asm modules look like - // - // Module["asm"] = (function(global, env, buffer) { - // .. - // }); - // - // we need to clean that up. - if (*input == 'M') { - while (*input != 'f') { - input++; - num--; - } - char *end = input + num - 1; - while (*end != '}') { - *end = 0; - end--; - } - } + Asm2WasmPreProcessor pre; + input = pre.process(input); if (debug) std::cerr << "parsing...\n"; cashew::Parser<Ref, DotZeroValueBuilder> builder; diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 976e0afe1..187bfeee6 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -82,6 +82,62 @@ struct AstStackHelper { std::vector<Ref> AstStackHelper::astStack; // +// Asm2WasmPreProcessor - does some initial parsing/processing +// of asm.js code. +// + +struct Asm2WasmPreProcessor { + bool memoryGrowth = false; + + char* process(char* input) { + // emcc --separate-asm modules can look like + // + // Module["asm"] = (function(global, env, buffer) { + // .. + // }); + // + // we need to clean that up. + if (*input == 'M') { + size_t num = strlen(input); + while (*input != 'f') { + input++; + num--; + } + char *end = input + num - 1; + while (*end != '}') { + *end = 0; + end--; + } + } + + // asm.js memory growth uses a quite elaborate pattern. Instead of parsing and + // matching it, we do a simpler detection on emscripten's asm.js output format + const char* START_FUNCS = "// EMSCRIPTEN_START_FUNCS"; + char *marker = strstr(input, START_FUNCS); + if (marker) { + *marker = 0; // look for memory growth code just up to here + char *growthSign = strstr(input, "return true;"); // this can only show up in growth code, as normal asm.js lacks "true" + if (growthSign) { + memoryGrowth = true; + // clean out this function, we don't need it + char *growthFuncStart = strstr(input, "function "); + assert(strstr(growthFuncStart + 1, "function ") == 0); // should be only this one function in this area, so no confusion for us + char *growthFuncEnd = strchr(growthSign, '}'); + assert(growthFuncEnd > growthFuncStart + 5); + growthFuncStart[0] = '/'; + growthFuncStart[1] = '*'; + growthFuncEnd--; + growthFuncEnd[0] = '*'; + growthFuncEnd[1] = '/'; + } + *marker = START_FUNCS[0]; + } + + return input; + } +}; + +// // Asm2WasmBuilder - converts an asm.js module into WebAssembly // @@ -213,7 +269,7 @@ private: } public: - Asm2WasmBuilder(Module& wasm) : wasm(wasm), nextGlobal(8), maxGlobal(1000) {} // XXX sync with emcc + Asm2WasmBuilder(Module& wasm) : wasm(wasm), nextGlobal(8), maxGlobal(1000) {} void processAsm(Ref ast); void optimize(); diff --git a/src/wasm-js.cpp b/src/wasm-js.cpp index bd0ee51a7..fbd3031ee 100644 --- a/src/wasm-js.cpp +++ b/src/wasm-js.cpp @@ -36,47 +36,8 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { wasmJSDebug = EM_ASM_INT_V({ return !!Module['outside']['WASM_JS_DEBUG'] }); // Set WASM_JS_DEBUG on the outside Module to get debugging #endif - // emcc --separate-asm modules look like - // - // Module["asm"] = (function(global, env, buffer) { - // .. - // }); - // - // we need to clean that up. - size_t num = strlen(input); - assert(*input == 'M'); - while (*input != 'f') { - input++; - num--; - } - char *end = input + num - 1; - while (*end != '}') { - *end = 0; - end--; - } - - // asm.js memory growth uses a quite elaborate pattern. Instead of parsing and - // matching it, we do a simpler detection on emscripten's asm.js output format - bool memoryGrowth = false; - const char* START_FUNCS = "// EMSCRIPTEN_START_FUNCS"; - char *marker = strstr(input, START_FUNCS); - assert(marker && "must have '// EMSCRIPTEN_START_FUNCS' marker (for now)"); - *marker = 0; // look for memory growth code just up to here - char *growthSign = strstr(input, "return true;"); // this can only show up in growth code, as normal asm.js lacks "true" - if (growthSign) { - memoryGrowth = true; - // clean out this function, we don't need it - char *growthFuncStart = strstr(input, "function "); - assert(strstr(growthFuncStart + 1, "function ") == 0); // should be only this one function in this area, so no confusion for us - char *growthFuncEnd = strchr(growthSign, '}'); - assert(growthFuncEnd > growthFuncStart + 5); - growthFuncStart[0] = '/'; - growthFuncStart[1] = '*'; - growthFuncEnd--; - growthFuncEnd[0] = '*'; - growthFuncEnd[1] = '/'; - } - *marker = START_FUNCS[0]; + Asm2WasmPreProcessor pre; + input = pre.process(input); // proceed to parse and wasmify if (wasmJSDebug) std::cerr << "parsing...\n"; @@ -88,13 +49,13 @@ extern "C" void EMSCRIPTEN_KEEPALIVE load_asm(char *input) { 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; + module->memory.max = pre.memoryGrowth ? -1 : module->memory.initial; if (wasmJSDebug) std::cerr << "wasming...\n"; asm2wasm = new Asm2WasmBuilder(*module); asm2wasm->processAsm(asmjs); - if (memoryGrowth) { + if (pre.memoryGrowth) { // create and export a function that just calls memory growth auto growWasmMemory = new Function(); growWasmMemory->name = GROW_WASM_MEMORY; |