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/base/platform/elapsed-timer.h" | 5 #include "src/base/platform/elapsed-timer.h" |
6 #include "src/signature.h" | 6 #include "src/signature.h" |
7 | 7 |
8 #include "src/flags.h" | 8 #include "src/flags.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 error("improperly nested conditional branch"); | 387 error("improperly nested conditional branch"); |
388 } | 388 } |
389 len = 2; | 389 len = 2; |
390 break; | 390 break; |
391 } | 391 } |
392 case kExprTableSwitch: { | 392 case kExprTableSwitch: { |
393 if (!checkAvailable(5)) { | 393 if (!checkAvailable(5)) { |
394 error("expected #tableswitch <cases> <table>, fell off end"); | 394 error("expected #tableswitch <cases> <table>, fell off end"); |
395 break; | 395 break; |
396 } | 396 } |
397 uint16_t case_count = *reinterpret_cast<const uint16_t*>(pc_ + 1); | 397 uint16_t case_count = ReadUnalignedUInt16(pc_ + 1); |
398 uint16_t table_count = *reinterpret_cast<const uint16_t*>(pc_ + 3); | 398 uint16_t table_count = ReadUnalignedUInt16(pc_ + 3); |
399 len = 5 + table_count * 2; | 399 len = 5 + table_count * 2; |
400 | 400 |
401 if (table_count == 0) { | 401 if (table_count == 0) { |
402 error("tableswitch with 0 entries"); | 402 error("tableswitch with 0 entries"); |
403 break; | 403 break; |
404 } | 404 } |
405 | 405 |
406 if (!checkAvailable(len)) { | 406 if (!checkAvailable(len)) { |
407 error("expected #tableswitch <cases> <table>, fell off end"); | 407 error("expected #tableswitch <cases> <table>, fell off end"); |
408 break; | 408 break; |
409 } | 409 } |
410 | 410 |
411 Shift(kAstEnd, 1 + case_count); | 411 Shift(kAstEnd, 1 + case_count); |
412 | 412 |
413 // Verify table. | 413 // Verify table. |
414 for (int i = 0; i < table_count; i++) { | 414 for (int i = 0; i < table_count; i++) { |
415 uint16_t target = | 415 uint16_t target = ReadUnalignedUInt16(pc_ + 5 + i * 2); |
416 *reinterpret_cast<const uint16_t*>(pc_ + 5 + i * 2); | 416 |
417 if (target >= 0x8000) { | 417 if (target >= 0x8000) { |
418 size_t depth = target - 0x8000; | 418 size_t depth = target - 0x8000; |
419 if (depth > blocks_.size()) { | 419 if (depth > blocks_.size()) { |
420 error(pc_ + 5 + i * 2, "improper branch in tableswitch"); | 420 error(pc_ + 5 + i * 2, "improper branch in tableswitch"); |
421 } | 421 } |
422 } else { | 422 } else { |
423 if (target >= case_count) { | 423 if (target >= case_count) { |
424 error(pc_ + 5 + i * 2, "invalid case target in tableswitch"); | 424 error(pc_ + 5 + i * 2, "invalid case target in tableswitch"); |
425 } | 425 } |
426 } | 426 } |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 SsaEnv* tenv = Split(fenv); | 798 SsaEnv* tenv = Split(fenv); |
799 BUILD(Branch, p->tree->children[0]->node, &tenv->control, | 799 BUILD(Branch, p->tree->children[0]->node, &tenv->control, |
800 &fenv->control); | 800 &fenv->control); |
801 ssa_env_ = tenv; | 801 ssa_env_ = tenv; |
802 ReduceBreakToExprBlock(p, block); | 802 ReduceBreakToExprBlock(p, block); |
803 ssa_env_ = fenv; | 803 ssa_env_ = fenv; |
804 } | 804 } |
805 break; | 805 break; |
806 } | 806 } |
807 case kExprTableSwitch: { | 807 case kExprTableSwitch: { |
808 uint16_t table_count = *reinterpret_cast<const uint16_t*>(p->pc() + 3); | 808 uint16_t table_count = ReadUnalignedUInt16(p->pc() + 3); |
809 if (table_count == 1) { | 809 if (table_count == 1) { |
810 // Degenerate switch with only a default target. | 810 // Degenerate switch with only a default target. |
811 if (p->index == 1) { | 811 if (p->index == 1) { |
812 SsaEnv* break_env = ssa_env_; | 812 SsaEnv* break_env = ssa_env_; |
813 PushBlock(break_env); | 813 PushBlock(break_env); |
814 SetEnv("switch:default", Steal(break_env)); | 814 SetEnv("switch:default", Steal(break_env)); |
815 } | 815 } |
816 if (p->done()) { | 816 if (p->done()) { |
817 Block* block = &blocks_.back(); | 817 Block* block = &blocks_.back(); |
818 // fall through to the end. | 818 // fall through to the end. |
819 ReduceBreakToExprBlock(p, block); | 819 ReduceBreakToExprBlock(p, block); |
820 SetEnv("switch:end", block->ssa_env); | 820 SetEnv("switch:end", block->ssa_env); |
821 blocks_.pop_back(); | 821 blocks_.pop_back(); |
822 } | 822 } |
823 break; | 823 break; |
824 } | 824 } |
825 | 825 |
826 if (p->index == 1) { | 826 if (p->index == 1) { |
827 // Switch key finished. | 827 // Switch key finished. |
828 TypeCheckLast(p, kAstI32); | 828 TypeCheckLast(p, kAstI32); |
829 | 829 |
830 TFNode* sw = BUILD(Switch, table_count, p->last()->node); | 830 TFNode* sw = BUILD(Switch, table_count, p->last()->node); |
831 | 831 |
832 // Allocate environments for each case. | 832 // Allocate environments for each case. |
833 uint16_t case_count = *reinterpret_cast<const uint16_t*>(p->pc() + 1); | 833 uint16_t case_count = ReadUnalignedUInt16(p->pc() + 1); |
834 SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(case_count); | 834 SsaEnv** case_envs = zone_->NewArray<SsaEnv*>(case_count); |
835 for (int i = 0; i < case_count; i++) { | 835 for (int i = 0; i < case_count; i++) { |
836 case_envs[i] = UnreachableEnv(); | 836 case_envs[i] = UnreachableEnv(); |
837 } | 837 } |
838 | 838 |
839 ifs_.push_back({nullptr, nullptr, case_envs}); | 839 ifs_.push_back({nullptr, nullptr, case_envs}); |
840 SsaEnv* break_env = ssa_env_; | 840 SsaEnv* break_env = ssa_env_; |
841 PushBlock(break_env); | 841 PushBlock(break_env); |
842 SsaEnv* copy = Steal(break_env); | 842 SsaEnv* copy = Steal(break_env); |
843 ssa_env_ = copy; | 843 ssa_env_ = copy; |
844 | 844 |
845 // Build the environments for each case based on the table. | 845 // Build the environments for each case based on the table. |
846 const uint16_t* table = | 846 const uint16_t* table = |
847 reinterpret_cast<const uint16_t*>(p->pc() + 5); | 847 reinterpret_cast<const uint16_t*>(p->pc() + 5); |
848 for (int i = 0; i < table_count; i++) { | 848 for (int i = 0; i < table_count; i++) { |
849 uint16_t target = table[i]; | 849 uint16_t target = ReadUnalignedUInt16(table + i); |
850 SsaEnv* env = Split(copy); | 850 SsaEnv* env = Split(copy); |
851 env->control = (i == table_count - 1) ? BUILD(IfDefault, sw) | 851 env->control = (i == table_count - 1) ? BUILD(IfDefault, sw) |
852 : BUILD(IfValue, i, sw); | 852 : BUILD(IfValue, i, sw); |
853 if (target >= 0x8000) { | 853 if (target >= 0x8000) { |
854 // Targets an outer block. | 854 // Targets an outer block. |
855 int depth = target - 0x8000; | 855 int depth = target - 0x8000; |
856 SsaEnv* tenv = blocks_[blocks_.size() - depth - 1].ssa_env; | 856 SsaEnv* tenv = blocks_[blocks_.size() - depth - 1].ssa_env; |
857 Goto(env, tenv); | 857 Goto(env, tenv); |
858 } else { | 858 } else { |
859 // Targets a case. | 859 // Targets a case. |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 break; | 1300 break; |
1301 case 4: | 1301 case 4: |
1302 msg = "Expected 4-byte operand following opcode"; | 1302 msg = "Expected 4-byte operand following opcode"; |
1303 break; | 1303 break; |
1304 default: | 1304 default: |
1305 break; | 1305 break; |
1306 } | 1306 } |
1307 error(pc, msg); | 1307 error(pc, msg); |
1308 return -1; | 1308 return -1; |
1309 } | 1309 } |
1310 return *reinterpret_cast<const V*>(pc + 1); | 1310 return ReadUnalignedValue<V>(pc + 1); |
1311 } | 1311 } |
1312 | 1312 |
1313 int EnvironmentCount() { | 1313 int EnvironmentCount() { |
1314 if (builder_) return static_cast<int>(function_env_->GetLocalCount()); | 1314 if (builder_) return static_cast<int>(function_env_->GetLocalCount()); |
1315 return 0; // if we aren't building a graph, don't bother with SSA renaming. | 1315 return 0; // if we aren't building a graph, don't bother with SSA renaming. |
1316 } | 1316 } |
1317 | 1317 |
1318 LocalType LocalOperand(const byte* pc, uint32_t* index, int* length) { | 1318 LocalType LocalOperand(const byte* pc, uint32_t* index, int* length) { |
1319 *index = UnsignedLEB128Operand(pc, length); | 1319 *index = UnsignedLEB128Operand(pc, length); |
1320 if (function_env_->IsValidLocal(*index)) { | 1320 if (function_env_->IsValidLocal(*index)) { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 case kExprLoadGlobal: | 1495 case kExprLoadGlobal: |
1496 case kExprCallFunction: | 1496 case kExprCallFunction: |
1497 case kExprCallIndirect: | 1497 case kExprCallIndirect: |
1498 case kExprGetLocal: { | 1498 case kExprGetLocal: { |
1499 int length; | 1499 int length; |
1500 uint32_t result = 0; | 1500 uint32_t result = 0; |
1501 ReadUnsignedLEB128Operand(pc + 1, pc + 6, &length, &result); | 1501 ReadUnsignedLEB128Operand(pc + 1, pc + 6, &length, &result); |
1502 return 1 + length; | 1502 return 1 + length; |
1503 } | 1503 } |
1504 case kExprTableSwitch: { | 1504 case kExprTableSwitch: { |
1505 uint16_t table_count = *reinterpret_cast<const uint16_t*>(pc + 3); | 1505 uint16_t table_count = ReadUnalignedUInt16(pc + 3); |
1506 return 5 + table_count * 2; | 1506 return 5 + table_count * 2; |
1507 } | 1507 } |
1508 | 1508 |
1509 default: | 1509 default: |
1510 return 1; | 1510 return 1; |
1511 } | 1511 } |
1512 } | 1512 } |
1513 | 1513 |
1514 | 1514 |
1515 int OpcodeArity(FunctionEnv* env, const byte* pc) { | 1515 int OpcodeArity(FunctionEnv* env, const byte* pc) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE) | 1574 FOREACH_MISC_MEM_OPCODE(DECLARE_OPCODE_CASE) |
1575 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE) | 1575 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE) |
1576 #undef DECLARE_OPCODE_CASE | 1576 #undef DECLARE_OPCODE_CASE |
1577 } | 1577 } |
1578 UNREACHABLE(); | 1578 UNREACHABLE(); |
1579 return 0; | 1579 return 0; |
1580 } | 1580 } |
1581 } // namespace wasm | 1581 } // namespace wasm |
1582 } // namespace internal | 1582 } // namespace internal |
1583 } // namespace v8 | 1583 } // namespace v8 |
OLD | NEW |