summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-interpreter.cpp44
-rw-r--r--src/wasm.h2
2 files changed, 38 insertions, 8 deletions
diff --git a/src/wasm-interpreter.cpp b/src/wasm-interpreter.cpp
index a055ee17d..84f9b585a 100644
--- a/src/wasm-interpreter.cpp
+++ b/src/wasm-interpreter.cpp
@@ -18,11 +18,31 @@ public:
}
}
- Literal callFunction(const char *name) {
- return callFunction(IString(name));
- }
+ typedef std::vector<Literal> LiteralList;
Literal callFunction(IString name) {
+ LiteralList empty;
+ return callFunction(name, empty);
+ }
+
+ Literal callFunction(IString name, LiteralList& arguments) {
+
+ class FunctionScope {
+ public:
+ std::map<IString, Literal> locals;
+
+ FunctionScope(Function* function, LiteralList& arguments) {
+ assert(function->params.size() == arguments.size());
+ for (size_t i = 0; i < arguments.size(); i++) {
+ assert(function->params[i].type == arguments[i].type);
+ locals[function->params[i].name] = arguments[i];
+ }
+ for (auto& local : function->locals) {
+ locals[local.name].type = local.type;
+ }
+ }
+ };
+
// Stuff that flows around during executing expressions: a literal, or a change in control flow
class Flow {
public:
@@ -43,10 +63,10 @@ public:
// Execute a statement
class ExpressionRunner : public WasmVisitor<Flow> {
- private:
- std::vector<Literal> arguments; // filled in before a call, cleared by the call
-
+ FunctionScope& scope;
public:
+ ExpressionRunner(FunctionScope& scope) : scope(scope) {}
+
Flow visitBlock(Block *curr) override {
Flow flow;
for (auto expression : curr->list) {
@@ -96,6 +116,14 @@ public:
abort();
}
Flow visitCall(Call *curr) override {
+ LiteralList arguments;
+ arguments.reserve(curr->operands.size());
+ for (auto expression : curr->operands) {
+ Flow flow = visit(expression);
+ if (flow.breaking()) return flow;
+ arguments.push_back(flow.value);
+ }
+ return callFunction(curr->target, arguments);
}
Flow visitCallImport(CallImport *curr) override {
}
@@ -126,7 +154,9 @@ public:
}
};
- return ExpressionRunner().visit(functions[name]->body).value;
+ Function *function = functions[name];
+ FunctionScope scope(function, arguments);
+ return ExpressionRunner(scope).visit(function->body).value;
}
private:
diff --git a/src/wasm.h b/src/wasm.h
index 07cddfcdd..097ce1900 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -164,7 +164,7 @@ struct Literal {
double f64;
};
- Literal() : type(WasmType::none) {}
+ Literal() : type(WasmType::none), f64(0) {}
Literal(int32_t init) : type(WasmType::i32), i32(init) {}
Literal(int64_t init) : type(WasmType::i64), i64(init) {}
Literal(float init) : type(WasmType::f32), f32(init) {}