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