Index: src/wasm/ast-decoder.cc |
diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc |
index 28723c5fa6ae3410bdaf66d14ef684fe188c5c63..dbd3518de27a902c5a03c1f8facacfd89102c859 100644 |
--- a/src/wasm/ast-decoder.cc |
+++ b/src/wasm/ast-decoder.cc |
@@ -147,8 +147,12 @@ class WasmDecoder : public Decoder { |
inline bool Complete(const byte* pc, CallIndirectOperand& operand) { |
ModuleEnv* m = module_; |
- if (m && m->module && operand.index < m->module->signatures.size()) { |
- operand.sig = m->module->signatures[operand.index]; |
+ if (m && m->module && operand.sig_index < m->module->signatures.size() && |
+ operand.table_index < m->module->function_tables.size()) { |
+ operand.sig = m->module->signatures[operand.sig_index]; |
+ operand.table = |
+ m->module->signatures[m->module->function_tables[operand.table_index] |
+ .sig_index]; |
return true; |
} |
return false; |
@@ -157,11 +161,19 @@ class WasmDecoder : public Decoder { |
inline bool Validate(const byte* pc, CallIndirectOperand& operand) { |
if (Complete(pc, operand)) { |
uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); |
+ uint32_t table_sig = |
+ module_->module->function_tables[operand.table_index].sig_index; |
if (operand.arity != expected) { |
error(pc, pc + 1, |
"arity mismatch in indirect function call (expected %u, got %u)", |
expected, operand.arity); |
return false; |
+ } else if (!isAnyFuncType(operand.table) && |
+ operand.sig_index != table_sig) { |
+ error(pc, pc + 1, |
+ "signature mismatch in indirect function call (expected %u, got " |
+ "%u)", |
+ operand.sig_index, table_sig); |
} |
return true; |
} |
@@ -977,8 +989,8 @@ class WasmFullDecoder : public WasmDecoder { |
TFNode** buffer = PopArgs(operand.sig); |
Value index = Pop(0, kAstI32); |
if (buffer) buffer[0] = index.node; |
- TFNode* call = |
- BUILD(CallIndirect, operand.index, buffer, position()); |
+ TFNode* call = BUILD(CallIndirect, operand.sig_index, |
+ operand.table_index, buffer, position()); |
Push(GetReturnType(operand.sig), call); |
} |
len = 1 + operand.length; |
@@ -1615,9 +1627,11 @@ bool PrintAst(base::AccountingAllocator* allocator, const FunctionBody& body, |
case kExprCallIndirect: { |
CallIndirectOperand operand(&i, i.pc()); |
if (decoder.Complete(i.pc(), operand)) { |
- os << " // sig #" << operand.index << ": " << *operand.sig; |
+ os << " // sig #" << operand.sig_index << ": " << *operand.sig |
+ << ", table # " << operand.table_index; |
} else { |
- os << " // arity=" << operand.arity << " sig #" << operand.index; |
+ os << " // arity=" << operand.arity << " sig #" << operand.sig_index |
+ << "table # " << operand.table_index; |
} |
break; |
} |