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" |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 0, // source_size | 253 0, // source_size |
254 false}); // init | 254 false}); // init |
255 WasmDataSegment* segment = &module->data_segments.back(); | 255 WasmDataSegment* segment = &module->data_segments.back(); |
256 DecodeDataSegmentInModule(module, segment); | 256 DecodeDataSegmentInModule(module, segment); |
257 } | 257 } |
258 break; | 258 break; |
259 } | 259 } |
260 case WasmSection::Code::FunctionTable: { | 260 case WasmSection::Code::FunctionTable: { |
261 // An indirect function table requires functions first. | 261 // An indirect function table requires functions first. |
262 CheckForFunctions(module, section); | 262 CheckForFunctions(module, section); |
263 // Assume only one table for now. | 263 uint32_t table_count = consume_u32v("function table count"); |
264 static const uint32_t kSupportedTableCount = 1; | 264 module->function_tables.reserve(SafeReserve(table_count)); |
265 module->function_tables.reserve(SafeReserve(kSupportedTableCount)); | |
266 // Decode function table. | 265 // Decode function table. |
267 for (uint32_t i = 0; i < kSupportedTableCount; ++i) { | 266 for (uint32_t i = 0; i < table_count; ++i) { |
268 if (failed()) break; | 267 if (failed()) break; |
269 TRACE("DecodeFunctionTable[%d] module+%d\n", i, | 268 TRACE("DecodeFunctionTable[%d] module+%d\n", i, |
270 static_cast<int>(pc_ - start_)); | 269 static_cast<int>(pc_ - start_)); |
271 module->function_tables.push_back({0, 0, std::vector<uint16_t>()}); | 270 module->function_tables.push_back( |
272 DecodeFunctionTableInModule(module, &module->function_tables[i]); | 271 {!i, // default |
| 272 nullptr, // sig |
| 273 0, // sig_index |
| 274 0, // size |
| 275 0, // max_size |
| 276 std::vector<uint16_t>()}); // vals |
| 277 DecodeFunctionTableInModule(module, |
| 278 &module->function_tables.back()); |
273 } | 279 } |
274 break; | 280 break; |
275 } | 281 } |
276 case WasmSection::Code::StartFunction: { | 282 case WasmSection::Code::StartFunction: { |
277 // Declares a start function for a module. | 283 // Declares a start function for a module. |
278 CheckForFunctions(module, section); | 284 CheckForFunctions(module, section); |
279 if (module->start_function_index >= 0) { | 285 if (module->start_function_index >= 0) { |
280 error("start function already declared"); | 286 error("start function already declared"); |
281 break; | 287 break; |
282 } | 288 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 segment->source_size)) { | 505 segment->source_size)) { |
500 error(start, "segment out of bounds of memory"); | 506 error(start, "segment out of bounds of memory"); |
501 } | 507 } |
502 | 508 |
503 consume_bytes(segment->source_size); | 509 consume_bytes(segment->source_size); |
504 } | 510 } |
505 | 511 |
506 // Decodes a single function table inside a module starting at {pc_}. | 512 // Decodes a single function table inside a module starting at {pc_}. |
507 void DecodeFunctionTableInModule(WasmModule* module, | 513 void DecodeFunctionTableInModule(WasmModule* module, |
508 WasmIndirectFunctionTable* table) { | 514 WasmIndirectFunctionTable* table) { |
| 515 table->isDefault = consume_u8("default"); |
| 516 if (table->isDefault && module->function_tables.size() > 1) { |
| 517 error("invalid default flag"); |
| 518 } |
| 519 table->sig_index = consume_sig_index(module, &table->sig); |
| 520 |
509 table->size = consume_u32v("function table entry count"); | 521 table->size = consume_u32v("function table entry count"); |
510 table->max_size = table->size; | 522 table->max_size = consume_u32v(); |
511 | 523 |
512 if (table->max_size != table->size) { | 524 if (table->max_size != table->size) { |
513 error("invalid table maximum size"); | 525 error("invalid table maximum size"); |
514 } | 526 } |
515 | 527 |
516 for (uint32_t i = 0; i < table->size; ++i) { | 528 for (uint32_t i = 0; i < table->size; ++i) { |
517 uint16_t index = consume_u32v(); | 529 uint16_t index = consume_u32v(); |
518 if (index >= module->functions.size()) { | 530 if (index >= module->functions.size()) { |
519 error(pc_ - sizeof(index), "invalid function index"); | 531 error(pc_ - sizeof(index), "invalid function index"); |
520 break; | 532 break; |
521 } | 533 } |
| 534 if (!isAnyFuncType(table->sig) && |
| 535 module->functions[index].sig != table->sig) { |
| 536 error("invalid function signature type"); |
| 537 break; |
| 538 } |
522 table->values.push_back(index); | 539 table->values.push_back(index); |
523 } | 540 } |
524 } | 541 } |
525 | 542 |
526 // Calculate individual global offsets and total size of globals table. | 543 // Calculate individual global offsets and total size of globals table. |
527 void CalculateGlobalsOffsets(WasmModule* module) { | 544 void CalculateGlobalsOffsets(WasmModule* module) { |
528 uint32_t offset = 0; | 545 uint32_t offset = 0; |
529 if (module->globals.size() == 0) { | 546 if (module->globals.size() == 0) { |
530 module->globals_size = 0; | 547 module->globals_size = 0; |
531 return; | 548 return; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 if (form != kWasmFunctionTypeForm) { | 664 if (form != kWasmFunctionTypeForm) { |
648 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", | 665 error(pos, pos, "expected function type form (0x%02x), got: 0x%02x", |
649 kWasmFunctionTypeForm, form); | 666 kWasmFunctionTypeForm, form); |
650 return nullptr; | 667 return nullptr; |
651 } | 668 } |
652 // parse parameter types | 669 // parse parameter types |
653 uint32_t param_count = consume_u32v("param count"); | 670 uint32_t param_count = consume_u32v("param count"); |
654 std::vector<LocalType> params; | 671 std::vector<LocalType> params; |
655 for (uint32_t i = 0; i < param_count; ++i) { | 672 for (uint32_t i = 0; i < param_count; ++i) { |
656 LocalType param = consume_local_type(); | 673 LocalType param = consume_local_type(); |
657 if (param == kAstStmt) error(pc_ - 1, "invalid void parameter type"); | 674 if (param == kAstStmt && i) error(pc_ - 1, "invalid void parameter type"); |
658 params.push_back(param); | 675 params.push_back(param); |
659 } | 676 } |
660 | 677 |
661 // parse return types | 678 // parse return types |
662 const byte* pt = pc_; | 679 const byte* pt = pc_; |
663 uint32_t return_count = consume_u32v("return count"); | 680 uint32_t return_count = consume_u32v("return count"); |
664 if (return_count > kMaxReturnCount) { | 681 if (return_count > kMaxReturnCount) { |
665 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, | 682 error(pt, pt, "return count of %u exceeds maximum of %u", return_count, |
666 kMaxReturnCount); | 683 kMaxReturnCount); |
667 return nullptr; | 684 return nullptr; |
668 } | 685 } |
669 std::vector<LocalType> returns; | 686 std::vector<LocalType> returns; |
670 for (uint32_t i = 0; i < return_count; ++i) { | 687 for (uint32_t i = 0; i < return_count; ++i) { |
671 LocalType ret = consume_local_type(); | 688 LocalType ret = consume_local_type(); |
672 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); | 689 if (ret == kAstStmt) error(pc_ - 1, "invalid void return type"); |
673 returns.push_back(ret); | 690 returns.push_back(ret); |
674 } | 691 } |
675 | 692 |
| 693 // Check if a parameter is kAstStmt but it is not the special kAnyFunc type |
| 694 if (param_count == 1 && params[0] == kAstStmt && return_count != 0) |
| 695 error(pc_ - 1, "invalid void parameter type"); |
| 696 |
676 // FunctionSig stores the return types first. | 697 // FunctionSig stores the return types first. |
677 LocalType* buffer = | 698 LocalType* buffer = |
678 module_zone->NewArray<LocalType>(param_count + return_count); | 699 module_zone->NewArray<LocalType>(param_count + return_count); |
679 uint32_t b = 0; | 700 uint32_t b = 0; |
680 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; | 701 for (uint32_t i = 0; i < return_count; ++i) buffer[b++] = returns[i]; |
681 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; | 702 for (uint32_t i = 0; i < param_count; ++i) buffer[b++] = params[i]; |
682 | 703 |
683 return new (module_zone) FunctionSig(return_count, param_count, buffer); | 704 return new (module_zone) FunctionSig(return_count, param_count, buffer); |
684 } | 705 } |
685 }; | 706 }; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 decoder.consume_bytes(size); | 832 decoder.consume_bytes(size); |
812 } | 833 } |
813 if (decoder.more()) decoder.error("unexpected additional bytes"); | 834 if (decoder.more()) decoder.error("unexpected additional bytes"); |
814 | 835 |
815 return decoder.toResult(std::move(table)); | 836 return decoder.toResult(std::move(table)); |
816 } | 837 } |
817 | 838 |
818 } // namespace wasm | 839 } // namespace wasm |
819 } // namespace internal | 840 } // namespace internal |
820 } // namespace v8 | 841 } // namespace v8 |
OLD | NEW |