diff options
author | Heejin Ahn <aheejin@gmail.com> | 2020-02-03 14:41:37 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-03 14:41:37 -0800 |
commit | e0a449672a372aced4d11b4d60a49293d413a9bb (patch) | |
tree | 4b3879c08c8fbfddf38d8092bdac99c6ffb5f9a2 /src | |
parent | c9f2e9b7b24182e830f39c176170d5ca64d3d05e (diff) | |
download | binaryen-e0a449672a372aced4d11b4d60a49293d413a9bb.tar.gz binaryen-e0a449672a372aced4d11b4d60a49293d413a9bb.tar.bz2 binaryen-e0a449672a372aced4d11b4d60a49293d413a9bb.zip |
Trap when call_indirect's signatures mismatch (#2636)
This makes the interpreter trap when the signature in `call_indirect`
instruction and that of the actual function in the table mismatch. This
also makes the `wasm-ctor-eval` not evaluate `call_indirect` in case the
signatures mismatch.
Before we only compared the arguments' signature and the function
signature, which was sufficient before we had subtypes, but now the
signature in `call_indirect` and that of the actual function can be
different even if the argument's signature is OK.
Diffstat (limited to 'src')
-rw-r--r-- | src/shell-interface.h | 4 | ||||
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 5 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 3 |
3 files changed, 11 insertions, 1 deletions
diff --git a/src/shell-interface.h b/src/shell-interface.h index f1b68ab60..03b190626 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -150,6 +150,7 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { } Literal callTable(Index index, + Signature sig, LiteralList& arguments, Type results, ModuleInstance& instance) override { @@ -160,6 +161,9 @@ struct ShellExternalInterface : ModuleInstance::ExternalInterface { if (!func) { trap("uninitialized table element"); } + if (sig != func->sig) { + trap("callIndirect: function signatures don't match"); + } const std::vector<Type>& params = func->sig.params.expand(); if (params.size() != arguments.size()) { trap("callIndirect: bad # of arguments"); diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index b45c624a4..3aef10cf0 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -215,6 +215,7 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface { } Literal callTable(Index index, + Signature sig, LiteralList& arguments, Type result, EvallingModuleInstance& instance) override { @@ -240,6 +241,10 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface { // if this is one of our functions, we can call it; if it was imported, // fail auto* func = wasm->getFunction(name); + if (func->sig != sig) { + throw FailToEvalException( + std::string("callTable signature mismatch: ") + name.str); + } if (!func->imported()) { return instance.callFunctionInternal(name, arguments); } else { diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index cf5908adf..cbed38b2f 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1188,6 +1188,7 @@ public: virtual void importGlobals(GlobalManager& globals, Module& wasm) = 0; virtual Literal callImport(Function* import, LiteralList& arguments) = 0; virtual Literal callTable(Index index, + Signature sig, LiteralList& arguments, Type result, SubType& instance) = 0; @@ -1575,7 +1576,7 @@ private: Index index = target.value.geti32(); Type type = curr->isReturn ? scope.function->sig.results : curr->type; Flow ret = instance.externalInterface->callTable( - index, arguments, type, *instance.self()); + index, curr->sig, arguments, type, *instance.self()); // TODO: make this a proper tail call (return first) if (curr->isReturn) { Const c; |