diff options
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r-- | src/wasm-interpreter.h | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 406938a56..37719d4d9 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1272,6 +1272,7 @@ public: WASM_UNREACHABLE("unimp"); } Flow visitPop(Pop* curr) { WASM_UNREACHABLE("unimp"); } + Flow visitCallRef(CallRef* curr) { WASM_UNREACHABLE("unimp"); } Flow visitRefNull(RefNull* curr) { NOTE_ENTER("RefNull"); return Literal::makeNull(curr->type); @@ -1593,11 +1594,14 @@ public: } return Flow(NONCONSTANT_FLOW); } - Flow visitCallIndirect(CallIndirect* curr) { NOTE_ENTER("CallIndirect"); return Flow(NONCONSTANT_FLOW); } + Flow visitCallRef(CallRef* curr) { + NOTE_ENTER("CallRef"); + return Flow(NONCONSTANT_FLOW); + } Flow visitLoad(Load* curr) { NOTE_ENTER("Load"); return Flow(NONCONSTANT_FLOW); @@ -2095,6 +2099,34 @@ private: } return ret; } + Flow visitCallRef(CallRef* curr) { + NOTE_ENTER("CallRef"); + LiteralList arguments; + Flow flow = this->generateArguments(curr->operands, arguments); + if (flow.breaking()) { + return flow; + } + Flow target = this->visit(curr->target); + if (target.breaking()) { + return target; + } + Name funcName = target.getSingleValue().getFunc(); + auto* func = instance.wasm.getFunction(funcName); + Flow ret; + if (func->imported()) { + ret.values = instance.externalInterface->callImport(func, arguments); + } else { + ret.values = instance.callFunctionInternal(funcName, arguments); + } +#ifdef WASM_INTERPRETER_DEBUG + std::cout << "(returned to " << scope.function->name << ")\n"; +#endif + // TODO: make this a proper tail call (return first) + if (curr->isReturn) { + ret.breakTo = RETURN_FLOW; + } + return ret; + } Flow visitLocalGet(LocalGet* curr) { NOTE_ENTER("LocalGet"); |