Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: src/wasm/ast-decoder.cc

Issue 2275293002: [WASM] Implements catch for the wasm low level exception mechanism. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Git pull Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/zone-containers.h" 10 #include "src/zone/zone-containers.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 } 63 }
64 }; 64 };
65 65
66 // An entry on the value stack. 66 // An entry on the value stack.
67 struct Value { 67 struct Value {
68 const byte* pc; 68 const byte* pc;
69 TFNode* node; 69 TFNode* node;
70 LocalType type; 70 LocalType type;
71 }; 71 };
72 72
73 struct Control; 73 struct TryInfo : public ZoneObject {
74 SsaEnv* catch_env;
75 TFNode* exception;
76
77 explicit TryInfo(SsaEnv* c) : catch_env(c), exception(nullptr) {}
78 };
74 79
75 struct MergeValues { 80 struct MergeValues {
76 uint32_t arity; 81 uint32_t arity;
77 union { 82 union {
78 Value* array; 83 Value* array;
79 Value first; 84 Value first;
80 } vals; // Either multiple values or a single value. 85 } vals; // Either multiple values or a single value.
81 86
82 Value& first() { 87 Value& first() {
83 DCHECK_GT(arity, 0u); 88 DCHECK_GT(arity, 0u);
84 return arity == 1 ? vals.first : vals.array[0]; 89 return arity == 1 ? vals.first : vals.array[0];
85 } 90 }
86 }; 91 };
87 92
88 // IncomingBranch is used by exception handling code for managing finally's.
89 struct IncomingBranch {
90 int32_t token_value;
91 Control* target;
92 MergeValues merge;
93 };
94
95 static Value* NO_VALUE = nullptr; 93 static Value* NO_VALUE = nullptr;
96 94
97 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry }; 95 enum ControlKind { kControlIf, kControlBlock, kControlLoop, kControlTry };
98 96
99 // An entry on the control stack (i.e. if, block, loop). 97 // An entry on the control stack (i.e. if, block, loop).
100 struct Control { 98 struct Control {
101 const byte* pc; 99 const byte* pc;
102 ControlKind kind; 100 ControlKind kind;
103 int stack_depth; // stack height at the beginning of the construct. 101 int stack_depth; // stack height at the beginning of the construct.
104 SsaEnv* end_env; // end environment for the construct. 102 SsaEnv* end_env; // end environment for the construct.
105 SsaEnv* false_env; // false environment (only for if). 103 SsaEnv* false_env; // false environment (only for if).
106 SsaEnv* catch_env; // catch environment (only for try). 104 TryInfo* try_info; // Information used for compiling try statements.
titzer 2016/09/28 17:09:14 This will of course, require rebase onto 0xC.
John 2016/09/29 13:28:31 Oh, this was painful... <rant />
105 int32_t previous_catch; // The previous Control (on the stack) with a catch.
106 TFNode* node; // result node for the construct.
107 LocalType type; // result type for the construct.
107 108
108 // Values merged into the end of this control construct. 109 // Values merged into the end of this control construct.
109 MergeValues merge; 110 MergeValues merge;
110 111
111 inline bool is_if() const { return kind == kControlIf; } 112 inline bool is_if() const { return kind == kControlIf; }
112 inline bool is_block() const { return kind == kControlBlock; } 113 inline bool is_block() const { return kind == kControlBlock; }
113 inline bool is_loop() const { return kind == kControlLoop; } 114 inline bool is_loop() const { return kind == kControlLoop; }
114 inline bool is_try() const { return kind == kControlTry; } 115 inline bool is_try() const { return kind == kControlTry; }
115 116
116 // Named constructors. 117 // Named constructors.
117 static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env) { 118 static Control Block(const byte* pc, int stack_depth, SsaEnv* end_env,
118 return {pc, kControlBlock, stack_depth, end_env, 119 int32_t previous_catch) {
119 nullptr, nullptr, {0, {NO_VALUE}}}; 120 return {pc, kControlBlock, stack_depth, end_env, nullptr,
121 nullptr, previous_catch, nullptr, kAstEnd, {0, {NO_VALUE}}};
120 } 122 }
121 123
122 static Control If(const byte* pc, int stack_depth, SsaEnv* end_env, 124 static Control If(const byte* pc, int stack_depth, SsaEnv* end_env,
123 SsaEnv* false_env) { 125 SsaEnv* false_env, int32_t previous_catch) {
124 return {pc, kControlIf, stack_depth, end_env, 126 return {pc, kControlIf, stack_depth, end_env, false_env,
125 false_env, nullptr, {0, {NO_VALUE}}}; 127 nullptr, previous_catch, nullptr, kAstStmt, {0, {NO_VALUE}}};
126 } 128 }
127 129
128 static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env) { 130 static Control Loop(const byte* pc, int stack_depth, SsaEnv* end_env,
129 return {pc, kControlLoop, stack_depth, end_env, 131 int32_t previous_catch) {
130 nullptr, nullptr, {0, {NO_VALUE}}}; 132 return {pc, kControlLoop, stack_depth, end_env, nullptr,
133 nullptr, previous_catch, nullptr, kAstEnd, {0, {NO_VALUE}}};
131 } 134 }
132 135
133 static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env, 136 static Control Try(const byte* pc, int stack_depth, SsaEnv* end_env,
134 SsaEnv* catch_env) { 137 Zone* zone, SsaEnv* catch_env, int32_t previous_catch) {
135 return {pc, kControlTry, stack_depth, end_env, 138 DCHECK_NOT_NULL(catch_env);
136 nullptr, catch_env, {0, {NO_VALUE}}}; 139 return {pc,
140 kControlTry,
141 stack_depth,
142 end_env,
143 nullptr,
144 new (zone) TryInfo(catch_env),
145 previous_catch,
146 nullptr,
147 kAstEnd,
148 {0, {NO_VALUE}}};
137 } 149 }
138 }; 150 };
139 151
140 // Macros that build nodes only if there is a graph and the current SSA 152 // Macros that build nodes only if there is a graph and the current SSA
141 // environment is reachable from start. This avoids problems with malformed 153 // environment is reachable from start. This avoids problems with malformed
142 // TF graphs when decoding inputs that have unreachable code. 154 // TF graphs when decoding inputs that have unreachable code.
143 #define BUILD(func, ...) (build() ? builder_->func(__VA_ARGS__) : nullptr) 155 #define BUILD(func, ...) \
144 #define BUILD0(func) (build() ? builder_->func() : nullptr) 156 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr)
157 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr)
145 158
146 // Generic Wasm bytecode decoder with utilities for decoding operands, 159 // Generic Wasm bytecode decoder with utilities for decoding operands,
147 // lengths, etc. 160 // lengths, etc.
148 class WasmDecoder : public Decoder { 161 class WasmDecoder : public Decoder {
149 public: 162 public:
150 WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start, 163 WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start,
151 const byte* end) 164 const byte* end)
152 : Decoder(start, end), 165 : Decoder(start, end),
153 module_(module), 166 module_(module),
154 sig_(sig), 167 sig_(sig),
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 case kExprF32Const: 309 case kExprF32Const:
297 return 5; 310 return 5;
298 case kExprF64Const: 311 case kExprF64Const:
299 return 9; 312 return 9;
300 default: 313 default:
301 return 1; 314 return 1;
302 } 315 }
303 } 316 }
304 }; 317 };
305 318
319 static const int32_t kNullCatch = -1;
320
306 // The full WASM decoder for bytecode. Both verifies bytecode and generates 321 // The full WASM decoder for bytecode. Both verifies bytecode and generates
307 // a TurboFan IR graph. 322 // a TurboFan IR graph.
308 class WasmFullDecoder : public WasmDecoder { 323 class WasmFullDecoder : public WasmDecoder {
309 public: 324 public:
310 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body) 325 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
311 : WasmDecoder(body.module, body.sig, body.start, body.end), 326 : WasmDecoder(body.module, body.sig, body.start, body.end),
312 zone_(zone), 327 zone_(zone),
313 builder_(builder), 328 builder_(builder),
314 base_(body.base), 329 base_(body.base),
315 local_type_vec_(zone), 330 local_type_vec_(zone),
316 stack_(zone), 331 stack_(zone),
317 control_(zone), 332 control_(zone),
318 last_end_found_(false) { 333 last_end_found_(false),
334 current_catch_(kNullCatch) {
319 local_types_ = &local_type_vec_; 335 local_types_ = &local_type_vec_;
320 } 336 }
321 337
322 bool Decode() { 338 bool Decode() {
323 base::ElapsedTimer decode_timer; 339 base::ElapsedTimer decode_timer;
324 if (FLAG_trace_wasm_decode_time) { 340 if (FLAG_trace_wasm_decode_time) {
325 decode_timer.Start(); 341 decode_timer.Start();
326 } 342 }
327 stack_.clear(); 343 stack_.clear();
328 control_.clear(); 344 control_.clear();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 TFBuilder* builder_; 450 TFBuilder* builder_;
435 const byte* base_; 451 const byte* base_;
436 452
437 SsaEnv* ssa_env_; 453 SsaEnv* ssa_env_;
438 454
439 ZoneVector<LocalType> local_type_vec_; // types of local variables. 455 ZoneVector<LocalType> local_type_vec_; // types of local variables.
440 ZoneVector<Value> stack_; // stack of values. 456 ZoneVector<Value> stack_; // stack of values.
441 ZoneVector<Control> control_; // stack of blocks, loops, and ifs. 457 ZoneVector<Control> control_; // stack of blocks, loops, and ifs.
442 bool last_end_found_; 458 bool last_end_found_;
443 459
460 int32_t current_catch_;
461
462 TryInfo* current_try_info() { return control_[current_catch_].try_info; }
463
444 inline bool build() { return builder_ && ssa_env_->go(); } 464 inline bool build() { return builder_ && ssa_env_->go(); }
445 465
446 void InitSsaEnv() { 466 void InitSsaEnv() {
447 TFNode* start = nullptr; 467 TFNode* start = nullptr;
448 SsaEnv* ssa_env = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv))); 468 SsaEnv* ssa_env = reinterpret_cast<SsaEnv*>(zone_->New(sizeof(SsaEnv)));
449 size_t size = sizeof(TFNode*) * EnvironmentCount(); 469 size_t size = sizeof(TFNode*) * EnvironmentCount();
450 ssa_env->state = SsaEnv::kReached; 470 ssa_env->state = SsaEnv::kReached;
451 ssa_env->locals = 471 ssa_env->locals =
452 size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr; 472 size > 0 ? reinterpret_cast<TFNode**>(zone_->New(size)) : nullptr;
453 473
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); 630 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
611 Value value = Pop(0, kAstI32); 631 Value value = Pop(0, kAstI32);
612 BUILD(Throw, value.node); 632 BUILD(Throw, value.node);
613 break; 633 break;
614 } 634 }
615 case kExprTry: { 635 case kExprTry: {
616 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); 636 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
617 BlockTypeOperand operand(this, pc_); 637 BlockTypeOperand operand(this, pc_);
618 SsaEnv* outer_env = ssa_env_; 638 SsaEnv* outer_env = ssa_env_;
619 SsaEnv* try_env = Steal(outer_env); 639 SsaEnv* try_env = Steal(outer_env);
620 SsaEnv* catch_env = Split(try_env); 640 SsaEnv* catch_env = UnreachableEnv();
621 PushTry(outer_env, catch_env); 641 PushTry(outer_env, catch_env);
622 SetEnv("try_catch:start", try_env); 642 SetEnv("try_catch:start", try_env);
623 SetBlockType(&control_.back(), operand); 643 SetBlockType(&control_.back(), operand);
624 len = 1 + operand.length; 644 len = 1 + operand.length;
625 break; 645 break;
626 } 646 }
627 case kExprCatch: { 647 case kExprCatch: {
628 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype); 648 CHECK_PROTOTYPE_OPCODE(wasm_eh_prototype);
629 LocalIndexOperand operand(this, pc_); 649 LocalIndexOperand operand(this, pc_);
630 len = 1 + operand.length; 650 len = 1 + operand.length;
631 651
632 if (control_.empty()) { 652 if (control_.empty()) {
633 error("catch does not match any try"); 653 error("catch does not match any try");
634 break; 654 break;
635 } 655 }
636 656
637 Control* c = &control_.back(); 657 Control* c = &control_.back();
638 if (!c->is_try()) { 658 if (!c->is_try()) {
639 error("catch does not match any try"); 659 error("catch does not match any try");
640 break; 660 break;
641 } 661 }
642 662
643 if (c->catch_env == nullptr) { 663 if (c->try_info->catch_env == nullptr) {
644 error("catch already present for try with catch"); 664 error(pc_, "catch already present for try with catch");
645 break; 665 break;
646 } 666 }
647 667
648 Goto(ssa_env_, c->end_env); 668 if (ssa_env_->go()) {
669 MergeValuesInto(c);
670 }
671 stack_.resize(c->stack_depth);
649 672
650 SsaEnv* catch_env = c->catch_env; 673 DCHECK_NOT_NULL(c->try_info);
651 c->catch_env = nullptr; 674 SsaEnv* catch_env = c->try_info->catch_env;
675 c->try_info->catch_env = nullptr;
652 SetEnv("catch:begin", catch_env); 676 SetEnv("catch:begin", catch_env);
677 current_catch_ = c->previous_catch;
653 678
654 if (Validate(pc_, operand)) { 679 if (Validate(pc_, operand)) {
655 // TODO(jpp): figure out how thrown value is propagated. It is
656 // unlikely to be a value on the stack.
657 if (ssa_env_->locals) { 680 if (ssa_env_->locals) {
658 ssa_env_->locals[operand.index] = nullptr; 681 TFNode* exception_as_i32 =
682 BUILD(Catch, c->try_info->exception, position());
683 ssa_env_->locals[operand.index] = exception_as_i32;
659 } 684 }
660 } 685 }
661 686
662 PopUpTo(c->stack_depth);
663 break; 687 break;
664 } 688 }
665 case kExprLoop: { 689 case kExprLoop: {
666 BlockTypeOperand operand(this, pc_); 690 BlockTypeOperand operand(this, pc_);
667 SsaEnv* finish_try_env = Steal(ssa_env_); 691 SsaEnv* finish_try_env = Steal(ssa_env_);
668 // The continue environment is the inner environment. 692 // The continue environment is the inner environment.
669 PrepareForLoop(pc_, finish_try_env); 693 PrepareForLoop(pc_, finish_try_env);
670 SetEnv("loop:start", Split(finish_try_env)); 694 SetEnv("loop:start", Split(finish_try_env));
671 ssa_env_->SetNotMerged(); 695 ssa_env_->SetNotMerged();
672 PushLoop(finish_try_env); 696 PushLoop(finish_try_env);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 } 764 }
741 name = "if:merge"; 765 name = "if:merge";
742 } else { 766 } else {
743 // End the false branch of a two-armed if. 767 // End the false branch of a two-armed if.
744 name = "if_else:merge"; 768 name = "if_else:merge";
745 } 769 }
746 } else if (c->is_try()) { 770 } else if (c->is_try()) {
747 name = "try:end"; 771 name = "try:end";
748 772
749 // validate that catch was seen. 773 // validate that catch was seen.
750 if (c->catch_env != nullptr) { 774 if (c->try_info->catch_env != nullptr) {
751 error("missing catch in try"); 775 error(pc_, "missing catch in try");
752 break; 776 break;
753 } 777 }
754 } 778 }
755 FallThruTo(c); 779 FallThruTo(c);
756 SetEnv(name, c->end_env); 780 SetEnv(name, c->end_env);
757 781
758 // Push the end values onto the stack. 782 // Push the end values onto the stack.
759 stack_.resize(c->stack_depth); 783 stack_.resize(c->stack_depth);
760 if (c->merge.arity == 1) { 784 if (c->merge.arity == 1) {
761 stack_.push_back(c->merge.vals.first); 785 stack_.push_back(c->merge.vals.first);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 error("grow_memory is not supported for asmjs modules"); 1074 error("grow_memory is not supported for asmjs modules");
1051 } 1075 }
1052 break; 1076 break;
1053 case kExprMemorySize: 1077 case kExprMemorySize:
1054 Push(kAstI32, BUILD(CurrentMemoryPages)); 1078 Push(kAstI32, BUILD(CurrentMemoryPages));
1055 break; 1079 break;
1056 case kExprCallFunction: { 1080 case kExprCallFunction: {
1057 CallFunctionOperand operand(this, pc_); 1081 CallFunctionOperand operand(this, pc_);
1058 if (Validate(pc_, operand)) { 1082 if (Validate(pc_, operand)) {
1059 TFNode** buffer = PopArgs(operand.sig); 1083 TFNode** buffer = PopArgs(operand.sig);
1060 TFNode** rets = 1084 TFNode** rets = nullptr;
1061 BUILD(CallDirect, operand.index, buffer, position()); 1085 BUILD(CallDirect, operand.index, buffer, &rets, position());
1062 PushReturns(operand.sig, rets); 1086 PushReturns(operand.sig, rets);
1063 } 1087 }
1064 len = 1 + operand.length; 1088 len = 1 + operand.length;
1065 break; 1089 break;
1066 } 1090 }
1067 case kExprCallIndirect: { 1091 case kExprCallIndirect: {
1068 CallIndirectOperand operand(this, pc_); 1092 CallIndirectOperand operand(this, pc_);
1069 if (Validate(pc_, operand)) { 1093 if (Validate(pc_, operand)) {
1070 Value index = Pop(0, kAstI32); 1094 Value index = Pop(0, kAstI32);
1071 TFNode** buffer = PopArgs(operand.sig); 1095 TFNode** buffer = PopArgs(operand.sig);
1072 if (buffer) buffer[0] = index.node; 1096 if (buffer) buffer[0] = index.node;
1073 TFNode** rets = 1097 TFNode** rets = nullptr;
1074 BUILD(CallIndirect, operand.index, buffer, position()); 1098 BUILD(CallIndirect, operand.index, buffer, &rets, position());
1075 PushReturns(operand.sig, rets); 1099 PushReturns(operand.sig, rets);
1076 } 1100 }
1077 len = 1 + operand.length; 1101 len = 1 + operand.length;
1078 break; 1102 break;
1079 } 1103 }
1080 case kSimdPrefix: { 1104 case kSimdPrefix: {
1081 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); 1105 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype);
1082 len++; 1106 len++;
1083 byte simd_index = *(pc_ + 1); 1107 byte simd_index = *(pc_ + 1);
1084 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); 1108 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 return nullptr; 1201 return nullptr;
1178 } 1202 }
1179 } 1203 }
1180 1204
1181 LocalType GetReturnType(FunctionSig* sig) { 1205 LocalType GetReturnType(FunctionSig* sig) {
1182 return sig->return_count() == 0 ? kAstStmt : sig->GetReturn(); 1206 return sig->return_count() == 0 ? kAstStmt : sig->GetReturn();
1183 } 1207 }
1184 1208
1185 void PushBlock(SsaEnv* end_env) { 1209 void PushBlock(SsaEnv* end_env) {
1186 const int stack_depth = static_cast<int>(stack_.size()); 1210 const int stack_depth = static_cast<int>(stack_.size());
1187 control_.emplace_back(Control::Block(pc_, stack_depth, end_env)); 1211 control_.emplace_back(
1212 Control::Block(pc_, stack_depth, end_env, current_catch_));
1188 } 1213 }
1189 1214
1190 void PushLoop(SsaEnv* end_env) { 1215 void PushLoop(SsaEnv* end_env) {
1191 const int stack_depth = static_cast<int>(stack_.size()); 1216 const int stack_depth = static_cast<int>(stack_.size());
1192 control_.emplace_back(Control::Loop(pc_, stack_depth, end_env)); 1217 control_.emplace_back(
1218 Control::Loop(pc_, stack_depth, end_env, current_catch_));
1193 } 1219 }
1194 1220
1195 void PushIf(SsaEnv* end_env, SsaEnv* false_env) { 1221 void PushIf(SsaEnv* end_env, SsaEnv* false_env) {
1196 const int stack_depth = static_cast<int>(stack_.size()); 1222 const int stack_depth = static_cast<int>(stack_.size());
1197 control_.emplace_back(Control::If(pc_, stack_depth, end_env, false_env)); 1223 control_.emplace_back(
1224 Control::If(pc_, stack_depth, end_env, false_env, current_catch_));
1198 } 1225 }
1199 1226
1200 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) { 1227 void PushTry(SsaEnv* end_env, SsaEnv* catch_env) {
1201 const int stack_depth = static_cast<int>(stack_.size()); 1228 const int stack_depth = static_cast<int>(stack_.size());
1202 control_.emplace_back(Control::Try(pc_, stack_depth, end_env, catch_env)); 1229 control_.emplace_back(Control::Try(pc_, stack_depth, end_env, zone_,
1230 catch_env, current_catch_));
1231 current_catch_ = static_cast<int32_t>(control_.size() - 1);
1203 } 1232 }
1204 1233
1205 void PopControl() { control_.pop_back(); } 1234 void PopControl() { control_.pop_back(); }
1206 1235
1207 int DecodeLoadMem(LocalType type, MachineType mem_type) { 1236 int DecodeLoadMem(LocalType type, MachineType mem_type) {
1208 MemoryAccessOperand operand(this, pc_, 1237 MemoryAccessOperand operand(this, pc_,
1209 ElementSizeLog2Of(mem_type.representation())); 1238 ElementSizeLog2Of(mem_type.representation()));
1210 1239
1211 Value index = Pop(0, kAstI32); 1240 Value index = Pop(0, kAstI32);
1212 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, 1241 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset,
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 PrintF("\n"); 1481 PrintF("\n");
1453 } 1482 }
1454 #endif 1483 #endif
1455 ssa_env_ = env; 1484 ssa_env_ = env;
1456 if (builder_) { 1485 if (builder_) {
1457 builder_->set_control_ptr(&env->control); 1486 builder_->set_control_ptr(&env->control);
1458 builder_->set_effect_ptr(&env->effect); 1487 builder_->set_effect_ptr(&env->effect);
1459 } 1488 }
1460 } 1489 }
1461 1490
1491 TFNode* CheckForException(TFNode* node) {
1492 if (node == nullptr) {
1493 return nullptr;
1494 }
1495
1496 if (builder_->DoesNotThrow(node)) {
1497 return node;
1498 }
1499
1500 const bool inside_try_scope = current_catch_ != kNullCatch;
1501
1502 if (!inside_try_scope) {
1503 return node;
1504 }
1505
1506 SsaEnv* success_env = Steal(ssa_env_);
1507 TFNode* if_success = builder_->IfSuccess(node);
1508 success_env->control = if_success;
1509
1510 SsaEnv* exception_env = Split(success_env);
1511 TFNode* if_exception = builder_->IfException(node);
1512 exception_env->control = if_exception;
1513 TryInfo* try_info = current_try_info();
1514 Goto(exception_env, try_info->catch_env);
1515 TFNode* exception = try_info->exception;
1516 if (exception == nullptr) {
1517 DCHECK_EQ(SsaEnv::kReached, try_info->catch_env->state);
1518 try_info->exception = if_exception;
1519 } else {
1520 DCHECK_EQ(SsaEnv::kMerged, try_info->catch_env->state);
1521 try_info->exception =
1522 CreateOrMergeIntoPhi(kAstI32, try_info->catch_env->control,
1523 try_info->exception, if_exception);
1524 }
1525
1526 SetEnv("if_success", success_env);
1527 return node;
1528 }
1529
1462 void Goto(SsaEnv* from, SsaEnv* to) { 1530 void Goto(SsaEnv* from, SsaEnv* to) {
1463 DCHECK_NOT_NULL(to); 1531 DCHECK_NOT_NULL(to);
1464 if (!from->go()) return; 1532 if (!from->go()) return;
1465 switch (to->state) { 1533 switch (to->state) {
1466 case SsaEnv::kUnreachable: { // Overwrite destination. 1534 case SsaEnv::kUnreachable: { // Overwrite destination.
1467 to->state = SsaEnv::kReached; 1535 to->state = SsaEnv::kReached;
1468 to->locals = from->locals; 1536 to->locals = from->locals;
1469 to->control = from->control; 1537 to->control = from->control;
1470 to->effect = from->effect; 1538 to->effect = from->effect;
1471 break; 1539 break;
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 1942 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
1875 const byte* start, const byte* end) { 1943 const byte* start, const byte* end) {
1876 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; 1944 FunctionBody body = {nullptr, nullptr, nullptr, start, end};
1877 WasmFullDecoder decoder(zone, nullptr, body); 1945 WasmFullDecoder decoder(zone, nullptr, body);
1878 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); 1946 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals);
1879 } 1947 }
1880 1948
1881 } // namespace wasm 1949 } // namespace wasm
1882 } // namespace internal 1950 } // namespace internal
1883 } // namespace v8 1951 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698