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 | |
parent | 2d6a5ed822740a6ac53d1807fe2111bee5098bc6 (diff) | |
download | binaryen-51be0e93e50c3717cb8e4dff47000a494e67b29a.tar.gz binaryen-51be0e93e50c3717cb8e4dff47000a494e67b29a.tar.bz2 binaryen-51be0e93e50c3717cb8e4dff47000a494e67b29a.zip |
progress on interpreter
-rwxr-xr-x | build.sh | 1 | ||||
-rw-r--r-- | src/wasm-interpreter.cpp | 96 | ||||
-rw-r--r-- | src/wasm.h | 52 |
3 files changed, 97 insertions, 52 deletions
@@ -1,3 +1,2 @@ -#g++ -std=c++11 src/wasm-interpreter.cpp -g -o bin/wasm g++ -std=c++11 src/asm2wasm.cpp src/parser.cpp src/simple_ast.cpp -g -o bin/asm2wasm 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: diff --git a/src/wasm.h b/src/wasm.h index 25d514368..07cddfcdd 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -114,8 +114,8 @@ bool isFloat(WasmType type) { switch (type) { case f32: case f64: return true; + default: return false; } - return false; } WasmType getWasmType(unsigned size, bool float_) { @@ -170,6 +170,11 @@ struct Literal { Literal(float init) : type(WasmType::f32), f32(init) {} Literal(double init) : type(WasmType::f64), f64(init) {} + int32_t geti32() { assert(type == WasmType::i32); return i32; } + int64_t geti64() { assert(type == WasmType::i64); return i64; } + float getf32() { assert(type == WasmType::f32); return f32; } + double getf64() { assert(type == WasmType::f64); return f64; } + void printDouble(std::ostream &o, double d) { const char *text = JSPrinter::numToString(d); // spec interpreter hates floats starting with '.' @@ -231,8 +236,6 @@ class Expression { public: WasmType type; // the type of the expression: its output, not necessarily its input(s) - Expression() : type(type) {} - virtual std::ostream& print(std::ostream &o, unsigned indent) = 0; template<class T> @@ -244,7 +247,7 @@ public: std::ostream& printFullLine(std::ostream &o, unsigned indent, Expression *expression) { doIndent(o, indent); expression->print(o, indent); - o << '\n'; + return o << '\n'; } std::ostream& printOpening(std::ostream &o, const char *str, bool major=false) { @@ -325,6 +328,7 @@ public: class Label : public Expression { public: Name name; + Expression* body; }; class Break : public Expression { @@ -860,26 +864,26 @@ struct WasmWalker : public WasmVisitor<Expression*> { WasmWalker(wasm::Arena* allocator) : allocator(allocator) {} // Each method receives an AST pointer, and it is replaced with what is returned. - virtual Expression* visitBlock(Block *curr) { return curr; }; - virtual Expression* visitIf(If *curr) { return curr; }; - virtual Expression* visitLoop(Loop *curr) { return curr; }; - virtual Expression* visitLabel(Label *curr) { return curr; }; - virtual Expression* visitBreak(Break *curr) { return curr; }; - virtual Expression* visitSwitch(Switch *curr) { return curr; }; - virtual Expression* visitCall(Call *curr) { return curr; }; - virtual Expression* visitCallImport(CallImport *curr) { return curr; }; - virtual Expression* visitCallIndirect(CallIndirect *curr) { return curr; }; - virtual Expression* visitGetLocal(GetLocal *curr) { return curr; }; - virtual Expression* visitSetLocal(SetLocal *curr) { return curr; }; - virtual Expression* visitLoad(Load *curr) { return curr; }; - virtual Expression* visitStore(Store *curr) { return curr; }; - virtual Expression* visitConst(Const *curr) { return curr; }; - virtual Expression* visitUnary(Unary *curr) { return curr; }; - virtual Expression* visitBinary(Binary *curr) { return curr; }; - virtual Expression* visitCompare(Compare *curr) { return curr; }; - virtual Expression* visitConvert(Convert *curr) { return curr; }; - virtual Expression* visitHost(Host *curr) { return curr; }; - virtual Expression* visitNop(Nop *curr) { return curr; }; + Expression* visitBlock(Block *curr) override { return curr; }; + Expression* visitIf(If *curr) override { return curr; }; + Expression* visitLoop(Loop *curr) override { return curr; }; + Expression* visitLabel(Label *curr) override { return curr; }; + Expression* visitBreak(Break *curr) override { return curr; }; + Expression* visitSwitch(Switch *curr) override { return curr; }; + Expression* visitCall(Call *curr) override { return curr; }; + Expression* visitCallImport(CallImport *curr) override { return curr; }; + Expression* visitCallIndirect(CallIndirect *curr) override { return curr; }; + Expression* visitGetLocal(GetLocal *curr) override { return curr; }; + Expression* visitSetLocal(SetLocal *curr) override { return curr; }; + Expression* visitLoad(Load *curr) override { return curr; }; + Expression* visitStore(Store *curr) override { return curr; }; + Expression* visitConst(Const *curr) override { return curr; }; + Expression* visitUnary(Unary *curr) override { return curr; }; + Expression* visitBinary(Binary *curr) override { return curr; }; + Expression* visitCompare(Compare *curr) override { return curr; }; + Expression* visitConvert(Convert *curr) override { return curr; }; + Expression* visitHost(Host *curr) override { return curr; }; + Expression* visitNop(Nop *curr) override { return curr; }; // children-first Expression *walk(Expression *curr) { |