diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-12-07 13:59:59 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-12-07 14:03:43 -0800 |
commit | 09771ea21a3f30ade4a8abb7482fdd3b6eaaba7a (patch) | |
tree | 6b4ce653edc13318b758db60417d68f714623bae /src | |
parent | 43ddf341c47350db98618c49a5d0acb0af6960ab (diff) | |
download | binaryen-09771ea21a3f30ade4a8abb7482fdd3b6eaaba7a.tar.gz binaryen-09771ea21a3f30ade4a8abb7482fdd3b6eaaba7a.tar.bz2 binaryen-09771ea21a3f30ade4a8abb7482fdd3b6eaaba7a.zip |
emit function table calls in wasm2asm
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 14 | ||||
-rw-r--r-- | src/asm_v_wasm.h | 20 | ||||
-rw-r--r-- | src/wasm2asm.h | 27 |
3 files changed, 47 insertions, 14 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 27f7edffb..dbf142fd3 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -233,23 +233,13 @@ private: } } - char getSigFromType(WasmType type) { - switch (type) { - case i32: return 'i'; - case f32: return 'f'; - case f64: return 'd'; - case none: return 'v'; - default: abort(); - } - } - FunctionType *getFunctionType(Ref parent, ExpressionList& operands) { // generate signature WasmType result = detectWasmType(parent, nullptr); std::string str = "FUNCSIG$"; - str += getSigFromType(result); + str += getSig(result); for (auto operand : operands) { - str += getSigFromType(operand->type); + str += getSig(operand->type); } IString sig(str.c_str(), false); if (wasm.functionTypesMap.find(sig) == wasm.functionTypesMap.end()) { diff --git a/src/asm_v_wasm.h b/src/asm_v_wasm.h index f59d51d25..323d255ee 100644 --- a/src/asm_v_wasm.h +++ b/src/asm_v_wasm.h @@ -27,7 +27,27 @@ AsmType wasmToAsmType(WasmType type) { abort(); } +char getSig(WasmType type) { + switch (type) { + case i32: return 'i'; + case f32: return 'f'; + case f64: return 'd'; + case none: return 'v'; + default: abort(); + } +} + +std::string getSig(FunctionType *type) { + // generate signature + std::string ret; + ret += getSig(type->result); + for (auto param : type->params) { + ret += getSig(param); + } + return ret; } +} // namespace wasm + #endif // _asm_v_wasm_h_ diff --git a/src/wasm2asm.h b/src/wasm2asm.h index 8f8025dfa..4fab55f86 100644 --- a/src/wasm2asm.h +++ b/src/wasm2asm.h @@ -143,6 +143,10 @@ public: return breakedWithValue.find(name) != breakedWithValue.end(); } + size_t getTableSize() { + return tableSize; + } + private: // How many temp vars we need std::vector<int> temps; // type => num temps @@ -155,6 +159,9 @@ private: // Label names to which we break with a value aka spooky-return-at-a-distance std::set<Name> breakedWithValue; + // All our function tables have the same size TODO: optimize? + size_t tableSize; + void addHeaps(Ref ast); }; @@ -166,7 +173,15 @@ Ref Wasm2AsmBuilder::processWasm(Module* wasm) { ValueBuilder::appendArgumentToFunction(asmFunc, ENV); ValueBuilder::appendArgumentToFunction(asmFunc, BUFFER); asmFunc[3]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeString(USE_ASM))); + // create heaps addHeaps(asmFunc[3]); + // figure out the table size + tableSize = wasm->table.names.size(); + size_t pow2ed = 1; + while (pow2ed < tableSize) { + pow2ed <<= 1; + } + tableSize = pow2ed; // imports XXX // exports XXX // functions @@ -638,9 +653,17 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { return visitCall(curr); } Ref visitCallIndirect(CallIndirect *curr) override { + std::string stable = std::string("FUNCTION_TABLE_") + getSig(curr->fullType); + IString table = IString(stable.c_str(), false); + auto makeTableCall = [&](Ref target) { + return ValueBuilder::makeCall(ValueBuilder::makeSub( + ValueBuilder::makeName(table), + ValueBuilder::makeBinary(target, AND, ValueBuilder::makeInt(parent->getTableSize()-1)) + )); + }; if (!isStatement(curr)) { // none of our operands is a statement; go right ahead and create a simple expression - Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), visit(curr->target, EXPRESSION_RESULT))); + Ref theCall = makeTableCall(visit(curr->target, EXPRESSION_RESULT)); for (auto operand : curr->operands) { theCall[2]->push_back(makeAsmCoercion(visit(operand, EXPRESSION_RESULT), wasmToAsmType(operand->type))); } @@ -650,7 +673,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { Ref ret = ValueBuilder::makeBlock(); ScopedTemp temp(i32, parent); flattenAppend(ret, visit(curr->target, temp)); - Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), temp.getAstName())); + Ref theCall = makeTableCall(temp.getAstName()); return makeStatementizedCall(curr->operands, ret, theCall, result, curr->type); } Ref visitGetLocal(GetLocal *curr) override { |