| 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;
|
| }
|
|
|