@@ -47,11 +47,14 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
47
47
ExpressionInterpreter (Interpreter& parent) : parent(parent) {}
48
48
49
49
WasmStore& store () { return InterpreterImpl::getStore (parent); }
50
+ Frame& frame () { return store ().callStack .back (); }
51
+ Instance& instance () { return frame ().instance ; }
52
+
50
53
void push (Literal val) { store ().push (val); }
51
54
Literal pop () { return store ().pop (); }
52
55
53
56
Flow visitNop (Nop* curr) { WASM_UNREACHABLE (" TODO" ); }
54
- Flow visitBlock (Block* curr) { WASM_UNREACHABLE ( " TODO " ) ; }
57
+ Flow visitBlock (Block* curr) { return {} ; }
55
58
Flow visitIf (If* curr) { WASM_UNREACHABLE (" TODO" ); }
56
59
Flow visitLoop (Loop* curr) { WASM_UNREACHABLE (" TODO" ); }
57
60
Flow visitBreak (Break* curr) { WASM_UNREACHABLE (" TODO" ); }
@@ -60,8 +63,14 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
60
63
Flow visitCallIndirect (CallIndirect* curr) { WASM_UNREACHABLE (" TODO" ); }
61
64
Flow visitLocalGet (LocalGet* curr) { WASM_UNREACHABLE (" TODO" ); }
62
65
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
+ }
65
74
Flow visitLoad (Load* curr) { WASM_UNREACHABLE (" TODO" ); }
66
75
Flow visitStore (Store* curr) { WASM_UNREACHABLE (" TODO" ); }
67
76
Flow visitAtomicRMW (AtomicRMW* curr) { WASM_UNREACHABLE (" TODO" ); }
@@ -272,13 +281,33 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
272
281
273
282
} // anonymous namespace
274
283
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
+ }
281
309
310
+ std::vector<Literal> Interpreter::run () {
282
311
ExpressionInterpreter interpreter (*this );
283
312
while (auto & it = store.callStack .back ().exprs ) {
284
313
if (auto flow = interpreter.visit (*it)) {
@@ -288,7 +317,9 @@ std::vector<Literal> Interpreter::run(Expression* root) {
288
317
}
289
318
}
290
319
291
- return store.callStack .back ().valueStack ;
320
+ auto valueStack = store.callStack .back ().valueStack ;
321
+ store.callStack .pop_back ();
322
+ return valueStack;
292
323
}
293
324
294
325
} // namespace wasm
0 commit comments