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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 // An entry on the value stack. | 58 // An entry on the value stack. |
59 struct Value { | 59 struct Value { |
60 const byte* pc; | 60 const byte* pc; |
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 TFNode* node; // result node for the construct. | 71 SsaEnv* catch_env; // catch environment (only for try with catch). |
72 LocalType type; // result type for the construct. | 72 SsaEnv* finish_try_env; // the environment where a try with finally lives. |
73 bool is_loop; // true if this is the inner label of a loop. | 73 TFNode* node; // result node for the construct. |
| 74 LocalType type; // result type for the construct. |
| 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* finish_try_env) { |
| 111 return {pc, stack_depth, end_env, nullptr, catch_env, finish_try_env, |
| 112 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->finish_try_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. |
| 798 // c->finish_try_env is the the environment enclosing the try block. |
| 799 Goto(ssa_env_, c->end_env); |
| 800 |
| 801 PopUpTo(c->stack_depth); |
| 802 |
| 803 // The current environment becomes end_env, and finish_try_env |
| 804 // becomes the new end_env. This ensures that any control flow |
| 805 // leaving a try block up to now will do so by branching to the |
| 806 // finally block. Setting the end_env to be finish_try_env ensures |
| 807 // that kExprEnd below can handle the try block as it would any |
| 808 // other block construct. |
| 809 SsaEnv* finally_env = c->end_env; |
| 810 c->end_env = c->finish_try_env; |
| 811 SetEnv("finally:begin", finally_env); |
| 812 c->finish_try_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* finish_try_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_, finish_try_env); |
636 SetEnv("loop:start", Split(cont_env)); | 823 SetEnv("loop:start", Split(finish_try_env)); |
637 ssa_env_->SetNotMerged(); | 824 ssa_env_->SetNotMerged(); |
638 PushLoop(cont_env); | 825 PushLoop(finish_try_env); |
639 break; | 826 break; |
640 } | 827 } |
641 case kExprIf: { | 828 case kExprIf: { |
642 // Condition on top of stack. Split environments for branches. | 829 // Condition on top of stack. Split environments for branches. |
643 Value cond = Pop(0, kAstI32); | 830 Value cond = Pop(0, kAstI32); |
644 TFNode* if_true = nullptr; | 831 TFNode* if_true = nullptr; |
645 TFNode* if_false = nullptr; | 832 TFNode* if_false = nullptr; |
646 BUILD(Branch, cond.node, &if_true, &if_false); | 833 BUILD(Branch, cond.node, &if_true, &if_false); |
647 SsaEnv* end_env = ssa_env_; | 834 SsaEnv* end_env = ssa_env_; |
648 SsaEnv* false_env = Split(ssa_env_); | 835 SsaEnv* false_env = Split(ssa_env_); |
(...skipping 25 matching lines...) Expand all 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->finish_try_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* finish_try_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, finish_try_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 |