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