@@ -47,11 +47,14 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
4747 ExpressionInterpreter (Interpreter& parent) : parent(parent) {}
4848
4949 WasmStore& store () { return InterpreterImpl::getStore (parent); }
50+ Frame& frame () { return store ().callStack .back (); }
51+ Instance& instance () { return frame ().instance ; }
52+
5053 void push (Literal val) { store ().push (val); }
5154 Literal pop () { return store ().pop (); }
5255
5356 Flow visitNop (Nop* curr) { WASM_UNREACHABLE (" TODO" ); }
54- Flow visitBlock (Block* curr) { WASM_UNREACHABLE ( " TODO " ) ; }
57+ Flow visitBlock (Block* curr) { return {} ; }
5558 Flow visitIf (If* curr) { WASM_UNREACHABLE (" TODO" ); }
5659 Flow visitLoop (Loop* curr) { WASM_UNREACHABLE (" TODO" ); }
5760 Flow visitBreak (Break* curr) { WASM_UNREACHABLE (" TODO" ); }
@@ -60,8 +63,14 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
6063 Flow visitCallIndirect (CallIndirect* curr) { WASM_UNREACHABLE (" TODO" ); }
6164 Flow visitLocalGet (LocalGet* curr) { WASM_UNREACHABLE (" TODO" ); }
6265 Flow visitLocalSet (LocalSet* curr) { WASM_UNREACHABLE (" TODO" ); }
63- Flow visitGlobalGet (GlobalGet* curr) { WASM_UNREACHABLE (" TODO" ); }
64- Flow visitGlobalSet (GlobalSet* curr) { WASM_UNREACHABLE (" TODO" ); }
66+ Flow visitGlobalGet (GlobalGet* curr) {
67+ push (instance ().globalValues [curr->name ]);
68+ return {};
69+ }
70+ Flow visitGlobalSet (GlobalSet* curr) {
71+ instance ().globalValues [curr->name ] = pop ();
72+ return {};
73+ }
6574 Flow visitLoad (Load* curr) { WASM_UNREACHABLE (" TODO" ); }
6675 Flow visitStore (Store* curr) { WASM_UNREACHABLE (" TODO" ); }
6776 Flow visitAtomicRMW (AtomicRMW* curr) { WASM_UNREACHABLE (" TODO" ); }
@@ -272,13 +281,33 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
272281
273282} // anonymous namespace
274283
275- std::vector<Literal> Interpreter::run (Expression* root) {
276- // Create a fresh store and execution frame, then run the expression to
277- // completion.
278- store = WasmStore ();
279- store.callStack .emplace_back ();
280- store.callStack .back ().exprs = ExpressionIterator (root);
284+ Result<> Interpreter::addInstance (std::shared_ptr<Module> wasm) {
285+ return instantiate (store.instances .emplace_back (wasm));
286+ }
287+
288+ Result<> Interpreter::instantiate (Instance& instance) {
289+ for (auto & global : instance.wasm ->globals ) {
290+ store.callStack .emplace_back (instance, ExpressionIterator (global->init ));
291+ auto results = run ();
292+ assert (results.size () == 1 );
293+ instance.globalValues [global->name ] = results[0 ];
294+ }
295+ return Ok{};
296+ }
297+
298+ // This is a temporary convenience while stil using gTests to validate this
299+ // interpreter. Once spec tests can run, this shall be deleted.
300+ std::vector<Literal> Interpreter::runTest (Expression* root) {
301+ static std::shared_ptr<wasm::Module> dummyModule = std::make_shared<Module>();
302+ if (store.instances .empty ()) {
303+ auto result = addInstance (dummyModule);
304+ }
305+ store.callStack .emplace_back (store.instances .back (),
306+ ExpressionIterator (root));
307+ return run ();
308+ }
281309
310+ std::vector<Literal> Interpreter::run () {
282311 ExpressionInterpreter interpreter (*this );
283312 while (auto & it = store.callStack .back ().exprs ) {
284313 if (auto flow = interpreter.visit (*it)) {
@@ -288,7 +317,9 @@ std::vector<Literal> Interpreter::run(Expression* root) {
288317 }
289318 }
290319
291- return store.callStack .back ().valueStack ;
320+ auto valueStack = store.callStack .back ().valueStack ;
321+ store.callStack .pop_back ();
322+ return valueStack;
292323}
293324
294325} // namespace wasm
0 commit comments