Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/wasm/module-decoder.h" | 5 #include "src/wasm/module-decoder.h" |
| 6 | 6 |
| 7 #include "src/base/functional.h" | 7 #include "src/base/functional.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| 11 #include "src/v8.h" | 11 #include "src/v8.h" |
| 12 | 12 |
| 13 #include "src/wasm/decoder.h" | 13 #include "src/wasm/decoder.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 namespace wasm { | 17 namespace wasm { |
| 18 | 18 |
| 19 #if DEBUG | 19 #if DEBUG |
| 20 #define TRACE(...) \ | 20 #define TRACE(...) \ |
| 21 do { \ | 21 do { \ |
| 22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 22 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
| 23 } while (false) | 23 } while (false) |
| 24 #else | 24 #else |
| 25 #define TRACE(...) | 25 #define TRACE(...) |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 | |
| 29 // The main logic for decoding the bytes of a module. | 28 // The main logic for decoding the bytes of a module. |
| 30 class ModuleDecoder : public Decoder { | 29 class ModuleDecoder : public Decoder { |
| 31 public: | 30 public: |
| 32 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, | 31 ModuleDecoder(Zone* zone, const byte* module_start, const byte* module_end, |
| 33 ModuleOrigin origin) | 32 ModuleOrigin origin) |
| 34 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { | 33 : Decoder(module_start, module_end), module_zone(zone), origin_(origin) { |
| 35 result_.start = start_; | 34 result_.start = start_; |
| 36 if (limit_ < start_) { | 35 if (limit_ < start_) { |
| 37 error(start_, "end is less than start"); | 36 error(start_, "end is less than start"); |
| 38 limit_ = start_; | 37 limit_ = start_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { | 71 ModuleResult DecodeModule(WasmModule* module, bool verify_functions = true) { |
| 73 pc_ = start_; | 72 pc_ = start_; |
| 74 module->module_start = start_; | 73 module->module_start = start_; |
| 75 module->module_end = limit_; | 74 module->module_end = limit_; |
| 76 module->min_mem_pages = 0; | 75 module->min_mem_pages = 0; |
| 77 module->max_mem_pages = 0; | 76 module->max_mem_pages = 0; |
| 78 module->mem_export = false; | 77 module->mem_export = false; |
| 79 module->mem_external = false; | 78 module->mem_external = false; |
| 80 module->origin = origin_; | 79 module->origin = origin_; |
| 81 | 80 |
| 82 bool sections[(size_t)WasmSection::Code::Max] = {false}; | |
| 83 | |
| 84 const byte* pos = pc_; | 81 const byte* pos = pc_; |
| 82 int current_order = 0; | |
| 85 uint32_t magic_word = consume_u32("wasm magic"); | 83 uint32_t magic_word = consume_u32("wasm magic"); |
| 86 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff | 84 #define BYTES(x) (x & 0xff), (x >> 8) & 0xff, (x >> 16) & 0xff, (x >> 24) & 0xff |
| 87 if (magic_word != kWasmMagic) { | 85 if (magic_word != kWasmMagic) { |
| 88 error(pos, pos, | 86 error(pos, pos, |
| 89 "expected magic word %02x %02x %02x %02x, " | 87 "expected magic word %02x %02x %02x %02x, " |
| 90 "found %02x %02x %02x %02x", | 88 "found %02x %02x %02x %02x", |
| 91 BYTES(kWasmMagic), BYTES(magic_word)); | 89 BYTES(kWasmMagic), BYTES(magic_word)); |
| 92 goto done; | 90 goto done; |
| 93 } | 91 } |
| 94 | 92 |
| 95 pos = pc_; | 93 pos = pc_; |
| 96 { | 94 { |
| 97 uint32_t magic_version = consume_u32("wasm version"); | 95 uint32_t magic_version = consume_u32("wasm version"); |
| 98 if (magic_version != kWasmVersion) { | 96 if (magic_version != kWasmVersion) { |
| 99 error(pos, pos, | 97 error(pos, pos, |
| 100 "expected version %02x %02x %02x %02x, " | 98 "expected version %02x %02x %02x %02x, " |
| 101 "found %02x %02x %02x %02x", | 99 "found %02x %02x %02x %02x", |
| 102 BYTES(kWasmVersion), BYTES(magic_version)); | 100 BYTES(kWasmVersion), BYTES(magic_version)); |
| 103 goto done; | 101 goto done; |
| 104 } | 102 } |
| 105 } | 103 } |
| 106 | 104 |
| 107 // Decode the module sections. | 105 // Decode the module sections. |
| 108 while (pc_ < limit_) { | 106 while (pc_ < limit_) { |
| 109 TRACE("DecodeSection\n"); | 107 TRACE("DecodeSection\n"); |
| 110 pos = pc_; | 108 pos = pc_; |
| 111 | 109 |
| 112 int length; | 110 // Read and check the section size. |
| 113 uint32_t section_length = consume_u32v(&length, "section size"); | 111 int section_leb_length = 0; |
| 114 | 112 uint32_t section_length = |
| 115 int section_string_leb_length = 0; | 113 consume_u32v(§ion_leb_length, "section length"); |
| 116 uint32_t section_string_length = 0; | 114 if (!checkAvailable(section_length)) { |
| 117 WasmSection::Code section = consume_section_name( | 115 // The section would extend beyond the end of the module. |
| 118 §ion_string_leb_length, §ion_string_length); | |
| 119 uint32_t string_and_leb_length = | |
| 120 section_string_leb_length + section_string_length; | |
| 121 if (string_and_leb_length > section_length) { | |
| 122 error(pos, pos, | |
| 123 "section string of size %u longer than total section bytes %u", | |
| 124 string_and_leb_length, section_length); | |
| 125 break; | 116 break; |
| 126 } | 117 } |
| 118 const byte* section_start = pc_; | |
| 119 const byte* expected_section_end = pc_ + section_length; | |
| 127 | 120 |
| 128 if (section == WasmSection::Code::Max) { | 121 // Read the section name. |
| 129 // Skip unknown section. | 122 int string_leb_length = 0; |
| 130 uint32_t skip = section_length - string_and_leb_length; | 123 uint32_t string_length = |
| 131 TRACE("skipping %u bytes from unknown section\n", skip); | 124 consume_u32v(&string_leb_length, "section name length"); |
| 132 consume_bytes(skip); | 125 const byte* section_name_start = pc_; |
| 133 continue; | 126 consume_bytes(string_length); |
| 127 if (failed()) { | |
| 128 TRACE("Section name of length %u couldn't be read\n", string_length); | |
| 129 break; | |
| 130 } | |
| 131 if (pc_ > expected_section_end) { | |
| 132 error(section_name_start, pc_, | |
| 133 "section name string %u longer than total section bytes %u", | |
| 134 string_length, section_length); | |
| 134 } | 135 } |
| 135 | 136 |
| 136 // Each section should appear at most once. | 137 WasmSection::Code section = |
| 137 CheckForPreviousSection(sections, section, false); | 138 WasmSection::lookup(section_name_start, string_length); |
| 138 sections[(size_t)section] = true; | 139 |
| 140 current_order = CheckSectionOrder(current_order, section); | |
| 139 | 141 |
| 140 switch (section) { | 142 switch (section) { |
| 141 case WasmSection::Code::End: | 143 case WasmSection::Code::End: |
| 142 // Terminate section decoding. | 144 // Terminate section decoding. |
| 143 limit_ = pc_; | 145 limit_ = pc_; |
| 144 break; | 146 break; |
| 145 case WasmSection::Code::Memory: | 147 case WasmSection::Code::Memory: |
| 146 int length; | 148 int length; |
| 147 module->min_mem_pages = consume_u32v(&length, "min memory"); | 149 module->min_mem_pages = consume_u32v(&length, "min memory"); |
| 148 module->max_mem_pages = consume_u32v(&length, "max memory"); | 150 module->max_mem_pages = consume_u32v(&length, "max memory"); |
| 149 module->mem_export = consume_u8("export memory") != 0; | 151 module->mem_export = consume_u8("export memory") != 0; |
| 150 break; | 152 break; |
| 151 case WasmSection::Code::Signatures: { | 153 case WasmSection::Code::Signatures: { |
| 152 int length; | 154 int length; |
| 153 uint32_t signatures_count = consume_u32v(&length, "signatures count"); | 155 uint32_t signatures_count = consume_u32v(&length, "signatures count"); |
| 154 module->signatures.reserve(SafeReserve(signatures_count)); | 156 module->signatures.reserve(SafeReserve(signatures_count)); |
| 155 // Decode signatures. | 157 // Decode signatures. |
| 156 for (uint32_t i = 0; i < signatures_count; i++) { | 158 for (uint32_t i = 0; i < signatures_count; i++) { |
| 157 if (failed()) break; | 159 if (failed()) break; |
| 158 TRACE("DecodeSignature[%d] module+%d\n", i, | 160 TRACE("DecodeSignature[%d] module+%d\n", i, |
| 159 static_cast<int>(pc_ - start_)); | 161 static_cast<int>(pc_ - start_)); |
| 160 FunctionSig* s = consume_sig(); // read function sig. | 162 FunctionSig* s = consume_sig(); // read function sig. |
| 161 module->signatures.push_back(s); | 163 module->signatures.push_back(s); |
| 162 } | 164 } |
| 163 break; | 165 break; |
| 164 } | 166 } |
| 165 case WasmSection::Code::FunctionSignatures: { | 167 case WasmSection::Code::FunctionSignatures: { |
| 166 // Functions require a signature table first. | |
| 167 CheckForPreviousSection(sections, WasmSection::Code::Signatures, | |
| 168 true); | |
| 169 int length; | 168 int length; |
| 170 uint32_t functions_count = consume_u32v(&length, "functions count"); | 169 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 171 module->functions.reserve(SafeReserve(functions_count)); | 170 module->functions.reserve(SafeReserve(functions_count)); |
| 172 for (uint32_t i = 0; i < functions_count; i++) { | 171 for (uint32_t i = 0; i < functions_count; i++) { |
| 173 module->functions.push_back( | 172 module->functions.push_back( |
| 174 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); | 173 {nullptr, i, 0, 0, 0, 0, 0, 0, false, false}); |
| 175 WasmFunction* function = &module->functions.back(); | 174 WasmFunction* function = &module->functions.back(); |
| 176 function->sig_index = consume_sig_index(module, &function->sig); | 175 function->sig_index = consume_sig_index(module, &function->sig); |
| 177 } | 176 } |
| 178 break; | 177 break; |
| 179 } | 178 } |
| 180 case WasmSection::Code::FunctionBodies: { | 179 case WasmSection::Code::FunctionBodies: { |
| 181 // Function bodies should follow signatures. | |
| 182 CheckForPreviousSection(sections, | |
| 183 WasmSection::Code::FunctionSignatures, true); | |
| 184 int length; | 180 int length; |
| 185 const byte* pos = pc_; | 181 const byte* pos = pc_; |
| 186 uint32_t functions_count = consume_u32v(&length, "functions count"); | 182 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 187 if (functions_count != module->functions.size()) { | 183 if (functions_count != module->functions.size()) { |
| 188 error(pos, pos, "function body count %u mismatch (%u expected)", | 184 error(pos, pos, "function body count %u mismatch (%u expected)", |
| 189 functions_count, | 185 functions_count, |
| 190 static_cast<uint32_t>(module->functions.size())); | 186 static_cast<uint32_t>(module->functions.size())); |
| 191 break; | 187 break; |
| 192 } | 188 } |
| 193 for (uint32_t i = 0; i < functions_count; i++) { | 189 for (uint32_t i = 0; i < functions_count; i++) { |
| 194 WasmFunction* function = &module->functions[i]; | 190 WasmFunction* function = &module->functions[i]; |
| 195 int length; | 191 int length; |
| 196 uint32_t size = consume_u32v(&length, "body size"); | 192 uint32_t size = consume_u32v(&length, "body size"); |
| 197 function->code_start_offset = pc_offset(); | 193 function->code_start_offset = pc_offset(); |
| 198 function->code_end_offset = pc_offset() + size; | 194 function->code_end_offset = pc_offset() + size; |
| 199 | 195 |
| 200 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", | 196 TRACE(" +%d %-20s: (%d bytes)\n", pc_offset(), "function body", |
| 201 size); | 197 size); |
| 202 pc_ += size; | 198 pc_ += size; |
| 203 if (pc_ > limit_) { | 199 if (pc_ > limit_) { |
| 204 error(pc_, "function body extends beyond end of file"); | 200 error(pc_, "function body extends beyond end of file"); |
| 205 } | 201 } |
| 206 } | 202 } |
| 207 break; | 203 break; |
| 208 } | 204 } |
| 209 case WasmSection::Code::Functions: { | 205 case WasmSection::Code::Functions: { |
| 210 // Functions require a signature table first. | |
| 211 CheckForPreviousSection(sections, WasmSection::Code::Signatures, | |
| 212 true); | |
| 213 int length; | 206 int length; |
| 214 uint32_t functions_count = consume_u32v(&length, "functions count"); | 207 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 215 module->functions.reserve(SafeReserve(functions_count)); | 208 module->functions.reserve(SafeReserve(functions_count)); |
| 216 // Set up module environment for verification. | 209 // Set up module environment for verification. |
| 217 ModuleEnv menv; | 210 ModuleEnv menv; |
| 218 menv.module = module; | 211 menv.module = module; |
| 219 menv.instance = nullptr; | 212 menv.instance = nullptr; |
| 220 menv.origin = origin_; | 213 menv.origin = origin_; |
| 221 // Decode functions. | 214 // Decode functions. |
| 222 for (uint32_t i = 0; i < functions_count; i++) { | 215 for (uint32_t i = 0; i < functions_count; i++) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 236 if (!function->external) { | 229 if (!function->external) { |
| 237 VerifyFunctionBody(i, &menv, function); | 230 VerifyFunctionBody(i, &menv, function); |
| 238 if (result_.failed()) | 231 if (result_.failed()) |
| 239 error(result_.error_pc, result_.error_msg.get()); | 232 error(result_.error_pc, result_.error_msg.get()); |
| 240 } | 233 } |
| 241 } | 234 } |
| 242 } | 235 } |
| 243 break; | 236 break; |
| 244 } | 237 } |
| 245 case WasmSection::Code::Names: { | 238 case WasmSection::Code::Names: { |
| 246 // Names correspond to functions. | |
| 247 CheckForPreviousSection(sections, | |
| 248 WasmSection::Code::FunctionSignatures, true); | |
| 249 int length; | 239 int length; |
| 250 const byte* pos = pc_; | 240 const byte* pos = pc_; |
| 251 uint32_t functions_count = consume_u32v(&length, "functions count"); | 241 uint32_t functions_count = consume_u32v(&length, "functions count"); |
| 252 if (functions_count != module->functions.size()) { | 242 if (functions_count != module->functions.size()) { |
| 253 error(pos, pos, "function name count %u mismatch (%u expected)", | 243 error(pos, pos, "function name count %u mismatch (%u expected)", |
| 254 functions_count, | 244 functions_count, |
| 255 static_cast<uint32_t>(module->functions.size())); | 245 static_cast<uint32_t>(module->functions.size())); |
| 256 break; | 246 break; |
| 257 } | 247 } |
| 258 | 248 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 334 WasmFunction* func; | 324 WasmFunction* func; |
| 335 const byte* pos = pc_; | 325 const byte* pos = pc_; |
| 336 module->start_function_index = consume_func_index(module, &func); | 326 module->start_function_index = consume_func_index(module, &func); |
| 337 if (func && func->sig->parameter_count() > 0) { | 327 if (func && func->sig->parameter_count() > 0) { |
| 338 error(pos, "invalid start function: non-zero parameter count"); | 328 error(pos, "invalid start function: non-zero parameter count"); |
| 339 break; | 329 break; |
| 340 } | 330 } |
| 341 break; | 331 break; |
| 342 } | 332 } |
| 343 case WasmSection::Code::ImportTable: { | 333 case WasmSection::Code::ImportTable: { |
| 344 // Declares an import table. | |
| 345 CheckForPreviousSection(sections, WasmSection::Code::Signatures, | |
| 346 true); | |
| 347 int length; | 334 int length; |
| 348 uint32_t import_table_count = | 335 uint32_t import_table_count = |
| 349 consume_u32v(&length, "import table count"); | 336 consume_u32v(&length, "import table count"); |
| 350 module->import_table.reserve(SafeReserve(import_table_count)); | 337 module->import_table.reserve(SafeReserve(import_table_count)); |
| 351 // Decode import table. | 338 // Decode import table. |
| 352 for (uint32_t i = 0; i < import_table_count; i++) { | 339 for (uint32_t i = 0; i < import_table_count; i++) { |
| 353 if (failed()) break; | 340 if (failed()) break; |
| 354 TRACE("DecodeImportTable[%d] module+%d\n", i, | 341 TRACE("DecodeImportTable[%d] module+%d\n", i, |
| 355 static_cast<int>(pc_ - start_)); | 342 static_cast<int>(pc_ - start_)); |
| 356 | 343 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 385 module->export_table.push_back({0, 0}); | 372 module->export_table.push_back({0, 0}); |
| 386 WasmExport* exp = &module->export_table.back(); | 373 WasmExport* exp = &module->export_table.back(); |
| 387 | 374 |
| 388 WasmFunction* func; | 375 WasmFunction* func; |
| 389 exp->func_index = consume_func_index(module, &func); | 376 exp->func_index = consume_func_index(module, &func); |
| 390 exp->name_offset = consume_string(&exp->name_length, "export name"); | 377 exp->name_offset = consume_string(&exp->name_length, "export name"); |
| 391 } | 378 } |
| 392 break; | 379 break; |
| 393 } | 380 } |
| 394 case WasmSection::Code::Max: | 381 case WasmSection::Code::Max: |
| 395 UNREACHABLE(); // Already skipped unknown sections. | 382 // Skip unknown sections. |
| 383 TRACE("Unknown section: '"); | |
| 384 for (uint32_t i = 0; i != string_length; ++i) { | |
| 385 TRACE("%c", *(section_name_start + i)); | |
| 386 } | |
| 387 TRACE("'\n"); | |
| 388 consume_bytes(section_length - string_length - string_leb_length); | |
| 389 break; | |
| 390 } | |
| 391 | |
| 392 if (pc_ != expected_section_end) { | |
| 393 const char* diff = pc_ < expected_section_end ? "shorter" : "longer"; | |
| 394 size_t expected_length = static_cast<size_t>(section_length); | |
| 395 size_t actual_length = static_cast<size_t>(pc_ - section_start); | |
| 396 error(pc_, pc_, | |
| 397 "section \"%s\" %s (%zu bytes) than specified (%zu bytes)", | |
| 398 WasmSection::getName(section), diff, actual_length, | |
| 399 expected_length); | |
|
JF
2016/04/20 17:59:54
If section is Code::Max then it'll print a slightl
titzer
2016/04/21 10:59:22
Acknowledged.
| |
| 400 break; | |
| 396 } | 401 } |
| 397 } | 402 } |
| 398 | 403 |
| 399 done: | 404 done: |
| 400 ModuleResult result = toResult(module); | 405 ModuleResult result = toResult(module); |
| 401 if (FLAG_dump_wasm_module) { | 406 if (FLAG_dump_wasm_module) { |
| 402 DumpModule(module, result); | 407 DumpModule(module, result); |
| 403 } | 408 } |
| 404 return result; | 409 return result; |
| 405 } | 410 } |
| 406 | 411 |
| 407 uint32_t SafeReserve(uint32_t count) { | 412 uint32_t SafeReserve(uint32_t count) { |
| 408 // Avoid OOM by only reserving up to a certain size. | 413 // Avoid OOM by only reserving up to a certain size. |
| 409 const uint32_t kMaxReserve = 20000; | 414 const uint32_t kMaxReserve = 20000; |
| 410 return count < kMaxReserve ? count : kMaxReserve; | 415 return count < kMaxReserve ? count : kMaxReserve; |
| 411 } | 416 } |
| 412 | 417 |
| 413 void CheckForFunctions(WasmModule* module, WasmSection::Code section) { | 418 void CheckForFunctions(WasmModule* module, WasmSection::Code section) { |
| 414 if (module->functions.size() == 0) { | 419 if (module->functions.size() == 0) { |
| 415 error(pc_ - 1, nullptr, "functions must appear before section %s", | 420 error(pc_ - 1, nullptr, "functions must appear before section %s", |
| 416 WasmSection::getName(section)); | 421 WasmSection::getName(section)); |
| 417 } | 422 } |
| 418 } | 423 } |
| 419 | 424 |
| 420 void CheckForPreviousSection(bool* sections, WasmSection::Code section, | 425 int CheckSectionOrder(int current_order, WasmSection::Code section) { |
| 421 bool present) { | 426 if (section == WasmSection::Code::Max) return current_order; |
| 422 if (section >= WasmSection::Code::Max) return; | 427 int next_order = WasmSection::getOrder(section); |
| 423 if (sections[(size_t)section] == present) return; | 428 if (next_order == 0) return current_order; |
| 424 if (present) { | 429 if (next_order == current_order) { |
| 425 error(pc_ - 1, nullptr, "required %s section missing", | 430 error(pc_, pc_, "section \"%s\" already defined", |
| 426 WasmSection::getName(section)); | |
| 427 } else { | |
| 428 error(pc_ - 1, nullptr, "%s section already present", | |
| 429 WasmSection::getName(section)); | 431 WasmSection::getName(section)); |
| 430 } | 432 } |
| 433 if (next_order < current_order) { | |
| 434 error(pc_, pc_, "section \"%s\" out of order", | |
| 435 WasmSection::getName(section)); | |
| 436 } | |
| 437 return next_order; | |
| 431 } | 438 } |
| 432 | 439 |
| 433 // Decodes a single anonymous function starting at {start_}. | 440 // Decodes a single anonymous function starting at {start_}. |
| 434 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, | 441 FunctionResult DecodeSingleFunction(ModuleEnv* module_env, |
| 435 WasmFunction* function) { | 442 WasmFunction* function) { |
| 436 pc_ = start_; | 443 pc_ = start_; |
| 437 function->sig = consume_sig(); // read signature | 444 function->sig = consume_sig(); // read signature |
| 438 function->name_offset = 0; // ---- name | 445 function->name_offset = 0; // ---- name |
| 439 function->name_length = 0; // ---- name length | 446 function->name_length = 0; // ---- name length |
| 440 function->code_start_offset = off(pc_); // ---- code start | 447 function->code_start_offset = off(pc_); // ---- code start |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 if (func_index >= module->functions.size()) { | 643 if (func_index >= module->functions.size()) { |
| 637 error(pos, pos, "function index %u out of bounds (%d functions)", | 644 error(pos, pos, "function index %u out of bounds (%d functions)", |
| 638 func_index, static_cast<int>(module->functions.size())); | 645 func_index, static_cast<int>(module->functions.size())); |
| 639 *func = nullptr; | 646 *func = nullptr; |
| 640 return 0; | 647 return 0; |
| 641 } | 648 } |
| 642 *func = &module->functions[func_index]; | 649 *func = &module->functions[func_index]; |
| 643 return func_index; | 650 return func_index; |
| 644 } | 651 } |
| 645 | 652 |
| 646 // Reads a section name. | |
| 647 WasmSection::Code consume_section_name(int* string_leb_length, | |
| 648 uint32_t* string_length) { | |
| 649 *string_length = consume_u32v(string_leb_length, "name length"); | |
| 650 const byte* start = pc_; | |
| 651 consume_bytes(*string_length); | |
| 652 if (failed()) { | |
| 653 TRACE("Section name of length %u couldn't be read\n", *string_length); | |
| 654 return WasmSection::Code::Max; | |
| 655 } | |
| 656 // TODO(jfb) Linear search, it may be better to do a common-prefix search. | |
| 657 for (WasmSection::Code i = WasmSection::begin(); i != WasmSection::end(); | |
| 658 i = WasmSection::next(i)) { | |
| 659 if (WasmSection::getNameLength(i) == *string_length && | |
| 660 0 == memcmp(WasmSection::getName(i), start, *string_length)) { | |
| 661 return i; | |
| 662 } | |
| 663 } | |
| 664 TRACE("Unknown section: '"); | |
| 665 for (uint32_t i = 0; i != *string_length; ++i) TRACE("%c", *(start + i)); | |
| 666 TRACE("'\n"); | |
| 667 return WasmSection::Code::Max; | |
| 668 } | |
| 669 | |
| 670 // Reads a single 8-bit integer, interpreting it as a local type. | 653 // Reads a single 8-bit integer, interpreting it as a local type. |
| 671 LocalType consume_local_type() { | 654 LocalType consume_local_type() { |
| 672 byte val = consume_u8("local type"); | 655 byte val = consume_u8("local type"); |
| 673 LocalTypeCode t = static_cast<LocalTypeCode>(val); | 656 LocalTypeCode t = static_cast<LocalTypeCode>(val); |
| 674 switch (t) { | 657 switch (t) { |
| 675 case kLocalVoid: | 658 case kLocalVoid: |
| 676 return kAstStmt; | 659 return kAstStmt; |
| 677 case kLocalI32: | 660 case kLocalI32: |
| 678 return kAstI32; | 661 return kAstI32; |
| 679 case kLocalI64: | 662 case kLocalI64: |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 return FunctionError("size > maximum function size"); | 787 return FunctionError("size > maximum function size"); |
| 805 isolate->counters()->wasm_function_size_bytes()->AddSample( | 788 isolate->counters()->wasm_function_size_bytes()->AddSample( |
| 806 static_cast<int>(size)); | 789 static_cast<int>(size)); |
| 807 WasmFunction* function = new WasmFunction(); | 790 WasmFunction* function = new WasmFunction(); |
| 808 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); | 791 ModuleDecoder decoder(zone, function_start, function_end, kWasmOrigin); |
| 809 return decoder.DecodeSingleFunction(module_env, function); | 792 return decoder.DecodeSingleFunction(module_env, function); |
| 810 } | 793 } |
| 811 } // namespace wasm | 794 } // namespace wasm |
| 812 } // namespace internal | 795 } // namespace internal |
| 813 } // namespace v8 | 796 } // namespace v8 |
| OLD | NEW |