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

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

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

Powered by Google App Engine
This is Rietveld 408576698