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/flags.h" | 9 #include "src/flags.h" |
10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 "expected version %02x %02x %02x %02x, " | 241 "expected version %02x %02x %02x %02x, " |
242 "found %02x %02x %02x %02x", | 242 "found %02x %02x %02x %02x", |
243 BYTES(kWasmVersion), BYTES(magic_version)); | 243 BYTES(kWasmVersion), BYTES(magic_version)); |
244 } | 244 } |
245 } | 245 } |
246 | 246 |
247 WasmSectionIterator section_iter(*this); | 247 WasmSectionIterator section_iter(*this); |
248 | 248 |
249 // ===== Type section ==================================================== | 249 // ===== Type section ==================================================== |
250 if (section_iter.section_code() == kTypeSectionCode) { | 250 if (section_iter.section_code() == kTypeSectionCode) { |
251 uint32_t signatures_count = consume_u32v("signatures count"); | 251 uint32_t signatures_count = consume_count("types count", kV8MaxWasmTypes); |
252 module->signatures.reserve(SafeReserve(signatures_count)); | 252 module->signatures.reserve(signatures_count); |
253 for (uint32_t i = 0; ok() && i < signatures_count; ++i) { | 253 for (uint32_t i = 0; ok() && i < signatures_count; ++i) { |
254 TRACE("DecodeSignature[%d] module+%d\n", i, | 254 TRACE("DecodeSignature[%d] module+%d\n", i, |
255 static_cast<int>(pc_ - start_)); | 255 static_cast<int>(pc_ - start_)); |
256 FunctionSig* s = consume_sig(); | 256 FunctionSig* s = consume_sig(); |
257 module->signatures.push_back(s); | 257 module->signatures.push_back(s); |
258 } | 258 } |
259 section_iter.advance(); | 259 section_iter.advance(); |
260 } | 260 } |
261 | 261 |
262 // ===== Import section ================================================== | 262 // ===== Import section ================================================== |
263 if (section_iter.section_code() == kImportSectionCode) { | 263 if (section_iter.section_code() == kImportSectionCode) { |
264 uint32_t import_table_count = consume_u32v("import table count"); | 264 uint32_t import_table_count = |
265 module->import_table.reserve(SafeReserve(import_table_count)); | 265 consume_count("imports count", kV8MaxWasmImports); |
| 266 module->import_table.reserve(import_table_count); |
266 for (uint32_t i = 0; ok() && i < import_table_count; ++i) { | 267 for (uint32_t i = 0; ok() && i < import_table_count; ++i) { |
267 TRACE("DecodeImportTable[%d] module+%d\n", i, | 268 TRACE("DecodeImportTable[%d] module+%d\n", i, |
268 static_cast<int>(pc_ - start_)); | 269 static_cast<int>(pc_ - start_)); |
269 | 270 |
270 module->import_table.push_back({ | 271 module->import_table.push_back({ |
271 0, // module_name_length | 272 0, // module_name_length |
272 0, // module_name_offset | 273 0, // module_name_offset |
273 0, // field_name_offset | 274 0, // field_name_offset |
274 0, // field_name_length | 275 0, // field_name_length |
275 kExternalFunction, // kind | 276 kExternalFunction, // kind |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 default: | 346 default: |
346 error(pos, pos, "unknown import kind 0x%02x", import->kind); | 347 error(pos, pos, "unknown import kind 0x%02x", import->kind); |
347 break; | 348 break; |
348 } | 349 } |
349 } | 350 } |
350 section_iter.advance(); | 351 section_iter.advance(); |
351 } | 352 } |
352 | 353 |
353 // ===== Function section ================================================ | 354 // ===== Function section ================================================ |
354 if (section_iter.section_code() == kFunctionSectionCode) { | 355 if (section_iter.section_code() == kFunctionSectionCode) { |
355 uint32_t functions_count = consume_u32v("functions count"); | 356 uint32_t functions_count = |
356 module->functions.reserve(SafeReserve(functions_count)); | 357 consume_count("functions count", kV8MaxWasmFunctions); |
| 358 module->functions.reserve(functions_count); |
357 module->num_declared_functions = functions_count; | 359 module->num_declared_functions = functions_count; |
358 for (uint32_t i = 0; ok() && i < functions_count; ++i) { | 360 for (uint32_t i = 0; ok() && i < functions_count; ++i) { |
359 uint32_t func_index = static_cast<uint32_t>(module->functions.size()); | 361 uint32_t func_index = static_cast<uint32_t>(module->functions.size()); |
360 module->functions.push_back({nullptr, // sig | 362 module->functions.push_back({nullptr, // sig |
361 func_index, // func_index | 363 func_index, // func_index |
362 0, // sig_index | 364 0, // sig_index |
363 0, // name_offset | 365 0, // name_offset |
364 0, // name_length | 366 0, // name_length |
365 0, // code_start_offset | 367 0, // code_start_offset |
366 0, // code_end_offset | 368 0, // code_end_offset |
367 false, // imported | 369 false, // imported |
368 false}); // exported | 370 false}); // exported |
369 WasmFunction* function = &module->functions.back(); | 371 WasmFunction* function = &module->functions.back(); |
370 function->sig_index = consume_sig_index(module, &function->sig); | 372 function->sig_index = consume_sig_index(module, &function->sig); |
371 } | 373 } |
372 section_iter.advance(); | 374 section_iter.advance(); |
373 } | 375 } |
374 | 376 |
375 // ===== Table section =================================================== | 377 // ===== Table section =================================================== |
376 if (section_iter.section_code() == kTableSectionCode) { | 378 if (section_iter.section_code() == kTableSectionCode) { |
377 const byte* pos = pc_; | 379 uint32_t table_count = consume_count("table count", kV8MaxWasmTables); |
378 uint32_t table_count = consume_u32v("table count"); | |
379 // Require at most one table for now. | |
380 if (table_count > 1) { | |
381 error(pos, pos, "invalid table count %d, maximum 1", table_count); | |
382 } | |
383 if (module->function_tables.size() < 1) { | 380 if (module->function_tables.size() < 1) { |
384 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), | 381 module->function_tables.push_back({0, 0, false, std::vector<int32_t>(), |
385 false, false, SignatureMap()}); | 382 false, false, SignatureMap()}); |
386 } | 383 } |
387 | 384 |
388 for (uint32_t i = 0; ok() && i < table_count; i++) { | 385 for (uint32_t i = 0; ok() && i < table_count; i++) { |
389 WasmIndirectFunctionTable* table = &module->function_tables.back(); | 386 WasmIndirectFunctionTable* table = &module->function_tables.back(); |
390 expect_u8("table type", kWasmAnyFunctionTypeForm); | 387 expect_u8("table type", kWasmAnyFunctionTypeForm); |
391 consume_resizable_limits( | 388 consume_resizable_limits( |
392 "table elements", "elements", kV8MaxWasmTableSize, &table->min_size, | 389 "table elements", "elements", kV8MaxWasmTableSize, &table->min_size, |
393 &table->has_max, kV8MaxWasmTableSize, &table->max_size); | 390 &table->has_max, kV8MaxWasmTableSize, &table->max_size); |
394 } | 391 } |
395 section_iter.advance(); | 392 section_iter.advance(); |
396 } | 393 } |
397 | 394 |
398 // ===== Memory section ================================================== | 395 // ===== Memory section ================================================== |
399 if (section_iter.section_code() == kMemorySectionCode) { | 396 if (section_iter.section_code() == kMemorySectionCode) { |
400 const byte* pos = pc_; | 397 uint32_t memory_count = consume_count("memory count", kV8MaxWasmMemories); |
401 uint32_t memory_count = consume_u32v("memory count"); | |
402 // Require at most one memory for now. | |
403 if (memory_count > 1) { | |
404 error(pos, pos, "invalid memory count %d, maximum 1", memory_count); | |
405 } | |
406 | 398 |
407 for (uint32_t i = 0; ok() && i < memory_count; i++) { | 399 for (uint32_t i = 0; ok() && i < memory_count; i++) { |
408 bool has_max = false; | 400 bool has_max = false; |
409 consume_resizable_limits( | 401 consume_resizable_limits( |
410 "memory", "pages", kV8MaxWasmMemoryPages, &module->min_mem_pages, | 402 "memory", "pages", kV8MaxWasmMemoryPages, &module->min_mem_pages, |
411 &has_max, kSpecMaxWasmMemoryPages, &module->max_mem_pages); | 403 &has_max, kSpecMaxWasmMemoryPages, &module->max_mem_pages); |
412 } | 404 } |
413 module->has_memory = true; | 405 module->has_memory = true; |
414 section_iter.advance(); | 406 section_iter.advance(); |
415 } | 407 } |
416 | 408 |
417 // ===== Global section ================================================== | 409 // ===== Global section ================================================== |
418 if (section_iter.section_code() == kGlobalSectionCode) { | 410 if (section_iter.section_code() == kGlobalSectionCode) { |
419 uint32_t globals_count = consume_u32v("globals count"); | 411 uint32_t globals_count = |
| 412 consume_count("globals count", kV8MaxWasmGlobals); |
420 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); | 413 uint32_t imported_globals = static_cast<uint32_t>(module->globals.size()); |
421 if (!IsWithinLimit(std::numeric_limits<int32_t>::max(), globals_count, | 414 module->globals.reserve(imported_globals + globals_count); |
422 imported_globals)) { | |
423 error(pos, pos, "too many imported+defined globals: %u + %u", | |
424 imported_globals, globals_count); | |
425 } | |
426 module->globals.reserve(SafeReserve(imported_globals + globals_count)); | |
427 for (uint32_t i = 0; ok() && i < globals_count; ++i) { | 415 for (uint32_t i = 0; ok() && i < globals_count; ++i) { |
428 TRACE("DecodeGlobal[%d] module+%d\n", i, | 416 TRACE("DecodeGlobal[%d] module+%d\n", i, |
429 static_cast<int>(pc_ - start_)); | 417 static_cast<int>(pc_ - start_)); |
430 // Add an uninitialized global and pass a pointer to it. | 418 // Add an uninitialized global and pass a pointer to it. |
431 module->globals.push_back( | 419 module->globals.push_back( |
432 {kAstStmt, false, WasmInitExpr(), 0, false, false}); | 420 {kAstStmt, false, WasmInitExpr(), 0, false, false}); |
433 WasmGlobal* global = &module->globals.back(); | 421 WasmGlobal* global = &module->globals.back(); |
434 DecodeGlobalInModule(module, i + imported_globals, global); | 422 DecodeGlobalInModule(module, i + imported_globals, global); |
435 } | 423 } |
436 section_iter.advance(); | 424 section_iter.advance(); |
437 } | 425 } |
438 | 426 |
439 // ===== Export section ================================================== | 427 // ===== Export section ================================================== |
440 if (section_iter.section_code() == kExportSectionCode) { | 428 if (section_iter.section_code() == kExportSectionCode) { |
441 uint32_t export_table_count = consume_u32v("export table count"); | 429 uint32_t export_table_count = |
442 module->export_table.reserve(SafeReserve(export_table_count)); | 430 consume_count("exports count", kV8MaxWasmImports); |
| 431 module->export_table.reserve(export_table_count); |
443 for (uint32_t i = 0; ok() && i < export_table_count; ++i) { | 432 for (uint32_t i = 0; ok() && i < export_table_count; ++i) { |
444 TRACE("DecodeExportTable[%d] module+%d\n", i, | 433 TRACE("DecodeExportTable[%d] module+%d\n", i, |
445 static_cast<int>(pc_ - start_)); | 434 static_cast<int>(pc_ - start_)); |
446 | 435 |
447 module->export_table.push_back({ | 436 module->export_table.push_back({ |
448 0, // name_length | 437 0, // name_length |
449 0, // name_offset | 438 0, // name_offset |
450 kExternalFunction, // kind | 439 kExternalFunction, // kind |
451 0 // index | 440 0 // index |
452 }); | 441 }); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 if (func && | 518 if (func && |
530 (func->sig->parameter_count() > 0 || func->sig->return_count() > 0)) { | 519 (func->sig->parameter_count() > 0 || func->sig->return_count() > 0)) { |
531 error(pos, | 520 error(pos, |
532 "invalid start function: non-zero parameter or return count"); | 521 "invalid start function: non-zero parameter or return count"); |
533 } | 522 } |
534 section_iter.advance(); | 523 section_iter.advance(); |
535 } | 524 } |
536 | 525 |
537 // ===== Elements section ================================================ | 526 // ===== Elements section ================================================ |
538 if (section_iter.section_code() == kElementSectionCode) { | 527 if (section_iter.section_code() == kElementSectionCode) { |
539 uint32_t element_count = consume_u32v("element count"); | 528 uint32_t element_count = |
| 529 consume_count("element count", kV8MaxWasmTableSize); |
540 for (uint32_t i = 0; ok() && i < element_count; ++i) { | 530 for (uint32_t i = 0; ok() && i < element_count; ++i) { |
541 const byte* pos = pc(); | 531 const byte* pos = pc(); |
542 uint32_t table_index = consume_u32v("table index"); | 532 uint32_t table_index = consume_u32v("table index"); |
543 if (table_index != 0) { | 533 if (table_index != 0) { |
544 error(pos, pos, "illegal table index %u != 0", table_index); | 534 error(pos, pos, "illegal table index %u != 0", table_index); |
545 } | 535 } |
546 WasmIndirectFunctionTable* table = nullptr; | 536 WasmIndirectFunctionTable* table = nullptr; |
547 if (table_index >= module->function_tables.size()) { | 537 if (table_index >= module->function_tables.size()) { |
548 error(pos, pos, "out of bounds table index %u", table_index); | 538 error(pos, pos, "out of bounds table index %u", table_index); |
549 } else { | 539 } else { |
550 table = &module->function_tables[table_index]; | 540 table = &module->function_tables[table_index]; |
551 } | 541 } |
552 WasmInitExpr offset = consume_init_expr(module, kAstI32); | 542 WasmInitExpr offset = consume_init_expr(module, kAstI32); |
553 uint32_t num_elem = consume_u32v("number of elements"); | 543 uint32_t num_elem = consume_u32v("number of elements"); |
554 std::vector<uint32_t> vector; | 544 std::vector<uint32_t> vector; |
555 module->table_inits.push_back({table_index, offset, vector}); | 545 module->table_inits.push_back({table_index, offset, vector}); |
556 WasmTableInit* init = &module->table_inits.back(); | 546 WasmTableInit* init = &module->table_inits.back(); |
557 init->entries.reserve(SafeReserve(num_elem)); | |
558 for (uint32_t j = 0; ok() && j < num_elem; j++) { | 547 for (uint32_t j = 0; ok() && j < num_elem; j++) { |
559 WasmFunction* func = nullptr; | 548 WasmFunction* func = nullptr; |
560 uint32_t index = consume_func_index(module, &func); | 549 uint32_t index = consume_func_index(module, &func); |
561 init->entries.push_back(index); | 550 init->entries.push_back(index); |
562 if (table && index < module->functions.size()) { | 551 if (table && index < module->functions.size()) { |
563 // Canonicalize signature indices during decoding. | 552 // Canonicalize signature indices during decoding. |
564 // TODO(titzer): suboptimal, redundant when verifying only. | 553 // TODO(titzer): suboptimal, redundant when verifying only. |
565 table->map.FindOrInsert(module->functions[index].sig); | 554 table->map.FindOrInsert(module->functions[index].sig); |
566 } | 555 } |
567 } | 556 } |
(...skipping 22 matching lines...) Expand all Loading... |
590 VerifyFunctionBody(i + module->num_imported_functions, &module_env, | 579 VerifyFunctionBody(i + module->num_imported_functions, &module_env, |
591 function); | 580 function); |
592 } | 581 } |
593 consume_bytes(size, "function body"); | 582 consume_bytes(size, "function body"); |
594 } | 583 } |
595 section_iter.advance(); | 584 section_iter.advance(); |
596 } | 585 } |
597 | 586 |
598 // ===== Data section ==================================================== | 587 // ===== Data section ==================================================== |
599 if (section_iter.section_code() == kDataSectionCode) { | 588 if (section_iter.section_code() == kDataSectionCode) { |
600 uint32_t data_segments_count = consume_u32v("data segments count"); | 589 uint32_t data_segments_count = |
601 module->data_segments.reserve(SafeReserve(data_segments_count)); | 590 consume_count("data segments count", kV8MaxWasmDataSegments); |
| 591 module->data_segments.reserve(data_segments_count); |
602 for (uint32_t i = 0; ok() && i < data_segments_count; ++i) { | 592 for (uint32_t i = 0; ok() && i < data_segments_count; ++i) { |
603 if (!module->has_memory) { | 593 if (!module->has_memory) { |
604 error("cannot load data without memory"); | 594 error("cannot load data without memory"); |
605 break; | 595 break; |
606 } | 596 } |
607 TRACE("DecodeDataSegment[%d] module+%d\n", i, | 597 TRACE("DecodeDataSegment[%d] module+%d\n", i, |
608 static_cast<int>(pc_ - start_)); | 598 static_cast<int>(pc_ - start_)); |
609 module->data_segments.push_back({ | 599 module->data_segments.push_back({ |
610 WasmInitExpr(), // dest_addr | 600 WasmInitExpr(), // dest_addr |
611 0, // source_offset | 601 0, // source_offset |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 } | 639 } |
650 const WasmModule* finished_module = module; | 640 const WasmModule* finished_module = module; |
651 ModuleResult result = toResult(finished_module); | 641 ModuleResult result = toResult(finished_module); |
652 if (verify_functions && result.ok()) { | 642 if (verify_functions && result.ok()) { |
653 result.MoveFrom(result_); // Copy error code and location. | 643 result.MoveFrom(result_); // Copy error code and location. |
654 } | 644 } |
655 if (FLAG_dump_wasm_module) DumpModule(result); | 645 if (FLAG_dump_wasm_module) DumpModule(result); |
656 return result; | 646 return result; |
657 } | 647 } |
658 | 648 |
659 uint32_t SafeReserve(uint32_t count) { | |
660 // Avoid OOM by only reserving up to a certain size. | |
661 const uint32_t kMaxReserve = 20000; | |
662 return count < kMaxReserve ? count : kMaxReserve; | |
663 } | |
664 | |
665 // Decodes a single anonymous function starting at {start_}. | 649 // Decodes a single anonymous function starting at {start_}. |
666 FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env, | 650 FunctionResult DecodeSingleFunction(ModuleBytesEnv* module_env, |
667 WasmFunction* function) { | 651 WasmFunction* function) { |
668 pc_ = start_; | 652 pc_ = start_; |
669 function->sig = consume_sig(); // read signature | 653 function->sig = consume_sig(); // read signature |
670 function->name_offset = 0; // ---- name | 654 function->name_offset = 0; // ---- name |
671 function->name_length = 0; // ---- name length | 655 function->name_length = 0; // ---- name length |
672 function->code_start_offset = off(pc_); // ---- code start | 656 function->code_start_offset = off(pc_); // ---- code start |
673 function->code_end_offset = off(limit_); // ---- code end | 657 function->code_end_offset = off(limit_); // ---- code end |
674 | 658 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 if (sig_index >= module->signatures.size()) { | 815 if (sig_index >= module->signatures.size()) { |
832 error(pos, pos, "signature index %u out of bounds (%d signatures)", | 816 error(pos, pos, "signature index %u out of bounds (%d signatures)", |
833 sig_index, static_cast<int>(module->signatures.size())); | 817 sig_index, static_cast<int>(module->signatures.size())); |
834 *sig = nullptr; | 818 *sig = nullptr; |
835 return 0; | 819 return 0; |
836 } | 820 } |
837 *sig = module->signatures[sig_index]; | 821 *sig = module->signatures[sig_index]; |
838 return sig_index; | 822 return sig_index; |
839 } | 823 } |
840 | 824 |
| 825 uint32_t consume_count(const char* name, size_t maximum) { |
| 826 const byte* p = pc_; |
| 827 uint32_t count = consume_u32v(name); |
| 828 if (count > maximum) { |
| 829 error(p, p, "%s of %u exceeds internal limit of %zu", name, count, |
| 830 maximum); |
| 831 return static_cast<uint32_t>(maximum); |
| 832 } |
| 833 return count; |
| 834 } |
| 835 |
841 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { | 836 uint32_t consume_func_index(WasmModule* module, WasmFunction** func) { |
842 return consume_index("function index", module->functions, func); | 837 return consume_index("function index", module->functions, func); |
843 } | 838 } |
844 | 839 |
845 uint32_t consume_global_index(WasmModule* module, WasmGlobal** global) { | 840 uint32_t consume_global_index(WasmModule* module, WasmGlobal** global) { |
846 return consume_index("global index", module->globals, global); | 841 return consume_index("global index", module->globals, global); |
847 } | 842 } |
848 | 843 |
849 uint32_t consume_table_index(WasmModule* module, | 844 uint32_t consume_table_index(WasmModule* module, |
850 WasmIndirectFunctionTable** table) { | 845 WasmIndirectFunctionTable** table) { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 default: | 1000 default: |
1006 error(pc_ - 1, "invalid local type"); | 1001 error(pc_ - 1, "invalid local type"); |
1007 return kAstStmt; | 1002 return kAstStmt; |
1008 } | 1003 } |
1009 } | 1004 } |
1010 | 1005 |
1011 // Parses a type entry, which is currently limited to functions only. | 1006 // Parses a type entry, which is currently limited to functions only. |
1012 FunctionSig* consume_sig() { | 1007 FunctionSig* consume_sig() { |
1013 if (!expect_u8("type form", kWasmFunctionTypeForm)) return nullptr; | 1008 if (!expect_u8("type form", kWasmFunctionTypeForm)) return nullptr; |
1014 // parse parameter types | 1009 // parse parameter types |
1015 uint32_t param_count = consume_u32v("param count"); | 1010 uint32_t param_count = |
| 1011 consume_count("param count", kV8MaxWasmFunctionParams); |
| 1012 if (failed()) return nullptr; |
1016 std::vector<LocalType> params; | 1013 std::vector<LocalType> params; |
1017 for (uint32_t i = 0; ok() && i < param_count; ++i) { | 1014 for (uint32_t i = 0; ok() && i < param_count; ++i) { |
1018 LocalType param = consume_value_type(); | 1015 LocalType param = consume_value_type(); |
1019 params.push_back(param); | 1016 params.push_back(param); |
1020 } | 1017 } |
1021 | 1018 |
1022 // parse return types | 1019 // parse return types |
1023 const byte* pt = pc_; | 1020 const size_t max_return_count = FLAG_wasm_mv_prototype |
1024 uint32_t return_count = consume_u32v("return count"); | 1021 ? kV8MaxWasmFunctionMultiReturns |
1025 if (return_count > kMaxReturnCount) { | 1022 : kV8MaxWasmFunctionReturns; |
1026 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, | 1023 uint32_t return_count = consume_count("return count", max_return_count); |
1027 kMaxReturnCount); | 1024 if (failed()) return nullptr; |
1028 return nullptr; | |
1029 } | |
1030 std::vector<LocalType> returns; | 1025 std::vector<LocalType> returns; |
1031 for (uint32_t i = 0; ok() && i < return_count; ++i) { | 1026 for (uint32_t i = 0; ok() && i < return_count; ++i) { |
1032 LocalType ret = consume_value_type(); | 1027 LocalType ret = consume_value_type(); |
1033 returns.push_back(ret); | 1028 returns.push_back(ret); |
1034 } | 1029 } |
1035 | 1030 |
1036 if (failed()) { | 1031 if (failed()) return nullptr; |
1037 // Decoding failed, return void -> void | |
1038 return new (module_zone) FunctionSig(0, 0, nullptr); | |
1039 } | |
1040 | 1032 |
1041 // FunctionSig stores the return types first. | 1033 // FunctionSig stores the return types first. |
1042 LocalType* buffer = | 1034 LocalType* buffer = |
1043 module_zone->NewArray<LocalType>(param_count + return_count); | 1035 module_zone->NewArray<LocalType>(param_count + return_count); |
1044 uint32_t b = 0; | 1036 uint32_t b = 0; |
1045 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; | 1037 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; |
1046 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; | 1038 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; |
1047 | 1039 |
1048 return new (module_zone) FunctionSig(return_count, param_count, buffer); | 1040 return new (module_zone) FunctionSig(return_count, param_count, buffer); |
1049 } | 1041 } |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 table.push_back(std::move(func_asm_offsets)); | 1224 table.push_back(std::move(func_asm_offsets)); |
1233 } | 1225 } |
1234 if (decoder.more()) decoder.error("unexpected additional bytes"); | 1226 if (decoder.more()) decoder.error("unexpected additional bytes"); |
1235 | 1227 |
1236 return decoder.toResult(std::move(table)); | 1228 return decoder.toResult(std::move(table)); |
1237 } | 1229 } |
1238 | 1230 |
1239 } // namespace wasm | 1231 } // namespace wasm |
1240 } // namespace internal | 1232 } // namespace internal |
1241 } // namespace v8 | 1233 } // namespace v8 |
OLD | NEW |