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