diff options
-rw-r--r-- | src/asm_v_wasm.h | 10 | ||||
-rw-r--r-- | src/wasm2asm.h | 35 | ||||
-rw-r--r-- | test/emcc_O2_hello_world.2asm.js | 3 | ||||
-rw-r--r-- | test/unit.2asm.js | 2 |
4 files changed, 50 insertions, 0 deletions
diff --git a/src/asm_v_wasm.h b/src/asm_v_wasm.h index 323d255ee..829d79930 100644 --- a/src/asm_v_wasm.h +++ b/src/asm_v_wasm.h @@ -47,6 +47,16 @@ std::string getSig(FunctionType *type) { return ret; } +std::string getSig(Function *func) { + // generate signature + std::string ret; + ret += getSig(func->result); + for (auto param : func->params) { + ret += getSig(param.type); + } + return ret; +} + } // namespace wasm #endif // _asm_v_wasm_h_ diff --git a/src/wasm2asm.h b/src/wasm2asm.h index 836fc450c..62baf1b54 100644 --- a/src/wasm2asm.h +++ b/src/wasm2asm.h @@ -164,6 +164,7 @@ private: void addBasics(Ref ast); void addImport(Ref ast, Import *import); + void addTables(Ref ast, Module *wasm); }; Ref Wasm2AsmBuilder::processWasm(Module* wasm) { @@ -192,6 +193,7 @@ Ref Wasm2AsmBuilder::processWasm(Module* wasm) { for (auto func : wasm->functions) { asmFunc[3]->push_back(processFunction(func)); } + addTables(asmFunc[3], wasm); // table XXX // memory XXX return ret; @@ -253,6 +255,39 @@ void Wasm2AsmBuilder::addImport(Ref ast, Import *import) { ); } +void Wasm2AsmBuilder::addTables(Ref ast, Module *wasm) { + std::map<std::string, std::vector<IString>> tables; // asm.js tables, sig => contents of table + for (size_t i = 0; i < wasm->table.names.size(); i++) { + Name name = wasm->table.names[i]; + auto func = wasm->functionsMap[name]; + std::string sig = getSig(func); + auto& table = tables[sig]; + if (table.size() == 0) { + // fill it with the first of its type seen. we have to fill with something; and for asm2wasm output, the first is the null anyhow + table.resize(tableSize); + for (int j = 0; j < tableSize; j++) { + table[j] = fromName(name); + } + } else { + table[i] = fromName(name); + } + } + for (auto& pair : tables) { + auto& sig = pair.first; + auto& table = pair.second; + std::string stable = std::string("FUNCTION_TABLE_") + sig; + IString asmName = IString(stable.c_str(), false); + // add to asm module + Ref theVar = ValueBuilder::makeVar(); + ast->push_back(theVar); + Ref theArray = ValueBuilder::makeArray(); + ValueBuilder::appendToVar(theVar, asmName, theArray); + for (auto& name : table) { + ValueBuilder::appendToArray(theArray, ValueBuilder::makeName(name)); + } + } +} + Ref Wasm2AsmBuilder::processFunction(Function* func) { Ref ret = ValueBuilder::makeFunction(fromName(func->name)); frees.clear(); diff --git a/test/emcc_O2_hello_world.2asm.js b/test/emcc_O2_hello_world.2asm.js index 37ec11b41..09ee16196 100644 --- a/test/emcc_O2_hello_world.2asm.js +++ b/test/emcc_O2_hello_world.2asm.js @@ -2527,5 +2527,8 @@ function asmFunc(global, env, buffer) { abort(2 | 0) } + var FUNCTION_TABLE_ii = [b0, ___stdio_close, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0, b0]; + var FUNCTION_TABLE_iiii = [b1, b1, b1, b1, ___stdout_write, ___stdio_seek, b1, ___stdio_write, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1, b1]; + var FUNCTION_TABLE_vi = [b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, _cleanup_418, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2, b2]; } diff --git a/test/unit.2asm.js b/test/unit.2asm.js index a8320d77c..b705e1e64 100644 --- a/test/unit.2asm.js +++ b/test/unit.2asm.js @@ -212,5 +212,7 @@ function asmFunc(global, env, buffer) { } + var FUNCTION_TABLE_d = [importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles, importedDoubles]; + var FUNCTION_TABLE_v = [z, big_negative, z, z, w, w, z, w, z, neg, z, z, z, z, z, z]; } |