Index: src/wasm/module-decoder.cc |
diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc |
index 542c47ca159c9836726ed92bf1b3f62e4bd5b9b0..0c75006e6a4ccf3830fc697bdd55b65a34f77afd 100644 |
--- a/src/wasm/module-decoder.cc |
+++ b/src/wasm/module-decoder.cc |
@@ -260,16 +260,22 @@ class ModuleDecoder : public Decoder { |
case WasmSection::Code::FunctionTable: { |
// An indirect function table requires functions first. |
CheckForFunctions(module, section); |
- // Assume only one table for now. |
- static const uint32_t kSupportedTableCount = 1; |
- module->function_tables.reserve(SafeReserve(kSupportedTableCount)); |
+ uint32_t table_count = consume_u32v("function table count"); |
+ module->function_tables.reserve(SafeReserve(table_count)); |
// Decode function table. |
- for (uint32_t i = 0; i < kSupportedTableCount; ++i) { |
+ for (uint32_t i = 0; i < table_count; ++i) { |
if (failed()) break; |
TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
static_cast<int>(pc_ - start_)); |
- module->function_tables.push_back({0, 0, std::vector<uint16_t>()}); |
- DecodeFunctionTableInModule(module, &module->function_tables[i]); |
+ module->function_tables.push_back( |
+ {!i, // default |
+ nullptr, // sig |
+ 0, // sig_index |
+ 0, // size |
+ 0, // max_size |
+ std::vector<uint16_t>()}); // vals |
+ DecodeFunctionTableInModule(module, |
+ &module->function_tables.back()); |
} |
break; |
} |
@@ -506,8 +512,14 @@ class ModuleDecoder : public Decoder { |
// Decodes a single function table inside a module starting at {pc_}. |
void DecodeFunctionTableInModule(WasmModule* module, |
WasmIndirectFunctionTable* table) { |
+ table->isDefault = consume_u8("default"); |
+ if (table->isDefault && module->function_tables.size() > 1) { |
+ error("invalid default flag"); |
+ } |
+ table->sig_index = consume_sig_index(module, &table->sig); |
+ |
table->size = consume_u32v("function table entry count"); |
- table->max_size = table->size; |
+ table->max_size = consume_u32v(); |
if (table->max_size != table->size) { |
error("invalid table maximum size"); |
@@ -519,6 +531,11 @@ class ModuleDecoder : public Decoder { |
error(pc_ - sizeof(index), "invalid function index"); |
break; |
} |
+ if (!isAnyFuncType(table->sig) && |
+ module->functions[index].sig != table->sig) { |
+ error("invalid function signature type"); |
+ break; |
+ } |
table->values.push_back(index); |
} |
} |
@@ -654,7 +671,7 @@ class ModuleDecoder : public Decoder { |
std::vector<LocalType> params; |
for (uint32_t i = 0; i < param_count; ++i) { |
LocalType param = consume_local_type(); |
- if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); |
+ if (param == kAstStmt && i) error(pc_ - 1, "invalid void parameter type"); |
params.push_back(param); |
} |
@@ -673,6 +690,10 @@ class ModuleDecoder : public Decoder { |
returns.push_back(ret); |
} |
+ // Check if a parameter is kAstStmt but it is not the special kAnyFunc type |
+ if (param_count == 1 && params[0] == kAstStmt && return_count != 0) |
+ error(pc_ - 1, "invalid void parameter type"); |
+ |
// FunctionSig stores the return types first. |
LocalType* buffer = |
module_zone->NewArray<LocalType>(param_count + return_count); |