OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 | 133 |
134 // Scoped class tracking control statements entered by the visitor. There are | 134 // Scoped class tracking control statements entered by the visitor. There are |
135 // different types of statements participating in this stack to properly track | 135 // different types of statements participating in this stack to properly track |
136 // local as well as non-local control flow: | 136 // local as well as non-local control flow: |
137 // - IterationStatement : Allows proper 'break' and 'continue' behavior. | 137 // - IterationStatement : Allows proper 'break' and 'continue' behavior. |
138 // - BreakableStatement : Allows 'break' from block and switch statements. | 138 // - BreakableStatement : Allows 'break' from block and switch statements. |
139 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. | 139 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. |
140 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. | 140 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. |
141 class AstGraphBuilder::ControlScope BASE_EMBEDDED { | 141 class AstGraphBuilder::ControlScope BASE_EMBEDDED { |
142 public: | 142 public: |
143 ControlScope(AstGraphBuilder* builder, int stack_delta) | 143 explicit ControlScope(AstGraphBuilder* builder) |
144 : builder_(builder), | 144 : builder_(builder), |
145 outer_(builder->execution_control()), | 145 outer_(builder->execution_control()), |
146 stack_delta_(stack_delta) { | 146 stack_height_(builder->environment()->stack_height()) { |
147 builder_->set_execution_control(this); // Push. | 147 builder_->set_execution_control(this); // Push. |
148 } | 148 } |
149 | 149 |
150 virtual ~ControlScope() { | 150 virtual ~ControlScope() { |
151 builder_->set_execution_control(outer_); // Pop. | 151 builder_->set_execution_control(outer_); // Pop. |
152 } | 152 } |
153 | 153 |
154 // Either 'break' or 'continue' to the target statement. | 154 // Either 'break' or 'continue' to the target statement. |
155 void BreakTo(BreakableStatement* target); | 155 void BreakTo(BreakableStatement* target); |
156 void ContinueTo(BreakableStatement* target); | 156 void ContinueTo(BreakableStatement* target); |
(...skipping 26 matching lines...) Expand all Loading... |
183 return true; | 183 return true; |
184 case CMD_BREAK: | 184 case CMD_BREAK: |
185 case CMD_CONTINUE: | 185 case CMD_CONTINUE: |
186 break; | 186 break; |
187 } | 187 } |
188 return false; | 188 return false; |
189 } | 189 } |
190 | 190 |
191 Environment* environment() { return builder_->environment(); } | 191 Environment* environment() { return builder_->environment(); } |
192 AstGraphBuilder* builder() const { return builder_; } | 192 AstGraphBuilder* builder() const { return builder_; } |
193 int stack_delta() const { return stack_delta_; } | 193 int stack_height() const { return stack_height_; } |
194 | 194 |
195 private: | 195 private: |
196 AstGraphBuilder* builder_; | 196 AstGraphBuilder* builder_; |
197 ControlScope* outer_; | 197 ControlScope* outer_; |
198 int stack_delta_; | 198 int stack_height_; |
199 }; | 199 }; |
200 | 200 |
201 | 201 |
202 // Helper class for a try-finally control scope. It can record intercepted | 202 // Helper class for a try-finally control scope. It can record intercepted |
203 // control-flow commands that cause entry into a finally-block, and re-apply | 203 // control-flow commands that cause entry into a finally-block, and re-apply |
204 // them after again leaving that block. Special tokens are used to identify | 204 // them after again leaving that block. Special tokens are used to identify |
205 // paths going through the finally-block to dispatch after leaving the block. | 205 // paths going through the finally-block to dispatch after leaving the block. |
206 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { | 206 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
207 public: | 207 public: |
208 explicit DeferredCommands(AstGraphBuilder* owner) | 208 explicit DeferredCommands(AstGraphBuilder* owner) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 AstGraphBuilder* owner_; | 264 AstGraphBuilder* owner_; |
265 ZoneVector<Entry> deferred_; | 265 ZoneVector<Entry> deferred_; |
266 }; | 266 }; |
267 | 267 |
268 | 268 |
269 // Control scope implementation for a BreakableStatement. | 269 // Control scope implementation for a BreakableStatement. |
270 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { | 270 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { |
271 public: | 271 public: |
272 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, | 272 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, |
273 ControlBuilder* control) | 273 ControlBuilder* control) |
274 : ControlScope(owner, 0), target_(target), control_(control) {} | 274 : ControlScope(owner), target_(target), control_(control) {} |
275 | 275 |
276 protected: | 276 protected: |
277 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 277 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
278 if (target != target_) return false; // We are not the command target. | 278 if (target != target_) return false; // We are not the command target. |
279 switch (cmd) { | 279 switch (cmd) { |
280 case CMD_BREAK: | 280 case CMD_BREAK: |
281 control_->Break(); | 281 control_->Break(); |
282 return true; | 282 return true; |
283 case CMD_CONTINUE: | 283 case CMD_CONTINUE: |
284 case CMD_THROW: | 284 case CMD_THROW: |
285 case CMD_RETURN: | 285 case CMD_RETURN: |
286 break; | 286 break; |
287 } | 287 } |
288 return false; | 288 return false; |
289 } | 289 } |
290 | 290 |
291 private: | 291 private: |
292 BreakableStatement* target_; | 292 BreakableStatement* target_; |
293 ControlBuilder* control_; | 293 ControlBuilder* control_; |
294 }; | 294 }; |
295 | 295 |
296 | 296 |
297 // Control scope implementation for an IterationStatement. | 297 // Control scope implementation for an IterationStatement. |
298 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { | 298 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { |
299 public: | 299 public: |
300 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, | 300 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, |
301 LoopBuilder* control, int stack_delta) | 301 LoopBuilder* control) |
302 : ControlScope(owner, stack_delta), target_(target), control_(control) {} | 302 : ControlScope(owner), target_(target), control_(control) {} |
303 | 303 |
304 protected: | 304 protected: |
305 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 305 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
306 if (target != target_) return false; // We are not the command target. | 306 if (target != target_) return false; // We are not the command target. |
307 switch (cmd) { | 307 switch (cmd) { |
308 case CMD_BREAK: | 308 case CMD_BREAK: |
309 control_->Break(); | 309 control_->Break(); |
310 return true; | 310 return true; |
311 case CMD_CONTINUE: | 311 case CMD_CONTINUE: |
312 control_->Continue(); | 312 control_->Continue(); |
313 return true; | 313 return true; |
314 case CMD_THROW: | 314 case CMD_THROW: |
315 case CMD_RETURN: | 315 case CMD_RETURN: |
316 break; | 316 break; |
317 } | 317 } |
318 return false; | 318 return false; |
319 } | 319 } |
320 | 320 |
321 private: | 321 private: |
322 BreakableStatement* target_; | 322 BreakableStatement* target_; |
323 LoopBuilder* control_; | 323 LoopBuilder* control_; |
324 }; | 324 }; |
325 | 325 |
326 | 326 |
327 // Control scope implementation for a TryCatchStatement. | 327 // Control scope implementation for a TryCatchStatement. |
328 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { | 328 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { |
329 public: | 329 public: |
330 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) | 330 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) |
331 : ControlScope(owner, 0), control_(control) { | 331 : ControlScope(owner), control_(control) { |
332 builder()->try_nesting_level_++; // Increment nesting. | 332 builder()->try_nesting_level_++; // Increment nesting. |
333 } | 333 } |
334 ~ControlScopeForCatch() { | 334 ~ControlScopeForCatch() { |
335 builder()->try_nesting_level_--; // Decrement nesting. | 335 builder()->try_nesting_level_--; // Decrement nesting. |
336 } | 336 } |
337 | 337 |
338 protected: | 338 protected: |
339 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 339 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
340 switch (cmd) { | 340 switch (cmd) { |
341 case CMD_THROW: | 341 case CMD_THROW: |
(...skipping 10 matching lines...) Expand all Loading... |
352 private: | 352 private: |
353 TryCatchBuilder* control_; | 353 TryCatchBuilder* control_; |
354 }; | 354 }; |
355 | 355 |
356 | 356 |
357 // Control scope implementation for a TryFinallyStatement. | 357 // Control scope implementation for a TryFinallyStatement. |
358 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { | 358 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { |
359 public: | 359 public: |
360 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, | 360 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, |
361 TryFinallyBuilder* control) | 361 TryFinallyBuilder* control) |
362 : ControlScope(owner, 0), commands_(commands), control_(control) { | 362 : ControlScope(owner), commands_(commands), control_(control) { |
363 builder()->try_nesting_level_++; // Increment nesting. | 363 builder()->try_nesting_level_++; // Increment nesting. |
364 } | 364 } |
365 ~ControlScopeForFinally() { | 365 ~ControlScopeForFinally() { |
366 builder()->try_nesting_level_--; // Decrement nesting. | 366 builder()->try_nesting_level_--; // Decrement nesting. |
367 } | 367 } |
368 | 368 |
369 protected: | 369 protected: |
370 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 370 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
371 Node* token = commands_->RecordCommand(cmd, target, value); | 371 Node* token = commands_->RecordCommand(cmd, target, value); |
372 control_->LeaveTry(token); | 372 control_->LeaveTry(token); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 | 432 |
433 | 433 |
434 bool AstGraphBuilder::CreateGraph(bool constant_context) { | 434 bool AstGraphBuilder::CreateGraph(bool constant_context) { |
435 Scope* scope = info()->scope(); | 435 Scope* scope = info()->scope(); |
436 DCHECK(graph() != NULL); | 436 DCHECK(graph() != NULL); |
437 | 437 |
438 // Set up the basic structure of the graph. | 438 // Set up the basic structure of the graph. |
439 int parameter_count = info()->num_parameters(); | 439 int parameter_count = info()->num_parameters(); |
440 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); | 440 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); |
441 | 441 |
442 // Initialize control scope. | |
443 ControlScope control(this, 0); | |
444 | |
445 // Initialize the top-level environment. | 442 // Initialize the top-level environment. |
446 Environment env(this, scope, graph()->start()); | 443 Environment env(this, scope, graph()->start()); |
447 set_environment(&env); | 444 set_environment(&env); |
448 | 445 |
| 446 // Initialize control scope. |
| 447 ControlScope control(this); |
| 448 |
449 if (info()->is_osr()) { | 449 if (info()->is_osr()) { |
450 // Use OSR normal entry as the start of the top-level environment. | 450 // Use OSR normal entry as the start of the top-level environment. |
451 // It will be replaced with {Dead} after typing and optimizations. | 451 // It will be replaced with {Dead} after typing and optimizations. |
452 NewNode(common()->OsrNormalEntry()); | 452 NewNode(common()->OsrNormalEntry()); |
453 } | 453 } |
454 | 454 |
455 // Initialize the incoming context. | 455 // Initialize the incoming context. |
456 CreateFunctionContext(constant_context); | 456 CreateFunctionContext(constant_context); |
457 ContextScope incoming(this, scope, function_context_.get()); | 457 ContextScope incoming(this, scope, function_context_.get()); |
458 | 458 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 return environment()->Context(); | 702 return environment()->Context(); |
703 } | 703 } |
704 | 704 |
705 | 705 |
706 void AstGraphBuilder::ControlScope::PerformCommand(Command command, | 706 void AstGraphBuilder::ControlScope::PerformCommand(Command command, |
707 Statement* target, | 707 Statement* target, |
708 Node* value) { | 708 Node* value) { |
709 Environment* env = environment()->CopyAsUnreachable(); | 709 Environment* env = environment()->CopyAsUnreachable(); |
710 ControlScope* current = this; | 710 ControlScope* current = this; |
711 while (current != NULL) { | 711 while (current != NULL) { |
| 712 environment()->Trim(current->stack_height()); |
712 if (current->Execute(command, target, value)) break; | 713 if (current->Execute(command, target, value)) break; |
713 environment()->Drop(current->stack_delta()); | |
714 current = current->outer_; | 714 current = current->outer_; |
715 } | 715 } |
716 builder()->set_environment(env); | 716 builder()->set_environment(env); |
717 DCHECK(current != NULL); // Always handled (unless stack is malformed). | 717 DCHECK(current != NULL); // Always handled (unless stack is malformed). |
718 } | 718 } |
719 | 719 |
720 | 720 |
721 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { | 721 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { |
722 PerformCommand(CMD_BREAK, stmt, nullptr); | 722 PerformCommand(CMD_BREAK, stmt, nullptr); |
723 } | 723 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 compare_switch.EndCase(); | 1012 compare_switch.EndCase(); |
1013 } | 1013 } |
1014 | 1014 |
1015 compare_switch.EndSwitch(); | 1015 compare_switch.EndSwitch(); |
1016 } | 1016 } |
1017 | 1017 |
1018 | 1018 |
1019 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 1019 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
1020 LoopBuilder while_loop(this); | 1020 LoopBuilder while_loop(this); |
1021 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1021 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1022 VisitIterationBody(stmt, &while_loop, 0); | 1022 VisitIterationBody(stmt, &while_loop); |
1023 while_loop.EndBody(); | 1023 while_loop.EndBody(); |
1024 VisitForTest(stmt->cond()); | 1024 VisitForTest(stmt->cond()); |
1025 Node* condition = environment()->Pop(); | 1025 Node* condition = environment()->Pop(); |
1026 while_loop.BreakUnless(condition); | 1026 while_loop.BreakUnless(condition); |
1027 while_loop.EndLoop(); | 1027 while_loop.EndLoop(); |
1028 } | 1028 } |
1029 | 1029 |
1030 | 1030 |
1031 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 1031 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
1032 LoopBuilder while_loop(this); | 1032 LoopBuilder while_loop(this); |
1033 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1033 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1034 VisitForTest(stmt->cond()); | 1034 VisitForTest(stmt->cond()); |
1035 Node* condition = environment()->Pop(); | 1035 Node* condition = environment()->Pop(); |
1036 while_loop.BreakUnless(condition); | 1036 while_loop.BreakUnless(condition); |
1037 VisitIterationBody(stmt, &while_loop, 0); | 1037 VisitIterationBody(stmt, &while_loop); |
1038 while_loop.EndBody(); | 1038 while_loop.EndBody(); |
1039 while_loop.EndLoop(); | 1039 while_loop.EndLoop(); |
1040 } | 1040 } |
1041 | 1041 |
1042 | 1042 |
1043 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { | 1043 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { |
1044 LoopBuilder for_loop(this); | 1044 LoopBuilder for_loop(this); |
1045 VisitIfNotNull(stmt->init()); | 1045 VisitIfNotNull(stmt->init()); |
1046 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1046 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1047 if (stmt->cond() != NULL) { | 1047 if (stmt->cond() != NULL) { |
1048 VisitForTest(stmt->cond()); | 1048 VisitForTest(stmt->cond()); |
1049 Node* condition = environment()->Pop(); | 1049 Node* condition = environment()->Pop(); |
1050 for_loop.BreakUnless(condition); | 1050 for_loop.BreakUnless(condition); |
1051 } else { | 1051 } else { |
1052 for_loop.BreakUnless(jsgraph()->TrueConstant()); | 1052 for_loop.BreakUnless(jsgraph()->TrueConstant()); |
1053 } | 1053 } |
1054 VisitIterationBody(stmt, &for_loop, 0); | 1054 VisitIterationBody(stmt, &for_loop); |
1055 for_loop.EndBody(); | 1055 for_loop.EndBody(); |
1056 VisitIfNotNull(stmt->next()); | 1056 VisitIfNotNull(stmt->next()); |
1057 for_loop.EndLoop(); | 1057 for_loop.EndLoop(); |
1058 } | 1058 } |
1059 | 1059 |
1060 | 1060 |
1061 // TODO(dcarney): this is a big function. Try to clean up some. | 1061 // TODO(dcarney): this is a big function. Try to clean up some. |
1062 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 1062 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
1063 VisitForValue(stmt->subject()); | 1063 VisitForValue(stmt->subject()); |
1064 Node* obj = environment()->Pop(); | 1064 Node* obj = environment()->Pop(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 is_property_missing.End(); | 1183 is_property_missing.End(); |
1184 } | 1184 } |
1185 // Replace 'value' in environment. | 1185 // Replace 'value' in environment. |
1186 environment()->Push(res); | 1186 environment()->Push(res); |
1187 test_should_filter.Else(); | 1187 test_should_filter.Else(); |
1188 test_should_filter.End(); | 1188 test_should_filter.End(); |
1189 } | 1189 } |
1190 value = environment()->Pop(); | 1190 value = environment()->Pop(); |
1191 // Bind value and do loop body. | 1191 // Bind value and do loop body. |
1192 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); | 1192 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); |
1193 VisitIterationBody(stmt, &for_loop, 5); | 1193 VisitIterationBody(stmt, &for_loop); |
1194 for_loop.EndBody(); | 1194 for_loop.EndBody(); |
1195 // Inc counter and continue. | 1195 // Inc counter and continue. |
1196 Node* index_inc = | 1196 Node* index_inc = |
1197 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 1197 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
1198 // TODO(jarin): provide real bailout id. | 1198 // TODO(jarin): provide real bailout id. |
1199 PrepareFrameState(index_inc, BailoutId::None()); | 1199 PrepareFrameState(index_inc, BailoutId::None()); |
1200 environment()->Poke(0, index_inc); | 1200 environment()->Poke(0, index_inc); |
1201 for_loop.EndLoop(); | 1201 for_loop.EndLoop(); |
1202 environment()->Drop(5); | 1202 environment()->Drop(5); |
1203 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1203 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1204 } | 1204 } |
1205 | 1205 |
1206 | 1206 |
1207 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { | 1207 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { |
1208 LoopBuilder for_loop(this); | 1208 LoopBuilder for_loop(this); |
1209 VisitForEffect(stmt->assign_iterator()); | 1209 VisitForEffect(stmt->assign_iterator()); |
1210 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1210 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1211 VisitForEffect(stmt->next_result()); | 1211 VisitForEffect(stmt->next_result()); |
1212 VisitForTest(stmt->result_done()); | 1212 VisitForTest(stmt->result_done()); |
1213 Node* condition = environment()->Pop(); | 1213 Node* condition = environment()->Pop(); |
1214 for_loop.BreakWhen(condition); | 1214 for_loop.BreakWhen(condition); |
1215 VisitForEffect(stmt->assign_each()); | 1215 VisitForEffect(stmt->assign_each()); |
1216 VisitIterationBody(stmt, &for_loop, 0); | 1216 VisitIterationBody(stmt, &for_loop); |
1217 for_loop.EndBody(); | 1217 for_loop.EndBody(); |
1218 for_loop.EndLoop(); | 1218 for_loop.EndLoop(); |
1219 } | 1219 } |
1220 | 1220 |
1221 | 1221 |
1222 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1222 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
1223 TryCatchBuilder try_control(this); | 1223 TryCatchBuilder try_control(this); |
1224 | 1224 |
1225 // Evaluate the try-block inside a control scope. This simulates a handler | 1225 // Evaluate the try-block inside a control scope. This simulates a handler |
1226 // that is intercepting 'throw' control commands. | 1226 // that is intercepting 'throw' control commands. |
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 } | 2297 } |
2298 | 2298 |
2299 | 2299 |
2300 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { | 2300 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { |
2301 if (stmt == NULL) return; | 2301 if (stmt == NULL) return; |
2302 Visit(stmt); | 2302 Visit(stmt); |
2303 } | 2303 } |
2304 | 2304 |
2305 | 2305 |
2306 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt, | 2306 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt, |
2307 LoopBuilder* loop, int stack_delta) { | 2307 LoopBuilder* loop) { |
2308 ControlScopeForIteration scope(this, stmt, loop, stack_delta); | 2308 ControlScopeForIteration scope(this, stmt, loop); |
2309 Visit(stmt->body()); | 2309 Visit(stmt->body()); |
2310 } | 2310 } |
2311 | 2311 |
2312 | 2312 |
2313 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { | 2313 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { |
2314 Node* value; | 2314 Node* value; |
2315 if (expr->expression()->IsVariableProxy()) { | 2315 if (expr->expression()->IsVariableProxy()) { |
2316 // Delete of an unqualified identifier is only allowed in classic mode but | 2316 // Delete of an unqualified identifier is only allowed in classic mode but |
2317 // deleting "this" is allowed in all language modes. | 2317 // deleting "this" is allowed in all language modes. |
2318 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2318 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3015 } | 3015 } |
3016 if (!environment()->IsMarkedAsUnreachable()) { | 3016 if (!environment()->IsMarkedAsUnreachable()) { |
3017 // Update the current control dependency for control-producing nodes. | 3017 // Update the current control dependency for control-producing nodes. |
3018 if (NodeProperties::IsControl(result)) { | 3018 if (NodeProperties::IsControl(result)) { |
3019 environment_->UpdateControlDependency(result); | 3019 environment_->UpdateControlDependency(result); |
3020 } | 3020 } |
3021 // Add implicit exception continuation for throwing nodes. | 3021 // Add implicit exception continuation for throwing nodes. |
3022 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { | 3022 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { |
3023 Node* on_exception = graph()->NewNode(common()->IfException(), result); | 3023 Node* on_exception = graph()->NewNode(common()->IfException(), result); |
3024 environment_->UpdateControlDependency(on_exception); | 3024 environment_->UpdateControlDependency(on_exception); |
3025 if (FLAG_turbo_exceptions) { | 3025 execution_control()->ThrowValue(jsgraph()->UndefinedConstant()); |
3026 execution_control()->ThrowValue(jsgraph()->UndefinedConstant()); | |
3027 } | |
3028 } | 3026 } |
3029 // Add implicit success continuation for throwing nodes. | 3027 // Add implicit success continuation for throwing nodes. |
3030 if (!result->op()->HasProperty(Operator::kNoThrow)) { | 3028 if (!result->op()->HasProperty(Operator::kNoThrow)) { |
3031 Node* on_success = graph()->NewNode(common()->IfSuccess(), result); | 3029 Node* on_success = graph()->NewNode(common()->IfSuccess(), result); |
3032 environment_->UpdateControlDependency(on_success); | 3030 environment_->UpdateControlDependency(on_success); |
3033 } | 3031 } |
3034 } | 3032 } |
3035 } | 3033 } |
3036 | 3034 |
3037 return result; | 3035 return result; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3235 // Phi does not exist yet, introduce one. | 3233 // Phi does not exist yet, introduce one. |
3236 value = NewPhi(inputs, value, control); | 3234 value = NewPhi(inputs, value, control); |
3237 value->ReplaceInput(inputs - 1, other); | 3235 value->ReplaceInput(inputs - 1, other); |
3238 } | 3236 } |
3239 return value; | 3237 return value; |
3240 } | 3238 } |
3241 | 3239 |
3242 } // namespace compiler | 3240 } // namespace compiler |
3243 } // namespace internal | 3241 } // namespace internal |
3244 } // namespace v8 | 3242 } // namespace v8 |
OLD | NEW |