diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-12-05 12:16:02 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-12-05 12:16:02 -0800 |
commit | 164805eb14c4ecdad1088cf92f241509552a85ec (patch) | |
tree | 3cd810016c60a15d50c10c71ad78af68c7af9ccd | |
parent | 9024b061cbf4609a3925bfd0100a6a5734ce9d92 (diff) | |
download | binaryen-164805eb14c4ecdad1088cf92f241509552a85ec.tar.gz binaryen-164805eb14c4ecdad1088cf92f241509552a85ec.tar.bz2 binaryen-164805eb14c4ecdad1088cf92f241509552a85ec.zip |
refactor call and add callIndirect in wasm2asm
-rw-r--r-- | src/wasm2asm.h | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/src/wasm2asm.h b/src/wasm2asm.h index 9ff7b7de1..2d58725c1 100644 --- a/src/wasm2asm.h +++ b/src/wasm2asm.h @@ -16,6 +16,7 @@ using namespace cashew; IString ASM_FUNC("asmFunc"), ABORT_FUNC("abort"), + FUNCTION_TABLE("FUNCTION_TABLE"), NO_RESULT("wasm2asm$noresult"), // no result at all EXPRESSION_RESULT("wasm2asm$expresult"); // result in an expression, no temp var @@ -544,20 +545,10 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { } return ret; } - Ref visitCall(Call *curr) override { - Ref theCall = ValueBuilder::makeCall(fromName(curr->target)); - if (!isStatement(curr)) { - // none of our operands is a statement; go right ahead and create a simple expression - Ref theCall = ValueBuilder::makeCall(fromName(curr->target)); - for (auto operand : curr->operands) { - theCall[2]->push_back(visit(operand, EXPRESSION_RESULT)); - } - return theCall; - } - // we must statementize them all - Ref ret = ValueBuilder::makeBlock(); + + Ref makeStatementizedCall(ExpressionList& operands, Ref ret, Ref theCall, IString result) { std::vector<ScopedTemp> temps; - for (auto& operand : curr->operands) { + for (auto& operand : operands) { temps.emplace_back(operand->type, parent); IString temp = temps.back().temp; ret[1]->push_back(visitAndAssign(operand, temp)); @@ -569,11 +560,37 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { ret[1]->push_back(theCall); return ret; } + + Ref visitCall(Call *curr) override { + Ref theCall = ValueBuilder::makeCall(fromName(curr->target)); + if (!isStatement(curr)) { + // none of our operands is a statement; go right ahead and create a simple expression + for (auto operand : curr->operands) { + theCall[2]->push_back(visit(operand, EXPRESSION_RESULT)); + } + return theCall; + } + // we must statementize them all + return makeStatementizedCall(curr->operands, ValueBuilder::makeBlock(), theCall, result); + } Ref visitCallImport(CallImport *curr) override { return visitCall(curr); } Ref visitCallIndirect(CallIndirect *curr) override { - abort(); // XXX TODO + 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))); + for (auto operand : curr->operands) { + theCall[2]->push_back(visit(operand, EXPRESSION_RESULT)); + } + return theCall; + } + // we must statementize them all + Ref ret = ValueBuilder::makeBlock(); + ScopedTemp temp(i32, parent); + ret[1]->push_back(visit(curr->target, temp)); + Ref theCall = ValueBuilder::makeCall(ValueBuilder::makeSub(ValueBuilder::makeName(FUNCTION_TABLE), temp.getAstName())); + return makeStatementizedCall(curr->operands, ret, theCall, result); } Ref visitGetLocal(GetLocal *curr) override { return ValueBuilder::makeName(fromName(curr->name)); |