| Index: src/wasm/module-decoder.cc
|
| diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc
|
| index 9721f5af63941e0785afa93457b131bf5543144d..d01a4f9a97ee45f96deb5d02b878cc4ac8025349 100644
|
| --- a/src/wasm/module-decoder.cc
|
| +++ b/src/wasm/module-decoder.cc
|
| @@ -30,6 +30,8 @@
|
|
|
| const char* kNameString = "name";
|
| const size_t kNameStringLength = 4;
|
| +
|
| +static const uint32_t kMaxTableSize = 1 << 28;
|
|
|
| LocalType TypeOf(const WasmModule* module, const WasmInitExpr& expr) {
|
| switch (expr.kind) {
|
| @@ -309,22 +311,19 @@
|
| // ===== Imported table ==========================================
|
| import->index =
|
| static_cast<uint32_t>(module->function_tables.size());
|
| - module->function_tables.push_back({0, 0, false,
|
| - std::vector<int32_t>(), true,
|
| - false, SignatureMap()});
|
| + module->function_tables.push_back(
|
| + {0, 0, std::vector<int32_t>(), true, false, SignatureMap()});
|
| expect_u8("element type", kWasmAnyFunctionTypeForm);
|
| WasmIndirectFunctionTable* table = &module->function_tables.back();
|
| - consume_resizable_limits(
|
| - "element count", "elements", WasmModule::kV8MaxTableSize,
|
| - &table->min_size, &table->has_max, &table->max_size);
|
| + consume_resizable_limits("element count", "elements", kMaxTableSize,
|
| + &table->size, &table->max_size);
|
| break;
|
| }
|
| case kExternalMemory: {
|
| // ===== Imported memory =========================================
|
| - bool has_max = false;
|
| - consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages,
|
| - &module->min_mem_pages, &has_max,
|
| - &module->max_mem_pages);
|
| + consume_resizable_limits(
|
| + "memory", "pages", WasmModule::kMaxLegalPages,
|
| + &module->min_mem_pages, &module->max_mem_pages);
|
| break;
|
| }
|
| case kExternalGlobal: {
|
| @@ -376,16 +375,15 @@
|
| error(pos, pos, "invalid table count %d, maximum 1", table_count);
|
| }
|
| if (module->function_tables.size() < 1) {
|
| - module->function_tables.push_back({0, 0, false, std::vector<int32_t>(),
|
| - false, false, SignatureMap()});
|
| + module->function_tables.push_back(
|
| + {0, 0, std::vector<int32_t>(), false, false, SignatureMap()});
|
| }
|
|
|
| for (uint32_t i = 0; ok() && i < table_count; i++) {
|
| WasmIndirectFunctionTable* table = &module->function_tables.back();
|
| expect_u8("table type", kWasmAnyFunctionTypeForm);
|
| - consume_resizable_limits("table elements", "elements",
|
| - WasmModule::kV8MaxTableSize, &table->min_size,
|
| - &table->has_max, &table->max_size);
|
| + consume_resizable_limits("table elements", "elements", kMaxUInt32,
|
| + &table->size, &table->max_size);
|
| }
|
| section_iter.advance();
|
| }
|
| @@ -400,9 +398,8 @@
|
| }
|
|
|
| for (uint32_t i = 0; ok() && i < memory_count; i++) {
|
| - bool has_max = false;
|
| - consume_resizable_limits("memory", "pages", WasmModule::kV8MaxPages,
|
| - &module->min_mem_pages, &has_max,
|
| + consume_resizable_limits("memory", "pages", WasmModule::kMaxLegalPages,
|
| + &module->min_mem_pages,
|
| &module->max_mem_pages);
|
| }
|
| section_iter.advance();
|
| @@ -626,6 +623,7 @@
|
|
|
| if (ok()) {
|
| CalculateGlobalOffsets(module);
|
| + PreinitializeIndirectFunctionTables(module);
|
| }
|
| const WasmModule* finished_module = module;
|
| ModuleResult result = toResult(finished_module);
|
| @@ -751,6 +749,30 @@
|
| module->globals_size = offset;
|
| }
|
|
|
| + // TODO(titzer): this only works without overlapping initializations from
|
| + // global bases for entries
|
| + void PreinitializeIndirectFunctionTables(WasmModule* module) {
|
| + // Fill all tables with invalid entries first.
|
| + for (WasmIndirectFunctionTable& table : module->function_tables) {
|
| + table.values.resize(table.size);
|
| + for (size_t i = 0; i < table.size; i++) {
|
| + table.values[i] = kInvalidFunctionIndex;
|
| + }
|
| + }
|
| + for (WasmTableInit& init : module->table_inits) {
|
| + if (init.offset.kind != WasmInitExpr::kI32Const) continue;
|
| + if (init.table_index >= module->function_tables.size()) continue;
|
| + WasmIndirectFunctionTable& table =
|
| + module->function_tables[init.table_index];
|
| + for (size_t i = 0; i < init.entries.size(); i++) {
|
| + size_t index = i + init.offset.val.i32_const;
|
| + if (index < table.values.size()) {
|
| + table.values[index] = init.entries[i];
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| // Verifies the body (code) of a given function.
|
| void VerifyFunctionBody(uint32_t func_num, ModuleEnv* menv,
|
| WasmFunction* function) {
|
| @@ -844,33 +866,29 @@
|
|
|
| void consume_resizable_limits(const char* name, const char* units,
|
| uint32_t max_value, uint32_t* initial,
|
| - bool* has_max, uint32_t* maximum) {
|
| + uint32_t* maximum) {
|
| uint32_t flags = consume_u32v("resizable limits flags");
|
| const byte* pos = pc();
|
| *initial = consume_u32v("initial size");
|
| - *has_max = false;
|
| if (*initial > max_value) {
|
| error(pos, pos,
|
| - "initial %s size (%u %s) is larger than implementation limit (%u)",
|
| + "initial %s size (%u %s) is larger than maximum allowable (%u)",
|
| name, *initial, units, max_value);
|
| }
|
| if (flags & 1) {
|
| - *has_max = true;
|
| pos = pc();
|
| *maximum = consume_u32v("maximum size");
|
| if (*maximum > max_value) {
|
| - error(
|
| - pos, pos,
|
| - "maximum %s size (%u %s) is larger than implementation limit (%u)",
|
| - name, *maximum, units, max_value);
|
| + error(pos, pos,
|
| + "maximum %s size (%u %s) is larger than maximum allowable (%u)",
|
| + name, *maximum, units, max_value);
|
| }
|
| if (*maximum < *initial) {
|
| error(pos, pos, "maximum %s size (%u %s) is less than initial (%u %s)",
|
| name, *maximum, units, *initial, units);
|
| }
|
| } else {
|
| - *has_max = false;
|
| - *maximum = max_value;
|
| + *maximum = 0;
|
| }
|
| }
|
|
|
|
|