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