Chromium Code Reviews| Index: src/wasm/module-decoder.cc |
| diff --git a/src/wasm/module-decoder.cc b/src/wasm/module-decoder.cc |
| index 401fb1823973049a9f616662a79b9699e91c8530..529570b1181c74f03bd4ae5fda42af859f97c412 100644 |
| --- a/src/wasm/module-decoder.cc |
| +++ b/src/wasm/module-decoder.cc |
| @@ -51,7 +51,7 @@ class ModuleDecoder : public Decoder { |
| module->mem_external = false; |
| module->origin = origin_; |
| - bool sections[kMaxModuleSectionCode] = {false}; |
| + bool sections[(size_t)WasmSection::Code::Max] = {false}; |
| const byte* pos = pc_; |
| uint32_t magic_word = consume_u32("wasm magic"); |
| @@ -77,33 +77,42 @@ class ModuleDecoder : public Decoder { |
| // Decode the module sections. |
| while (pc_ < limit_) { |
| TRACE("DecodeSection\n"); |
| - uint8_t section_u8 = consume_u8("section"); |
| + pos = pc_; |
| - if (section_u8 >= kMaxModuleSectionCode) { |
| + int length; |
| + uint32_t section_bytes = consume_u32v(&length, "section size"); |
|
titzer
2016/03/09 13:19:37
section_size
*_bytes sounds like it might refer t
JF
2016/03/09 18:51:52
Done.
|
| + |
| + uint32_t section_string_bytes; |
|
titzer
2016/03/09 13:19:37
section_string_size
JF
2016/03/09 18:51:52
Done.
|
| + WasmSection::Code section = consume_section_name(§ion_string_bytes); |
| + if (section_string_bytes > section_bytes) { |
| + error(pos, pos, |
| + "section string of size %u longer than total section bytes %u", |
| + section_string_bytes, section_bytes); |
| + break; |
| + } |
| + |
| + if (section == WasmSection::Code::Max) { |
| // Skip unknown section. |
| - int length; |
| - uint32_t section_bytes = consume_u32v(&length, "section size"); |
| - consume_bytes(section_bytes); |
| + consume_bytes(section_bytes - section_string_bytes); |
| continue; |
| } |
| // Each section should appear at most once. |
| - auto section = static_cast<WasmSectionDeclCode>(section_u8); |
| CheckForPreviousSection(sections, section, false); |
| - sections[section] = true; |
| + sections[(size_t)section] = true; |
| switch (section) { |
| - case kDeclEnd: |
| + case WasmSection::Code::End: |
| // Terminate section decoding. |
| limit_ = pc_; |
| break; |
| - case kDeclMemory: |
| + case WasmSection::Code::Memory: |
| int length; |
| module->min_mem_pages = consume_u32v(&length, "min memory"); |
| module->max_mem_pages = consume_u32v(&length, "max memory"); |
| module->mem_export = consume_u8("export memory") != 0; |
| break; |
| - case kDeclSignatures: { |
| + case WasmSection::Code::Signatures: { |
| int length; |
| uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
| module->signatures.reserve(SafeReserve(signatures_count)); |
| @@ -117,9 +126,9 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclFunctions: { |
| + case WasmSection::Code::Functions: { |
| // Functions require a signature table first. |
| - CheckForPreviousSection(sections, kDeclSignatures, true); |
| + CheckForPreviousSection(sections, WasmSection::Code::Signatures, true); |
| int length; |
| uint32_t functions_count = consume_u32v(&length, "functions count"); |
| module->functions.reserve(SafeReserve(functions_count)); |
| @@ -152,7 +161,7 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclGlobals: { |
| + case WasmSection::Code::Globals: { |
| int length; |
| uint32_t globals_count = consume_u32v(&length, "globals count"); |
| module->globals.reserve(SafeReserve(globals_count)); |
| @@ -167,7 +176,7 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclDataSegments: { |
| + case WasmSection::Code::DataSegments: { |
| int length; |
| uint32_t data_segments_count = |
| consume_u32v(&length, "data segments count"); |
| @@ -183,9 +192,9 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclFunctionTable: { |
| + case WasmSection::Code::FunctionTable: { |
| // An indirect function table requires functions first. |
| - CheckForPreviousSection(sections, kDeclFunctions, true); |
| + CheckForPreviousSection(sections, WasmSection::Code::Functions, true); |
| int length; |
| uint32_t function_table_count = |
| consume_u32v(&length, "function table count"); |
| @@ -204,9 +213,9 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclStartFunction: { |
| + case WasmSection::Code::StartFunction: { |
| // Declares a start function for a module. |
| - CheckForPreviousSection(sections, kDeclFunctions, true); |
| + CheckForPreviousSection(sections, WasmSection::Code::Functions, true); |
| if (module->start_function_index >= 0) { |
| error("start function already declared"); |
| break; |
| @@ -227,9 +236,9 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclImportTable: { |
| + case WasmSection::Code::ImportTable: { |
| // Declares an import table. |
| - CheckForPreviousSection(sections, kDeclSignatures, true); |
| + CheckForPreviousSection(sections, WasmSection::Code::Signatures, true); |
| int length; |
| uint32_t import_table_count = |
| consume_u32v(&length, "import table count"); |
| @@ -257,9 +266,9 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kDeclExportTable: { |
| + case WasmSection::Code::ExportTable: { |
| // Declares an export table. |
| - CheckForPreviousSection(sections, kDeclFunctions, true); |
| + CheckForPreviousSection(sections, WasmSection::Code::Functions, true); |
| int length; |
| uint32_t export_table_count = |
| consume_u32v(&length, "export table count"); |
| @@ -285,7 +294,7 @@ class ModuleDecoder : public Decoder { |
| } |
| break; |
| } |
| - case kMaxModuleSectionCode: |
| + case WasmSection::Code::Max: |
| UNREACHABLE(); // Already skipped unknown sections. |
| } |
| } |
| @@ -299,38 +308,16 @@ class ModuleDecoder : public Decoder { |
| return count < kMaxReserve ? count : kMaxReserve; |
| } |
| - void CheckForPreviousSection(bool* sections, WasmSectionDeclCode section, |
| + void CheckForPreviousSection(bool* sections, WasmSection::Code section, |
| bool present) { |
| - if (section >= kMaxModuleSectionCode) return; |
| - if (sections[section] == present) return; |
| - const char* name = ""; |
| - switch (section) { |
| - case kDeclMemory: |
| - name = "memory"; |
| - break; |
| - case kDeclSignatures: |
| - name = "signatures"; |
| - break; |
| - case kDeclFunctions: |
| - name = "function declaration"; |
| - break; |
| - case kDeclGlobals: |
| - name = "global variable"; |
| - break; |
| - case kDeclDataSegments: |
| - name = "data segment"; |
| - break; |
| - case kDeclFunctionTable: |
| - name = "function table"; |
| - break; |
| - default: |
| - name = ""; |
| - break; |
| - } |
| + if (section >= WasmSection::Code::Max) return; |
| + if (sections[(size_t)section] == present) return; |
| if (present) { |
| - error(pc_ - 1, nullptr, "required %s section missing", name); |
| + error(pc_ - 1, nullptr, "required %s section missing", |
| + WasmSection::getName(section)); |
| } else { |
| - error(pc_ - 1, nullptr, "%s section already present", name); |
| + error(pc_ - 1, nullptr, "%s section already present", |
| + WasmSection::getName(section)); |
| } |
| } |
| @@ -508,6 +495,27 @@ class ModuleDecoder : public Decoder { |
| return consume_offset(name ? name : "string"); |
| } |
| + // Reads a section name. |
| + WasmSection::Code consume_section_name(uint32_t* string_bytes) { |
| + int length; |
| + *string_bytes = consume_u32v(&length, "name length"); |
| + const byte* start = pc_; |
| + consume_bytes(*string_bytes); |
| + if (failed()) { |
| + TRACE("Section name of length %u couldn't be read\n", *string_bytes); |
| + return WasmSection::Code::Max; |
| + } |
| + for (WasmSection::Code i = WasmSection::begin(); i != WasmSection::end(); |
| + i = WasmSection::next(i)) { |
| + if (WasmSection::getNameLength(i) == *string_bytes && |
|
titzer
2016/03/09 13:19:37
Can you drop in a TODO here? It's a linear search.
JF
2016/03/09 18:51:52
Done.
|
| + 0 == memcmp(WasmSection::getName(i), start, *string_bytes)) { |
| + return i; |
| + } |
| + } |
| + TRACE("Unknown section: '%*s'\n", *string_bytes, start); |
| + return WasmSection::Code::Max; |
| + } |
| + |
| // Reads a single 8-bit integer, interpreting it as a local type. |
| LocalType consume_local_type() { |
| byte val = consume_u8("local type"); |