summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2020-02-03 14:41:37 -0800
committerGitHub <noreply@github.com>2020-02-03 14:41:37 -0800
commite0a449672a372aced4d11b4d60a49293d413a9bb (patch)
tree4b3879c08c8fbfddf38d8092bdac99c6ffb5f9a2 /src
parentc9f2e9b7b24182e830f39c176170d5ca64d3d05e (diff)
downloadbinaryen-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.h4
-rw-r--r--src/tools/wasm-ctor-eval.cpp5
-rw-r--r--src/wasm-interpreter.h3
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;