summaryrefslogtreecommitdiff
path: root/src/wasm-interpreter.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-11-24 12:36:11 -0800
committerGitHub <noreply@github.com>2020-11-24 12:36:11 -0800
commit78ccc1976bac069ae65b2ec227e8c2c515a02801 (patch)
treeb875343fa47a62a44db4370811080dc963a91233 /src/wasm-interpreter.h
parentcecff82aff317c3132f80a764dba163bcd852a78 (diff)
downloadbinaryen-78ccc1976bac069ae65b2ec227e8c2c515a02801.tar.gz
binaryen-78ccc1976bac069ae65b2ec227e8c2c515a02801.tar.bz2
binaryen-78ccc1976bac069ae65b2ec227e8c2c515a02801.zip
[TypedFunctionReferences] Implement call_ref (#3396)
Includes minimal support in various passes. Also includes actual optimization work in Directize, which was easy to add. Almost has fuzzer support, but the actual makeCallRef is just a stub so far. Includes s-parser support for parsing typed function references types.
Diffstat (limited to 'src/wasm-interpreter.h')
-rw-r--r--src/wasm-interpreter.h34
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");