summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-12-07 15:00:53 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-12-07 15:00:53 -0800
commit4b23bd513d926fb03e549bc1cf704a6016a91a70 (patch)
tree9e7850a54c41434de195a9dc568844aee0da1e89
parent75e8b709fe900efcfb53813f884a1cde6e81907b (diff)
downloadbinaryen-4b23bd513d926fb03e549bc1cf704a6016a91a70.tar.gz
binaryen-4b23bd513d926fb03e549bc1cf704a6016a91a70.tar.bz2
binaryen-4b23bd513d926fb03e549bc1cf704a6016a91a70.zip
emit asm function tables in wasm2asm
-rw-r--r--src/asm_v_wasm.h10
-rw-r--r--src/wasm2asm.h35
-rw-r--r--test/emcc_O2_hello_world.2asm.js3
-rw-r--r--test/unit.2asm.js2
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];
}