diff options
author | Alon Zakai <alonzakai@gmail.com> | 2015-10-30 21:54:41 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2015-10-30 21:54:41 -0700 |
commit | 51be0e93e50c3717cb8e4dff47000a494e67b29a (patch) | |
tree | 1295019dd99846b924423891faa015d137175057 /src/wasm-interpreter.cpp | |
parent | 2d6a5ed822740a6ac53d1807fe2111bee5098bc6 (diff) | |
download | binaryen-51be0e93e50c3717cb8e4dff47000a494e67b29a.tar.gz binaryen-51be0e93e50c3717cb8e4dff47000a494e67b29a.tar.bz2 binaryen-51be0e93e50c3717cb8e4dff47000a494e67b29a.zip |
progress on interpreter
Diffstat (limited to 'src/wasm-interpreter.cpp')
-rw-r--r-- | src/wasm-interpreter.cpp | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/src/wasm-interpreter.cpp b/src/wasm-interpreter.cpp index ae7b2e793..a055ee17d 100644 --- a/src/wasm-interpreter.cpp +++ b/src/wasm-interpreter.cpp @@ -24,67 +24,109 @@ public: Literal callFunction(IString name) { // Stuff that flows around during executing expressions: a literal, or a change in control flow - class Flow : public Literal { + class Flow { public: + Flow() {} + Flow(Literal value) : value(value) {} + + Literal value; IString breakTo; // if non-null, a break is going on + + bool breaking() { return breakTo.is(); } + + void clearIf(IString target) { + if (breakTo == target) { + breakTo.clear(); + } + } }; // Execute a statement class ExpressionRunner : public WasmVisitor<Flow> { - virtual Flow visitBlock(Block *curr) { + private: + std::vector<Literal> arguments; // filled in before a call, cleared by the call + + public: + Flow visitBlock(Block *curr) override { Flow flow; for (auto expression : curr->list) { flow = visit(expression); - if (flow.breakTo) { - if (flow.breakTo == curr->name) { - flow.breakTo.clear(); - } + if (flow.breaking()) { + flow.clearIf(curr->name); return flow; } } return flow; } - virtual Flow visitIf(If *curr) { - } - virtual Flow visitLoop(Loop *curr) { + Flow visitIf(If *curr) override { + Flow flow = visit(curr->condition); + if (flow.breaking()) return flow; + if (flow.value.geti32()) return visit(curr->ifTrue); + if (curr->ifFalse) return visit(curr->ifFalse); + return Flow(); + } + Flow visitLoop(Loop *curr) override { + while (1) { + Flow flow = visit(curr->body); + if (flow.breaking()) { + if (flow.breakTo == curr->in) continue; // lol + flow.clearIf(curr->out); + return flow; + } + } } - virtual Flow visitLabel(Label *curr) { + Flow visitLabel(Label *curr) override { + Flow flow = visit(curr->body); + flow.clearIf(curr->name); + return flow; } - virtual Flow visitBreak(Break *curr) { + Flow visitBreak(Break *curr) override { + if (curr->condition) { + Flow flow = visit(curr->condition); + if (flow.breaking()) return flow; + if (!flow.value.geti32()) return Flow(); + } + Flow flow = visit(curr->value); + if (!flow.breaking()) { + flow.breakTo = curr->name; + } + return flow; } - virtual Flow visitSwitch(Switch *curr) { + Flow visitSwitch(Switch *curr) override { + abort(); } - virtual Flow visitCall(Call *curr) { + Flow visitCall(Call *curr) override { } - virtual Flow visitCallImport(CallImport *curr) { + Flow visitCallImport(CallImport *curr) override { } - virtual Flow visitCallIndirect(CallIndirect *curr) { + Flow visitCallIndirect(CallIndirect *curr) override { } - virtual Flow visitGetLocal(GetLocal *curr) { + Flow visitGetLocal(GetLocal *curr) override { } - virtual Flow visitSetLocal(SetLocal *curr) { + Flow visitSetLocal(SetLocal *curr) override { } - virtual Flow visitLoad(Load *curr) { + Flow visitLoad(Load *curr) override { } - virtual Flow visitStore(Store *curr) { + Flow visitStore(Store *curr) override { } - virtual Flow visitConst(Const *curr) { + Flow visitConst(Const *curr) override { + return Flow(curr->value); // heh } - virtual Flow visitUnary(Unary *curr) { + Flow visitUnary(Unary *curr) override { } - virtual Flow visitBinary(Binary *curr) { + Flow visitBinary(Binary *curr) override { } - virtual Flow visitCompare(Compare *curr) { + Flow visitCompare(Compare *curr) override { } - virtual Flow visitConvert(Convert *curr) { + Flow visitConvert(Convert *curr) override { } - virtual Flow visitHost(Host *curr) { + Flow visitHost(Host *curr) override { } - virtual Flow visitNop(Nop *curr) { + Flow visitNop(Nop *curr) override { } }; - return ExpressionRunner().visit(functions[name]->body); + return ExpressionRunner().visit(functions[name]->body).value; } private: |