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/signature.h" | 5 #include "src/signature.h" |
6 | 6 |
7 #include "src/bit-vector.h" | 7 #include "src/bit-vector.h" |
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 } | 61 } |
62 }; | 62 }; |
63 | 63 |
64 // An entry on the value stack. | 64 // An entry on the value stack. |
65 struct Value { | 65 struct Value { |
66 const byte* pc; | 66 const byte* pc; |
67 TFNode* node; | 67 TFNode* node; |
68 LocalType type; | 68 LocalType type; |
69 }; | 69 }; |
70 | 70 |
71 // An entry on the control stack (i.e. if, block, loop). | 71 struct Control; |
| 72 |
| 73 // An entry on the control stack (i.e. if, block, loop, try). |
72 struct Control { | 74 struct Control { |
73 const byte* pc; | 75 const byte* pc; |
74 int stack_depth; // stack height at the beginning of the construct. | 76 int stack_depth; // stack height at the beginning of the construct. |
75 SsaEnv* end_env; // end environment for the construct. | 77 SsaEnv* end_env; // end environment for the construct. |
76 SsaEnv* false_env; // false environment (only for if). | 78 SsaEnv* false_env; // false environment (only for if). |
77 SsaEnv* catch_env; // catch environment (only for try with catch). | 79 SsaEnv* catch_env; // catch environment (only for try). |
78 SsaEnv* finish_try_env; // the environment where a try with finally lives. | 80 TFNode* node; // result node for the construct. |
79 TFNode* node; // result node for the construct. | 81 LocalType type; // result type for the construct. |
80 LocalType type; // result type for the construct. | 82 bool is_loop; // true if this is the inner label of a loop. |
81 bool is_loop; // true if this is the inner label of a loop. | |
82 | 83 |
83 bool is_if() const { return *pc == kExprIf; } | 84 bool is_if() const { return *pc == kExprIf; } |
84 | 85 |
85 bool is_try() const { | 86 bool is_try() const { return *pc == kExprTry; } |
86 return *pc == kExprTryCatch || *pc == kExprTryCatchFinally || | |
87 *pc == kExprTryFinally; | |
88 } | |
89 | |
90 bool has_catch() const { | |
91 return *pc == kExprTryCatch || *pc == kExprTryCatchFinally; | |
92 } | |
93 | |
94 bool has_finally() const { | |
95 return *pc == kExprTryCatchFinally || *pc == kExprTryFinally; | |
96 } | |
97 | 87 |
98 // Named constructors. | 88 // Named constructors. |
99 static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env) { | 89 static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env) { |
100 return {pc, stack_depth, end_env, nullptr, nullptr, | 90 return {pc, stack_depth, end_env, nullptr, |
101 nullptr, nullptr, kAstEnd, false}; | 91 nullptr, nullptr, kAstEnd, false}; |
102 } | 92 } |
103 | 93 |
104 static Control If(const byte* pc, int stack_depth, SsaEnv* end_env, | 94 static Control If(const byte* pc, int stack_depth, SsaEnv* end_env, |
105 SsaEnv* false_env) { | 95 SsaEnv* false_env) { |
106 return {pc, stack_depth, end_env, false_env, nullptr, | 96 return {pc, stack_depth, end_env, false_env, |
107 nullptr, nullptr, kAstStmt, false}; | 97 nullptr, nullptr, kAstStmt, false}; |
108 } | 98 } |
109 | 99 |
110 static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env) { | 100 static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env) { |
111 return {pc, stack_depth, end_env, nullptr, nullptr, | 101 return {pc, stack_depth, end_env, nullptr, nullptr, nullptr, kAstEnd, true}; |
112 nullptr, nullptr, kAstEnd, true}; | |
113 } | 102 } |
114 | 103 |
115 static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env, | 104 static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env, |
116 SsaEnv* catch_env, SsaEnv* finish_try_env) { | 105 SsaEnv* catch_env) { |
117 return {pc, stack_depth, end_env, nullptr, catch_env, finish_try_env, | 106 return {pc, stack_depth, end_env, nullptr, |
118 nullptr, kAstEnd, false}; | 107 catch_env, nullptr, kAstEnd, false}; |
119 } | 108 } |
120 }; | 109 }; |
121 | 110 |
122 // Macros that build nodes only if there is a graph and the current SSA | 111 // Macros that build nodes only if there is a graph and the current SSA |
123 // environment is reachable from start. This avoids problems with malformed | 112 // environment is reachable from start. This avoids problems with malformed |
124 // TF graphs when decoding inputs that have unreachable code. | 113 // TF graphs when decoding inputs that have unreachable code. |
125 #define BUILD(func, ...) (build() ? builder_->func(__VA_ARGS__) : nullptr) | 114 #define BUILD(func, ...) (build() ? builder_->func(__VA_ARGS__) : nullptr) |
126 #define BUILD0(func) (build() ? builder_->func() : nullptr) | 115 #define BUILD0(func) (build() ? builder_->func() : nullptr) |
127 | 116 |
128 // Generic Wasm bytecode decoder with utilities for decoding operands, | 117 // Generic Wasm bytecode decoder with utilities for decoding operands, |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 case kExprI64Const: | 270 case kExprI64Const: |
282 case kExprF64Const: | 271 case kExprF64Const: |
283 case kExprF32Const: | 272 case kExprF32Const: |
284 case kExprGetLocal: | 273 case kExprGetLocal: |
285 case kExprGetGlobal: | 274 case kExprGetGlobal: |
286 case kExprNop: | 275 case kExprNop: |
287 case kExprUnreachable: | 276 case kExprUnreachable: |
288 case kExprEnd: | 277 case kExprEnd: |
289 case kExprBlock: | 278 case kExprBlock: |
290 case kExprThrow: | 279 case kExprThrow: |
291 case kExprTryCatch: | 280 case kExprTry: |
292 case kExprTryCatchFinally: | |
293 case kExprTryFinally: | |
294 case kExprFinally: | |
295 case kExprLoop: | 281 case kExprLoop: |
296 return 0; | 282 return 0; |
297 | 283 |
298 case kExprSetGlobal: | 284 case kExprSetGlobal: |
299 case kExprSetLocal: | 285 case kExprSetLocal: |
300 case kExprElse: | 286 case kExprElse: |
301 case kExprCatch: | 287 case kExprCatch: |
302 return 1; | 288 return 1; |
303 | 289 |
304 case kExprBr: { | 290 case kExprBr: { |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 SetEnv("block:start", Steal(break_env)); | 665 SetEnv("block:start", Steal(break_env)); |
680 break; | 666 break; |
681 } | 667 } |
682 case kExprThrow: { | 668 case kExprThrow: { |
683 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | 669 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
684 Pop(0, kAstI32); | 670 Pop(0, kAstI32); |
685 | 671 |
686 // TODO(jpp): start exception propagation. | 672 // TODO(jpp): start exception propagation. |
687 break; | 673 break; |
688 } | 674 } |
689 case kExprTryCatch: { | 675 case kExprTry: { |
690 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | 676 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
691 SsaEnv* outer_env = ssa_env_; | 677 SsaEnv* outer_env = ssa_env_; |
692 SsaEnv* try_env = Steal(outer_env); | 678 SsaEnv* try_env = Steal(outer_env); |
693 SsaEnv* catch_env = Split(try_env); | 679 SsaEnv* catch_env = Split(try_env); |
694 PushTry(outer_env, catch_env, nullptr); | 680 PushTry(outer_env, catch_env); |
695 SetEnv("try_catch:start", try_env); | 681 SetEnv("try:start", try_env); |
696 break; | |
697 } | |
698 case kExprTryCatchFinally: { | |
699 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | |
700 SsaEnv* outer_env = ssa_env_; | |
701 SsaEnv* try_env = Steal(outer_env); | |
702 SsaEnv* catch_env = Split(try_env); | |
703 SsaEnv* finally_env = Split(try_env); | |
704 PushTry(finally_env, catch_env, outer_env); | |
705 SetEnv("try_catch_finally:start", try_env); | |
706 break; | |
707 } | |
708 case kExprTryFinally: { | |
709 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | |
710 SsaEnv* outer_env = ssa_env_; | |
711 SsaEnv* try_env = Steal(outer_env); | |
712 SsaEnv* finally_env = Split(outer_env); | |
713 PushTry(finally_env, nullptr, outer_env); | |
714 SetEnv("try_finally:start", try_env); | |
715 break; | 682 break; |
716 } | 683 } |
717 case kExprCatch: { | 684 case kExprCatch: { |
718 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | 685 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); |
719 LocalIndexOperand operand(this, pc_); | 686 LocalIndexOperand operand(this, pc_); |
720 len = 1 + operand.length; | 687 len = 1 + operand.length; |
721 | 688 |
722 if (control_.empty()) { | 689 if (control_.empty()) { |
723 error(pc_, "catch does not match a any try"); | 690 error(pc_, "catch does not match a any try"); |
724 break; | 691 break; |
725 } | 692 } |
726 | 693 |
727 Control* c = &control_.back(); | 694 Control* c = &control_.back(); |
728 if (!c->has_catch()) { | 695 if (!c->is_try()) { |
729 error(pc_, "catch does not match a try with catch"); | 696 error(pc_, "catch does not match a try"); |
730 break; | 697 break; |
731 } | 698 } |
732 | 699 |
733 if (c->catch_env == nullptr) { | 700 if (c->catch_env == nullptr) { |
734 error(pc_, "catch already present for try with catch"); | 701 error(pc_, "catch already present for try with catch"); |
735 break; | 702 break; |
736 } | 703 } |
737 | 704 |
738 Goto(ssa_env_, c->end_env); | 705 Goto(ssa_env_, c->end_env); |
739 | 706 |
740 SsaEnv* catch_env = c->catch_env; | 707 SsaEnv* catch_env = c->catch_env; |
741 c->catch_env = nullptr; | 708 c->catch_env = nullptr; |
742 SetEnv("catch:begin", catch_env); | 709 SetEnv("catch:begin", catch_env); |
743 | 710 |
744 if (Validate(pc_, operand)) { | 711 if (Validate(pc_, operand)) { |
745 // TODO(jpp): figure out how thrown value is propagated. It is | 712 // TODO(jpp): figure out how thrown value is propagated. It is |
746 // unlikely to be a value on the stack. | 713 // unlikely to be a value on the stack. |
747 if (ssa_env_->locals) { | 714 if (ssa_env_->locals) { |
748 ssa_env_->locals[operand.index] = nullptr; | 715 ssa_env_->locals[operand.index] = nullptr; |
749 } | 716 } |
750 } | 717 } |
751 | 718 |
752 PopUpTo(c->stack_depth); | 719 PopUpTo(c->stack_depth); |
753 | 720 |
754 break; | 721 break; |
755 } | 722 } |
756 case kExprFinally: { | |
757 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); | |
758 if (control_.empty()) { | |
759 error(pc_, "finally does not match a any try"); | |
760 break; | |
761 } | |
762 | |
763 Control* c = &control_.back(); | |
764 if (c->has_catch() && c->catch_env != nullptr) { | |
765 error(pc_, "missing catch for try with catch and finally"); | |
766 break; | |
767 } | |
768 | |
769 if (!c->has_finally()) { | |
770 error(pc_, "finally does not match a try with finally"); | |
771 break; | |
772 } | |
773 | |
774 if (c->finish_try_env == nullptr) { | |
775 error(pc_, "finally already present for try with finally"); | |
776 break; | |
777 } | |
778 | |
779 // ssa_env_ is either the env for either the try or the catch, but | |
780 // it does not matter: either way we need to direct the control flow | |
781 // to the end_env, which is the env for the finally. | |
782 // c->finish_try_env is the the environment enclosing the try block. | |
783 Goto(ssa_env_, c->end_env); | |
784 | |
785 PopUpTo(c->stack_depth); | |
786 | |
787 // The current environment becomes end_env, and finish_try_env | |
788 // becomes the new end_env. This ensures that any control flow | |
789 // leaving a try block up to now will do so by branching to the | |
790 // finally block. Setting the end_env to be finish_try_env ensures | |
791 // that kExprEnd below can handle the try block as it would any | |
792 // other block construct. | |
793 SsaEnv* finally_env = c->end_env; | |
794 c->end_env = c->finish_try_env; | |
795 SetEnv("finally:begin", finally_env); | |
796 c->finish_try_env = nullptr; | |
797 | |
798 break; | |
799 } | |
800 case kExprLoop: { | 723 case kExprLoop: { |
801 // The break environment is the outer environment. | 724 // The break environment is the outer environment. |
802 SsaEnv* break_env = ssa_env_; | 725 SsaEnv* break_env = ssa_env_; |
803 PushBlock(break_env); | 726 PushBlock(break_env); |
804 SsaEnv* finish_try_env = Steal(break_env); | 727 SsaEnv* finish_try_env = Steal(break_env); |
805 // The continue environment is the inner environment. | 728 // The continue environment is the inner environment. |
806 PrepareForLoop(pc_, finish_try_env); | 729 PrepareForLoop(pc_, finish_try_env); |
807 SetEnv("loop:start", Split(finish_try_env)); | 730 SetEnv("loop:start", Split(finish_try_env)); |
808 ssa_env_->SetNotMerged(); | 731 ssa_env_->SetNotMerged(); |
809 PushLoop(finish_try_env); | 732 PushLoop(finish_try_env); |
(...skipping 30 matching lines...) Expand all Loading... |
840 } | 763 } |
841 Value val = PopUpTo(c->stack_depth); | 764 Value val = PopUpTo(c->stack_depth); |
842 MergeInto(c->end_env, &c->node, &c->type, val); | 765 MergeInto(c->end_env, &c->node, &c->type, val); |
843 // Switch to environment for false branch. | 766 // Switch to environment for false branch. |
844 SetEnv("if_else:false", c->false_env); | 767 SetEnv("if_else:false", c->false_env); |
845 c->false_env = nullptr; // record that an else is already seen | 768 c->false_env = nullptr; // record that an else is already seen |
846 break; | 769 break; |
847 } | 770 } |
848 case kExprEnd: { | 771 case kExprEnd: { |
849 if (control_.empty()) { | 772 if (control_.empty()) { |
850 error(pc_, "end does not match any if or block"); | 773 error(pc_, "end does not match any if, try, or block"); |
851 break; | 774 break; |
852 } | 775 } |
853 const char* name = "block:end"; | 776 const char* name = "block:end"; |
854 Control* c = &control_.back(); | 777 Control* c = &control_.back(); |
855 Value val = PopUpTo(c->stack_depth); | 778 Value val = PopUpTo(c->stack_depth); |
856 if (c->is_loop) { | 779 if (c->is_loop) { |
857 // Loops always push control in pairs. | 780 // Loops always push control in pairs. |
858 control_.pop_back(); | 781 PopControl(); |
859 c = &control_.back(); | 782 c = &control_.back(); |
860 name = "loop:end"; | 783 name = "loop:end"; |
861 } else if (c->is_if()) { | 784 } else if (c->is_if()) { |
862 if (c->false_env != nullptr) { | 785 if (c->false_env != nullptr) { |
863 // End the true branch of a one-armed if. | 786 // End the true branch of a one-armed if. |
864 Goto(c->false_env, c->end_env); | 787 Goto(c->false_env, c->end_env); |
865 val = {val.pc, nullptr, kAstStmt}; | 788 val = {val.pc, nullptr, kAstStmt}; |
866 name = "if:merge"; | 789 name = "if:merge"; |
867 } else { | 790 } else { |
868 // End the false branch of a two-armed if. | 791 // End the false branch of a two-armed if. |
869 name = "if_else:merge"; | 792 name = "if_else:merge"; |
870 } | 793 } |
871 } else if (c->is_try()) { | 794 } else if (c->is_try()) { |
872 name = "try:end"; | 795 name = "try:end"; |
873 | 796 |
874 // try blocks do not yield a value. | 797 // validate that catch was seen. |
875 val = {val.pc, nullptr, kAstStmt}; | |
876 | |
877 // validate that catch/finally were seen. | |
878 if (c->catch_env != nullptr) { | 798 if (c->catch_env != nullptr) { |
879 error(pc_, "missing catch in try with catch"); | 799 error(pc_, "missing catch in try"); |
880 break; | |
881 } | |
882 | |
883 if (c->finish_try_env != nullptr) { | |
884 error(pc_, "missing finally in try with finally"); | |
885 break; | 800 break; |
886 } | 801 } |
887 } | 802 } |
888 | 803 |
889 if (ssa_env_->go()) { | 804 if (ssa_env_->go()) { |
| 805 // Adds a fallthrough edge to the next control block. |
890 MergeInto(c->end_env, &c->node, &c->type, val); | 806 MergeInto(c->end_env, &c->node, &c->type, val); |
891 } | 807 } |
892 SetEnv(name, c->end_env); | 808 SetEnv(name, c->end_env); |
893 stack_.resize(c->stack_depth); | 809 stack_.resize(c->stack_depth); |
894 Push(c->type, c->node); | 810 Push(c->type, c->node); |
895 control_.pop_back(); | 811 PopControl(); |
896 break; | 812 break; |
897 } | 813 } |
898 case kExprSelect: { | 814 case kExprSelect: { |
899 Value cond = Pop(2, kAstI32); | 815 Value cond = Pop(2, kAstI32); |
900 Value fval = Pop(); | 816 Value fval = Pop(); |
901 Value tval = Pop(); | 817 Value tval = Pop(); |
902 if (tval.type == kAstStmt || tval.type != fval.type) { | 818 if (tval.type == kAstStmt || tval.type != fval.type) { |
903 if (tval.type != kAstEnd && fval.type != kAstEnd) { | 819 if (tval.type != kAstEnd && fval.type != kAstEnd) { |
904 error(pc_, "type mismatch in select"); | 820 error(pc_, "type mismatch in select"); |
905 break; | 821 break; |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 void PushLoop(SsaEnv* end_env) { | 1202 void PushLoop(SsaEnv* end_env) { |
1287 const int stack_depth = static_cast<int>(stack_.size()); | 1203 const int stack_depth = static_cast<int>(stack_.size()); |
1288 control_.emplace_back(Control::Loop(pc_, stack_depth, end_env)); | 1204 control_.emplace_back(Control::Loop(pc_, stack_depth, end_env)); |
1289 } | 1205 } |
1290 | 1206 |
1291 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { | 1207 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { |
1292 const int stack_depth = static_cast<int>(stack_.size()); | 1208 const int stack_depth = static_cast<int>(stack_.size()); |
1293 control_.emplace_back(Control::If(pc_, stack_depth, end_env, false_env)); | 1209 control_.emplace_back(Control::If(pc_, stack_depth, end_env, false_env)); |
1294 } | 1210 } |
1295 | 1211 |
1296 void PushTry(SsaEnv* end_env, SsaEnv* catch_env, SsaEnv* finish_try_env) { | 1212 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { |
1297 const int stack_depth = static_cast<int>(stack_.size()); | 1213 const int stack_depth = static_cast<int>(stack_.size()); |
1298 control_.emplace_back( | 1214 control_.emplace_back(Control::Try(pc_, stack_depth, end_env, catch_env)); |
1299 Control::Try(pc_, stack_depth, end_env, catch_env, finish_try_env)); | |
1300 } | 1215 } |
1301 | 1216 |
| 1217 void PopControl() { control_.pop_back(); } |
| 1218 |
1302 int DecodeLoadMem(LocalType type, MachineType mem_type) { | 1219 int DecodeLoadMem(LocalType type, MachineType mem_type) { |
1303 MemoryAccessOperand operand(this, pc_, | 1220 MemoryAccessOperand operand(this, pc_, |
1304 ElementSizeLog2Of(mem_type.representation())); | 1221 ElementSizeLog2Of(mem_type.representation())); |
1305 | 1222 |
1306 Value index = Pop(0, kAstI32); | 1223 Value index = Pop(0, kAstI32); |
1307 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, | 1224 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, |
1308 operand.alignment, position()); | 1225 operand.alignment, position()); |
1309 Push(type, node); | 1226 Push(type, node); |
1310 return 1 + operand.length; | 1227 return 1 + operand.length; |
1311 } | 1228 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 return val; | 1329 return val; |
1413 } | 1330 } |
1414 } | 1331 } |
1415 | 1332 |
1416 int baserel(const byte* ptr) { | 1333 int baserel(const byte* ptr) { |
1417 return base_ ? static_cast<int>(ptr - base_) : 0; | 1334 return base_ ? static_cast<int>(ptr - base_) : 0; |
1418 } | 1335 } |
1419 | 1336 |
1420 int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); } | 1337 int startrel(const byte* ptr) { return static_cast<int>(ptr - start_); } |
1421 | 1338 |
1422 void BreakTo(Control* block, Value& val) { | 1339 void BreakTo(Control* block, const Value& val) { |
1423 if (block->is_loop) { | 1340 if (block->is_loop) { |
1424 // This is the inner loop block, which does not have a value. | 1341 // This is the inner loop block, which does not have a value. |
1425 Goto(ssa_env_, block->end_env); | 1342 Goto(ssa_env_, block->end_env); |
1426 } else { | 1343 } else { |
1427 // Merge the value into the production for the block. | 1344 // Merge the value into the production for the block. |
1428 MergeInto(block->end_env, &block->node, &block->type, val); | 1345 MergeInto(block->end_env, &block->node, &block->type, val); |
1429 } | 1346 } |
1430 } | 1347 } |
1431 | 1348 |
1432 void MergeInto(SsaEnv* target, TFNode** node, LocalType* type, Value& val) { | 1349 void MergeInto(SsaEnv* target, TFNode** node, LocalType* type, |
| 1350 const Value& val) { |
1433 if (!ssa_env_->go()) return; | 1351 if (!ssa_env_->go()) return; |
1434 DCHECK_NE(kAstEnd, val.type); | 1352 DCHECK_NE(kAstEnd, val.type); |
1435 | 1353 |
1436 bool first = target->state == SsaEnv::kUnreachable; | 1354 bool first = target->state == SsaEnv::kUnreachable; |
1437 Goto(ssa_env_, target); | 1355 Goto(ssa_env_, target); |
1438 | 1356 |
1439 if (first) { | 1357 if (first) { |
1440 // first merge to this environment; set the type and the node. | 1358 // first merge to this environment; set the type and the node. |
1441 *type = val.type; | 1359 *type = val.type; |
1442 *node = val.node; | 1360 *node = val.node; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_); | 1585 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_); |
1668 int depth = 0; | 1586 int depth = 0; |
1669 // Iteratively process all AST nodes nested inside the loop. | 1587 // Iteratively process all AST nodes nested inside the loop. |
1670 while (pc < limit_ && ok()) { | 1588 while (pc < limit_ && ok()) { |
1671 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); | 1589 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); |
1672 unsigned length = 1; | 1590 unsigned length = 1; |
1673 switch (opcode) { | 1591 switch (opcode) { |
1674 case kExprLoop: | 1592 case kExprLoop: |
1675 case kExprIf: | 1593 case kExprIf: |
1676 case kExprBlock: | 1594 case kExprBlock: |
1677 case kExprTryCatch: | 1595 case kExprTry: |
1678 case kExprTryCatchFinally: | |
1679 case kExprTryFinally: | |
1680 depth++; | 1596 depth++; |
1681 DCHECK_EQ(1, OpcodeLength(pc)); | 1597 DCHECK_EQ(1, OpcodeLength(pc)); |
1682 break; | 1598 break; |
1683 case kExprSetLocal: { | 1599 case kExprSetLocal: { |
1684 LocalIndexOperand operand(this, pc); | 1600 LocalIndexOperand operand(this, pc); |
1685 if (assigned->length() > 0 && | 1601 if (assigned->length() > 0 && |
1686 operand.index < static_cast<uint32_t>(assigned->length())) { | 1602 operand.index < static_cast<uint32_t>(assigned->length())) { |
1687 // Unverified code might have an out-of-bounds index. | 1603 // Unverified code might have an out-of-bounds index. |
1688 assigned->Add(operand.index); | 1604 assigned->Add(operand.index); |
1689 } | 1605 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1840 | 1756 |
1841 for (size_t j = 1; j < length; ++j) { | 1757 for (size_t j = 1; j < length; ++j) { |
1842 os << " " << AsHex(i.pc()[j], 2) << ","; | 1758 os << " " << AsHex(i.pc()[j], 2) << ","; |
1843 } | 1759 } |
1844 | 1760 |
1845 switch (opcode) { | 1761 switch (opcode) { |
1846 case kExprIf: | 1762 case kExprIf: |
1847 case kExprElse: | 1763 case kExprElse: |
1848 case kExprLoop: | 1764 case kExprLoop: |
1849 case kExprBlock: | 1765 case kExprBlock: |
1850 case kExprTryCatch: | 1766 case kExprTry: |
1851 case kExprTryCatchFinally: | |
1852 case kExprTryFinally: | |
1853 os << " // @" << i.pc_offset(); | 1767 os << " // @" << i.pc_offset(); |
1854 control_depth++; | 1768 control_depth++; |
1855 break; | 1769 break; |
1856 case kExprEnd: | 1770 case kExprEnd: |
1857 os << " // @" << i.pc_offset(); | 1771 os << " // @" << i.pc_offset(); |
1858 control_depth--; | 1772 control_depth--; |
1859 break; | 1773 break; |
1860 case kExprBr: { | 1774 case kExprBr: { |
1861 BreakDepthOperand operand(&i, i.pc()); | 1775 BreakDepthOperand operand(&i, i.pc()); |
1862 os << " // arity=" << operand.arity << " depth=" << operand.depth; | 1776 os << " // arity=" << operand.arity << " depth=" << operand.depth; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1832 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1919 const byte* start, const byte* end) { | 1833 const byte* start, const byte* end) { |
1920 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1834 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1921 WasmFullDecoder decoder(zone, nullptr, body); | 1835 WasmFullDecoder decoder(zone, nullptr, body); |
1922 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1836 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1923 } | 1837 } |
1924 | 1838 |
1925 } // namespace wasm | 1839 } // namespace wasm |
1926 } // namespace internal | 1840 } // namespace internal |
1927 } // namespace v8 | 1841 } // namespace v8 |
OLD | NEW |