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 TFNode* node; | 61 TFNode* node; |
62 LocalType type; | 62 LocalType type; |
63 }; | 63 }; |
64 | 64 |
65 // An entry on the control stack (i.e. if, block, loop). | 65 // An entry on the control stack (i.e. if, block, loop). |
66 struct Control { | 66 struct Control { |
67 const byte* pc; | 67 const byte* pc; |
68 int stack_depth; // stack height at the beginning of the construct. | 68 int stack_depth; // stack height at the beginning of the construct. |
69 SsaEnv* end_env; // end environment for the construct. | 69 SsaEnv* end_env; // end environment for the construct. |
70 SsaEnv* false_env; // false environment (only for if). | 70 SsaEnv* false_env; // false environment (only for if). |
71 SsaEnv* catch_env; // catch environment (only for try with catch). | |
72 SsaEnv* cont_env; // continuation environment (only for try with finally). | |
bradnelson
2016/08/11 00:39:29
This name is confusing, implies continue as in the
John
2016/08/11 11:22:27
Yeah, cont_env threw me off a few times, but I cou
| |
71 TFNode* node; // result node for the construct. | 73 TFNode* node; // result node for the construct. |
72 LocalType type; // result type for the construct. | 74 LocalType type; // result type for the construct. |
73 bool is_loop; // true if this is the inner label of a loop. | 75 bool is_loop; // true if this is the inner label of a loop. |
74 | 76 |
75 bool is_if() { return *pc == kExprIf; } | 77 bool is_if() const { return *pc == kExprIf; } |
76 bool is_block() { return *pc == kExprBlock; } | 78 |
79 bool is_try() const { | |
80 return *pc == kExprTryCatch || *pc == kExprTryCatchFinally || | |
81 *pc == kExprTryFinally; | |
82 } | |
83 | |
84 bool has_catch() const { | |
85 return *pc == kExprTryCatch || *pc == kExprTryCatchFinally; | |
86 } | |
87 | |
88 bool has_finally() const { | |
89 return *pc == kExprTryCatchFinally || *pc == kExprTryFinally; | |
90 } | |
91 | |
92 // Named constructors. | |
93 static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env) { | |
94 return {pc, stack_depth, end_env, nullptr, nullptr, | |
95 nullptr, nullptr, kAstEnd, false}; | |
96 } | |
97 | |
98 static Control If(const byte* pc, int stack_depth, SsaEnv* end_env, | |
99 SsaEnv* false_env) { | |
100 return {pc, stack_depth, end_env, false_env, nullptr, | |
101 nullptr, nullptr, kAstStmt, false}; | |
102 } | |
103 | |
104 static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env) { | |
105 return {pc, stack_depth, end_env, nullptr, nullptr, | |
106 nullptr, nullptr, kAstEnd, true}; | |
107 } | |
108 | |
109 static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env, | |
110 SsaEnv* catch_env, SsaEnv* cont_env) { | |
111 return {pc, stack_depth, end_env, nullptr, catch_env, | |
112 cont_env, nullptr, kAstEnd, false}; | |
113 } | |
77 }; | 114 }; |
78 | 115 |
79 // Macros that build nodes only if there is a graph and the current SSA | 116 // Macros that build nodes only if there is a graph and the current SSA |
80 // environment is reachable from start. This avoids problems with malformed | 117 // environment is reachable from start. This avoids problems with malformed |
81 // TF graphs when decoding inputs that have unreachable code. | 118 // TF graphs when decoding inputs that have unreachable code. |
82 #define BUILD(func, ...) (build() ? builder_->func(__VA_ARGS__) : nullptr) | 119 #define BUILD(func, ...) (build() ? builder_->func(__VA_ARGS__) : nullptr) |
83 #define BUILD0(func) (build() ? builder_->func() : nullptr) | 120 #define BUILD0(func) (build() ? builder_->func() : nullptr) |
84 | 121 |
85 // Generic Wasm bytecode decoder with utilities for decoding operands, | 122 // Generic Wasm bytecode decoder with utilities for decoding operands, |
86 // lengths, etc. | 123 // lengths, etc. |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 case kExprI32Const: | 274 case kExprI32Const: |
238 case kExprI64Const: | 275 case kExprI64Const: |
239 case kExprF64Const: | 276 case kExprF64Const: |
240 case kExprF32Const: | 277 case kExprF32Const: |
241 case kExprGetLocal: | 278 case kExprGetLocal: |
242 case kExprGetGlobal: | 279 case kExprGetGlobal: |
243 case kExprNop: | 280 case kExprNop: |
244 case kExprUnreachable: | 281 case kExprUnreachable: |
245 case kExprEnd: | 282 case kExprEnd: |
246 case kExprBlock: | 283 case kExprBlock: |
284 case kExprThrow: | |
285 case kExprTryCatch: | |
286 case kExprTryCatchFinally: | |
287 case kExprTryFinally: | |
288 case kExprFinally: | |
247 case kExprLoop: | 289 case kExprLoop: |
248 return 0; | 290 return 0; |
249 | 291 |
250 case kExprSetGlobal: | 292 case kExprSetGlobal: |
251 case kExprSetLocal: | 293 case kExprSetLocal: |
252 case kExprElse: | 294 case kExprElse: |
295 case kExprCatch: | |
253 return 1; | 296 return 1; |
254 | 297 |
255 case kExprBr: { | 298 case kExprBr: { |
256 BreakDepthOperand operand(this, pc); | 299 BreakDepthOperand operand(this, pc); |
257 return operand.arity; | 300 return operand.arity; |
258 } | 301 } |
259 case kExprBrIf: { | 302 case kExprBrIf: { |
260 BreakDepthOperand operand(this, pc); | 303 BreakDepthOperand operand(this, pc); |
261 return 1 + operand.arity; | 304 return 1 + operand.arity; |
262 } | 305 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 case kExprCallIndirect: { | 376 case kExprCallIndirect: { |
334 CallIndirectOperand operand(this, pc); | 377 CallIndirectOperand operand(this, pc); |
335 return 1 + operand.length; | 378 return 1 + operand.length; |
336 } | 379 } |
337 case kExprCallImport: { | 380 case kExprCallImport: { |
338 CallImportOperand operand(this, pc); | 381 CallImportOperand operand(this, pc); |
339 return 1 + operand.length; | 382 return 1 + operand.length; |
340 } | 383 } |
341 | 384 |
342 case kExprSetLocal: | 385 case kExprSetLocal: |
343 case kExprGetLocal: { | 386 case kExprGetLocal: |
387 case kExprCatch: { | |
344 LocalIndexOperand operand(this, pc); | 388 LocalIndexOperand operand(this, pc); |
345 return 1 + operand.length; | 389 return 1 + operand.length; |
346 } | 390 } |
347 case kExprBrTable: { | 391 case kExprBrTable: { |
348 BranchTableOperand operand(this, pc); | 392 BranchTableOperand operand(this, pc); |
349 return 1 + operand.length; | 393 return 1 + operand.length; |
350 } | 394 } |
351 case kExprI32Const: { | 395 case kExprI32Const: { |
352 ImmI32Operand operand(this, pc); | 396 ImmI32Operand operand(this, pc); |
353 return 1 + operand.length; | 397 return 1 + operand.length; |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 case kExprNop: | 663 case kExprNop: |
620 Push(kAstStmt, nullptr); | 664 Push(kAstStmt, nullptr); |
621 break; | 665 break; |
622 case kExprBlock: { | 666 case kExprBlock: { |
623 // The break environment is the outer environment. | 667 // The break environment is the outer environment. |
624 SsaEnv* break_env = ssa_env_; | 668 SsaEnv* break_env = ssa_env_; |
625 PushBlock(break_env); | 669 PushBlock(break_env); |
626 SetEnv("block:start", Steal(break_env)); | 670 SetEnv("block:start", Steal(break_env)); |
627 break; | 671 break; |
628 } | 672 } |
673 case kExprThrow: { | |
674 if (!FLAG_wasm_eh_prototype) { | |
675 error("Invalid opcode"); | |
676 return; | |
677 } | |
678 | |
679 // TODO(jpp): validate the poped value. | |
680 Pop(); | |
681 | |
682 // TODO(jpp): start exception propagation. | |
683 break; | |
684 } | |
685 case kExprTryCatch: { | |
686 if (!FLAG_wasm_eh_prototype) { | |
687 error("Invalid opcode"); | |
688 return; | |
689 } | |
690 | |
691 SsaEnv* outer_env = ssa_env_; | |
692 SsaEnv* try_env = Steal(outer_env); | |
693 SsaEnv* catch_env = Split(try_env); | |
694 PushTry(outer_env, catch_env, nullptr); | |
695 SetEnv("try_catch:start", try_env); | |
696 break; | |
697 } | |
698 case kExprTryCatchFinally: { | |
699 if (!FLAG_wasm_eh_prototype) { | |
700 error("Invalid opcode"); | |
701 return; | |
702 } | |
703 | |
704 SsaEnv* outer_env = ssa_env_; | |
705 SsaEnv* try_env = Steal(outer_env); | |
706 SsaEnv* catch_env = Split(try_env); | |
707 SsaEnv* finally_env = Split(try_env); | |
708 PushTry(finally_env, catch_env, outer_env); | |
709 SetEnv("try_catch_finally:start", try_env); | |
710 break; | |
711 } | |
712 case kExprTryFinally: { | |
713 if (!FLAG_wasm_eh_prototype) { | |
714 error("Invalid opcode"); | |
715 return; | |
716 } | |
717 | |
718 SsaEnv* outer_env = ssa_env_; | |
719 SsaEnv* try_env = Steal(outer_env); | |
720 SsaEnv* finally_env = Split(outer_env); | |
721 PushTry(finally_env, nullptr, outer_env); | |
722 SetEnv("try_finally:start", try_env); | |
723 break; | |
724 } | |
725 case kExprCatch: { | |
726 if (!FLAG_wasm_eh_prototype) { | |
727 error("Invalid opcode"); | |
728 return; | |
729 } | |
730 | |
731 LocalIndexOperand operand(this, pc_); | |
732 len = 1 + operand.length; | |
733 | |
734 if (control_.empty()) { | |
735 error(pc_, "catch does not match a any try"); | |
736 break; | |
737 } | |
738 | |
739 Control* c = &control_.back(); | |
740 if (!c->has_catch()) { | |
741 error(pc_, "catch does not match a try with catch"); | |
742 break; | |
743 } | |
744 | |
745 if (c->catch_env == nullptr) { | |
746 error(pc_, "catch already present for try with catch"); | |
747 break; | |
748 } | |
749 | |
750 Goto(ssa_env_, c->end_env); | |
751 | |
752 SsaEnv* catch_env = c->catch_env; | |
753 c->catch_env = nullptr; | |
754 SetEnv("catch:begin", catch_env); | |
755 | |
756 if (Validate(pc_, operand)) { | |
757 // TODO(jpp): figure out how thrown value is propagated. It is | |
758 // unlikely to be a value on the stack. | |
759 if (ssa_env_->locals) { | |
760 ssa_env_->locals[operand.index] = nullptr; | |
761 } | |
762 } | |
763 | |
764 PopUpTo(c->stack_depth); | |
765 | |
766 break; | |
767 } | |
768 case kExprFinally: { | |
769 if (!FLAG_wasm_eh_prototype) { | |
770 error("Invalid opcode"); | |
771 return; | |
772 } | |
773 | |
774 if (control_.empty()) { | |
775 error(pc_, "finally does not match a any try"); | |
776 break; | |
777 } | |
778 | |
779 Control* c = &control_.back(); | |
780 if (c->has_catch() && c->catch_env != nullptr) { | |
781 error(pc_, "missing catch for try with catch and finally"); | |
782 break; | |
783 } | |
784 | |
785 if (!c->has_finally()) { | |
786 error(pc_, "finally does not match a try with finally"); | |
787 break; | |
788 } | |
789 | |
790 if (c->cont_env == nullptr) { | |
791 error(pc_, "finally already present for try with finally"); | |
792 break; | |
793 } | |
794 | |
795 // ssa_env_ is either the env for either the try or the catch, but | |
796 // it does not matter: either way we need to direct the control flow | |
797 // to the end_env, which is the env for the finally. c->cont_env is | |
798 // the "continuation" environment - essentially, the environment | |
799 // where the try block appeared. | |
800 Goto(ssa_env_, c->end_env); | |
801 | |
802 PopUpTo(c->stack_depth); | |
803 | |
804 // The current environment becomes end_env, and cont_env becomes the | |
805 // new end_env. This ensures that any control flow leaving a try | |
806 // block up to now will do so by branching to the finally block. | |
807 // Setting the end_env to be cont_env ensures that kExprEnd below | |
808 // can handle the try block as it would any other block construct. | |
809 SsaEnv* finally_env = c->end_env; | |
810 c->end_env = c->cont_env; | |
811 SetEnv("finally:begin", finally_env); | |
812 c->cont_env = nullptr; | |
813 | |
814 break; | |
815 } | |
629 case kExprLoop: { | 816 case kExprLoop: { |
630 // The break environment is the outer environment. | 817 // The break environment is the outer environment. |
631 SsaEnv* break_env = ssa_env_; | 818 SsaEnv* break_env = ssa_env_; |
632 PushBlock(break_env); | 819 PushBlock(break_env); |
633 SsaEnv* cont_env = Steal(break_env); | 820 SsaEnv* cont_env = Steal(break_env); |
634 // The continue environment is the inner environment. | 821 // The continue environment is the inner environment. |
635 PrepareForLoop(pc_, cont_env); | 822 PrepareForLoop(pc_, cont_env); |
636 SetEnv("loop:start", Split(cont_env)); | 823 SetEnv("loop:start", Split(cont_env)); |
637 ssa_env_->SetNotMerged(); | 824 ssa_env_->SetNotMerged(); |
638 PushLoop(cont_env); | 825 PushLoop(cont_env); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
674 c->false_env = nullptr; // record that an else is already seen | 861 c->false_env = nullptr; // record that an else is already seen |
675 break; | 862 break; |
676 } | 863 } |
677 case kExprEnd: { | 864 case kExprEnd: { |
678 if (control_.empty()) { | 865 if (control_.empty()) { |
679 error(pc_, "end does not match any if or block"); | 866 error(pc_, "end does not match any if or block"); |
680 break; | 867 break; |
681 } | 868 } |
682 const char* name = "block:end"; | 869 const char* name = "block:end"; |
683 Control* c = &control_.back(); | 870 Control* c = &control_.back(); |
871 Value val = PopUpTo(c->stack_depth); | |
684 if (c->is_loop) { | 872 if (c->is_loop) { |
685 // Loops always push control in pairs. | 873 // Loops always push control in pairs. |
686 control_.pop_back(); | 874 control_.pop_back(); |
687 c = &control_.back(); | 875 c = &control_.back(); |
688 name = "loop:end"; | 876 name = "loop:end"; |
689 } | 877 } else if (c->is_if()) { |
690 Value val = PopUpTo(c->stack_depth); | |
691 if (c->is_if()) { | |
692 if (c->false_env != nullptr) { | 878 if (c->false_env != nullptr) { |
693 // End the true branch of a one-armed if. | 879 // End the true branch of a one-armed if. |
694 Goto(c->false_env, c->end_env); | 880 Goto(c->false_env, c->end_env); |
695 val = {val.pc, nullptr, kAstStmt}; | 881 val = {val.pc, nullptr, kAstStmt}; |
696 name = "if:merge"; | 882 name = "if:merge"; |
697 } else { | 883 } else { |
698 // End the false branch of a two-armed if. | 884 // End the false branch of a two-armed if. |
699 name = "if_else:merge"; | 885 name = "if_else:merge"; |
700 } | 886 } |
887 } else if (c->is_try()) { | |
888 DCHECK(FLAG_wasm_eh_prototype); | |
889 | |
890 name = "try:end"; | |
891 | |
892 // try blocks do not yield a value. | |
893 val = {val.pc, nullptr, kAstStmt}; | |
894 | |
895 // validate that catch/finally were seen. | |
896 if (c->catch_env != nullptr) { | |
897 error(pc_, "missing catch in try with catch"); | |
898 break; | |
899 } | |
900 | |
901 if (c->cont_env != nullptr) { | |
902 error(pc_, "missing finally in try with finally"); | |
903 break; | |
904 } | |
701 } | 905 } |
906 | |
702 if (ssa_env_->go()) { | 907 if (ssa_env_->go()) { |
703 MergeInto(c->end_env, &c->node, &c->type, val); | 908 MergeInto(c->end_env, &c->node, &c->type, val); |
704 } | 909 } |
705 SetEnv(name, c->end_env); | 910 SetEnv(name, c->end_env); |
706 stack_.resize(c->stack_depth); | 911 stack_.resize(c->stack_depth); |
707 Push(c->type, c->node); | 912 Push(c->type, c->node); |
708 control_.pop_back(); | 913 control_.pop_back(); |
709 break; | 914 break; |
710 } | 915 } |
711 case kExprSelect: { | 916 case kExprSelect: { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
989 if (Validate(pc_, operand)) { | 1194 if (Validate(pc_, operand)) { |
990 TFNode** buffer = PopArgs(operand.sig); | 1195 TFNode** buffer = PopArgs(operand.sig); |
991 TFNode* call = | 1196 TFNode* call = |
992 BUILD(CallImport, operand.index, buffer, position()); | 1197 BUILD(CallImport, operand.index, buffer, position()); |
993 Push(GetReturnType(operand.sig), call); | 1198 Push(GetReturnType(operand.sig), call); |
994 } | 1199 } |
995 len = 1 + operand.length; | 1200 len = 1 + operand.length; |
996 break; | 1201 break; |
997 } | 1202 } |
998 case kSimdPrefix: { | 1203 case kSimdPrefix: { |
999 if (FLAG_wasm_simd_prototype) { | 1204 if (!FLAG_wasm_simd_prototype) { |
1000 len++; | 1205 error("Invalid opcode"); |
1001 byte simd_index = *(pc_ + 1); | 1206 return; |
1002 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); | |
1003 DecodeSimdOpcode(opcode); | |
1004 break; | |
1005 } | 1207 } |
1208 len++; | |
1209 byte simd_index = *(pc_ + 1); | |
1210 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); | |
1211 DecodeSimdOpcode(opcode); | |
1212 break; | |
1006 } | 1213 } |
1007 default: | 1214 default: |
1008 error("Invalid opcode"); | 1215 error("Invalid opcode"); |
1009 return; | 1216 return; |
1010 } | 1217 } |
1011 } // end complex bytecode | 1218 } // end complex bytecode |
1012 | 1219 |
1013 #if DEBUG | 1220 #if DEBUG |
1014 if (FLAG_trace_wasm_decoder) { | 1221 if (FLAG_trace_wasm_decoder) { |
1015 for (size_t i = 0; i < stack_.size(); ++i) { | 1222 for (size_t i = 0; i < stack_.size(); ++i) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1066 } | 1273 } |
1067 return nullptr; | 1274 return nullptr; |
1068 } | 1275 } |
1069 } | 1276 } |
1070 | 1277 |
1071 LocalType GetReturnType(FunctionSig* sig) { | 1278 LocalType GetReturnType(FunctionSig* sig) { |
1072 return sig->return_count() == 0 ? kAstStmt : sig->GetReturn(); | 1279 return sig->return_count() == 0 ? kAstStmt : sig->GetReturn(); |
1073 } | 1280 } |
1074 | 1281 |
1075 void PushBlock(SsaEnv* end_env) { | 1282 void PushBlock(SsaEnv* end_env) { |
1076 int stack_depth = static_cast<int>(stack_.size()); | 1283 const int stack_depth = static_cast<int>(stack_.size()); |
1077 control_.push_back( | 1284 control_.emplace_back(Control::Block(pc_, stack_depth, end_env)); |
1078 {pc_, stack_depth, end_env, nullptr, nullptr, kAstEnd, false}); | |
1079 } | 1285 } |
1080 | 1286 |
1081 void PushLoop(SsaEnv* end_env) { | 1287 void PushLoop(SsaEnv* end_env) { |
1082 int stack_depth = static_cast<int>(stack_.size()); | 1288 const int stack_depth = static_cast<int>(stack_.size()); |
1083 control_.push_back( | 1289 control_.emplace_back(Control::Loop(pc_, stack_depth, end_env)); |
1084 {pc_, stack_depth, end_env, nullptr, nullptr, kAstEnd, true}); | |
1085 } | 1290 } |
1086 | 1291 |
1087 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { | 1292 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { |
1088 int stack_depth = static_cast<int>(stack_.size()); | 1293 const int stack_depth = static_cast<int>(stack_.size()); |
1089 control_.push_back( | 1294 control_.emplace_back(Control::If(pc_, stack_depth, end_env, false_env)); |
1090 {pc_, stack_depth, end_env, false_env, nullptr, kAstStmt, false}); | 1295 } |
1296 | |
1297 void PushTry(SsaEnv* end_env, SsaEnv* catch_env, SsaEnv* cont_env) { | |
1298 const int stack_depth = static_cast<int>(stack_.size()); | |
1299 control_.emplace_back( | |
1300 Control::Try(pc_, stack_depth, end_env, catch_env, cont_env)); | |
1091 } | 1301 } |
1092 | 1302 |
1093 int DecodeLoadMem(LocalType type, MachineType mem_type) { | 1303 int DecodeLoadMem(LocalType type, MachineType mem_type) { |
1094 MemoryAccessOperand operand(this, pc_); | 1304 MemoryAccessOperand operand(this, pc_); |
1095 Value index = Pop(0, kAstI32); | 1305 Value index = Pop(0, kAstI32); |
1096 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, | 1306 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, |
1097 operand.alignment, position()); | 1307 operand.alignment, position()); |
1098 Push(type, node); | 1308 Push(type, node); |
1099 return 1 + operand.length; | 1309 return 1 + operand.length; |
1100 } | 1310 } |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1434 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_); | 1644 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_); |
1435 int depth = 0; | 1645 int depth = 0; |
1436 // Iteratively process all AST nodes nested inside the loop. | 1646 // Iteratively process all AST nodes nested inside the loop. |
1437 while (pc < limit_ && ok()) { | 1647 while (pc < limit_ && ok()) { |
1438 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); | 1648 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); |
1439 unsigned length = 1; | 1649 unsigned length = 1; |
1440 switch (opcode) { | 1650 switch (opcode) { |
1441 case kExprLoop: | 1651 case kExprLoop: |
1442 case kExprIf: | 1652 case kExprIf: |
1443 case kExprBlock: | 1653 case kExprBlock: |
1654 case kExprTryCatch: | |
1655 case kExprTryCatchFinally: | |
1656 case kExprTryFinally: | |
1444 depth++; | 1657 depth++; |
1445 DCHECK_EQ(1, OpcodeLength(pc)); | 1658 DCHECK_EQ(1, OpcodeLength(pc)); |
1446 break; | 1659 break; |
1447 case kExprSetLocal: { | 1660 case kExprSetLocal: { |
1448 LocalIndexOperand operand(this, pc); | 1661 LocalIndexOperand operand(this, pc); |
1449 if (assigned->length() > 0 && | 1662 if (assigned->length() > 0 && |
1450 static_cast<int>(operand.index) < assigned->length()) { | 1663 static_cast<int>(operand.index) < assigned->length()) { |
1451 // Unverified code might have an out-of-bounds index. | 1664 // Unverified code might have an out-of-bounds index. |
1452 assigned->Add(operand.index); | 1665 assigned->Add(operand.index); |
1453 } | 1666 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1582 | 1795 |
1583 for (size_t j = 1; j < length; ++j) { | 1796 for (size_t j = 1; j < length; ++j) { |
1584 os << " " << AsHex(i.pc()[j], 2) << ","; | 1797 os << " " << AsHex(i.pc()[j], 2) << ","; |
1585 } | 1798 } |
1586 | 1799 |
1587 switch (opcode) { | 1800 switch (opcode) { |
1588 case kExprIf: | 1801 case kExprIf: |
1589 case kExprElse: | 1802 case kExprElse: |
1590 case kExprLoop: | 1803 case kExprLoop: |
1591 case kExprBlock: | 1804 case kExprBlock: |
1805 case kExprTryCatch: | |
1806 case kExprTryCatchFinally: | |
1807 case kExprTryFinally: | |
1592 os << " // @" << i.pc_offset(); | 1808 os << " // @" << i.pc_offset(); |
1593 control_depth++; | 1809 control_depth++; |
1594 break; | 1810 break; |
1595 case kExprEnd: | 1811 case kExprEnd: |
1596 os << " // @" << i.pc_offset(); | 1812 os << " // @" << i.pc_offset(); |
1597 control_depth--; | 1813 control_depth--; |
1598 break; | 1814 break; |
1599 case kExprBr: { | 1815 case kExprBr: { |
1600 BreakDepthOperand operand(&i, i.pc()); | 1816 BreakDepthOperand operand(&i, i.pc()); |
1601 os << " // arity=" << operand.arity << " depth=" << operand.depth; | 1817 os << " // arity=" << operand.arity << " depth=" << operand.depth; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1657 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1873 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1658 const byte* start, const byte* end) { | 1874 const byte* start, const byte* end) { |
1659 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1875 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1660 WasmFullDecoder decoder(zone, nullptr, body); | 1876 WasmFullDecoder decoder(zone, nullptr, body); |
1661 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1877 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1662 } | 1878 } |
1663 | 1879 |
1664 } // namespace wasm | 1880 } // namespace wasm |
1665 } // namespace internal | 1881 } // namespace internal |
1666 } // namespace v8 | 1882 } // namespace v8 |
OLD | NEW |