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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 | 132 |
133 // Scoped class tracking control statements entered by the visitor. There are | 133 // Scoped class tracking control statements entered by the visitor. There are |
134 // different types of statements participating in this stack to properly track | 134 // different types of statements participating in this stack to properly track |
135 // local as well as non-local control flow: | 135 // local as well as non-local control flow: |
136 // - IterationStatement : Allows proper 'break' and 'continue' behavior. | 136 // - IterationStatement : Allows proper 'break' and 'continue' behavior. |
137 // - BreakableStatement : Allows 'break' from block and switch statements. | 137 // - BreakableStatement : Allows 'break' from block and switch statements. |
138 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. | 138 // - TryCatchStatement : Intercepts 'throw' and implicit exceptional edges. |
139 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. | 139 // - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'. |
140 class AstGraphBuilder::ControlScope BASE_EMBEDDED { | 140 class AstGraphBuilder::ControlScope BASE_EMBEDDED { |
141 public: | 141 public: |
142 ControlScope(AstGraphBuilder* builder, int stack_delta) | 142 explicit ControlScope(AstGraphBuilder* builder) |
143 : builder_(builder), | 143 : builder_(builder), |
144 outer_(builder->execution_control()), | 144 outer_(builder->execution_control()), |
145 stack_delta_(stack_delta) { | 145 stack_height_(builder->environment()->stack_height()) { |
146 builder_->set_execution_control(this); // Push. | 146 builder_->set_execution_control(this); // Push. |
147 } | 147 } |
148 | 148 |
149 virtual ~ControlScope() { | 149 virtual ~ControlScope() { |
150 builder_->set_execution_control(outer_); // Pop. | 150 builder_->set_execution_control(outer_); // Pop. |
151 } | 151 } |
152 | 152 |
153 // Either 'break' or 'continue' to the target statement. | 153 // Either 'break' or 'continue' to the target statement. |
154 void BreakTo(BreakableStatement* target); | 154 void BreakTo(BreakableStatement* target); |
155 void ContinueTo(BreakableStatement* target); | 155 void ContinueTo(BreakableStatement* target); |
(...skipping 26 matching lines...) Expand all Loading... | |
182 return true; | 182 return true; |
183 case CMD_BREAK: | 183 case CMD_BREAK: |
184 case CMD_CONTINUE: | 184 case CMD_CONTINUE: |
185 break; | 185 break; |
186 } | 186 } |
187 return false; | 187 return false; |
188 } | 188 } |
189 | 189 |
190 Environment* environment() { return builder_->environment(); } | 190 Environment* environment() { return builder_->environment(); } |
191 AstGraphBuilder* builder() const { return builder_; } | 191 AstGraphBuilder* builder() const { return builder_; } |
192 int stack_delta() const { return stack_delta_; } | 192 int stack_height() const { return stack_height_; } |
193 | 193 |
194 private: | 194 private: |
195 AstGraphBuilder* builder_; | 195 AstGraphBuilder* builder_; |
196 ControlScope* outer_; | 196 ControlScope* outer_; |
197 int stack_delta_; | 197 int stack_height_; |
198 }; | 198 }; |
199 | 199 |
200 | 200 |
201 // Helper class for a try-finally control scope. It can record intercepted | 201 // Helper class for a try-finally control scope. It can record intercepted |
202 // control-flow commands that cause entry into a finally-block, and re-apply | 202 // control-flow commands that cause entry into a finally-block, and re-apply |
203 // them after again leaving that block. Special tokens are used to identify | 203 // them after again leaving that block. Special tokens are used to identify |
204 // paths going through the finally-block to dispatch after leaving the block. | 204 // paths going through the finally-block to dispatch after leaving the block. |
205 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { | 205 class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
206 public: | 206 public: |
207 explicit DeferredCommands(AstGraphBuilder* owner) | 207 explicit DeferredCommands(AstGraphBuilder* owner) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 AstGraphBuilder* owner_; | 263 AstGraphBuilder* owner_; |
264 ZoneVector<Entry> deferred_; | 264 ZoneVector<Entry> deferred_; |
265 }; | 265 }; |
266 | 266 |
267 | 267 |
268 // Control scope implementation for a BreakableStatement. | 268 // Control scope implementation for a BreakableStatement. |
269 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { | 269 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { |
270 public: | 270 public: |
271 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, | 271 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, |
272 ControlBuilder* control) | 272 ControlBuilder* control) |
273 : ControlScope(owner, 0), target_(target), control_(control) {} | 273 : ControlScope(owner), target_(target), control_(control) {} |
274 | 274 |
275 protected: | 275 protected: |
276 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 276 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
277 if (target != target_) return false; // We are not the command target. | 277 if (target != target_) return false; // We are not the command target. |
278 switch (cmd) { | 278 switch (cmd) { |
279 case CMD_BREAK: | 279 case CMD_BREAK: |
280 control_->Break(); | 280 control_->Break(); |
281 return true; | 281 return true; |
282 case CMD_CONTINUE: | 282 case CMD_CONTINUE: |
283 case CMD_THROW: | 283 case CMD_THROW: |
284 case CMD_RETURN: | 284 case CMD_RETURN: |
285 break; | 285 break; |
286 } | 286 } |
287 return false; | 287 return false; |
288 } | 288 } |
289 | 289 |
290 private: | 290 private: |
291 BreakableStatement* target_; | 291 BreakableStatement* target_; |
292 ControlBuilder* control_; | 292 ControlBuilder* control_; |
293 }; | 293 }; |
294 | 294 |
295 | 295 |
296 // Control scope implementation for an IterationStatement. | 296 // Control scope implementation for an IterationStatement. |
297 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { | 297 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { |
298 public: | 298 public: |
299 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, | 299 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, |
300 LoopBuilder* control, int stack_delta) | 300 LoopBuilder* control) |
301 : ControlScope(owner, stack_delta), target_(target), control_(control) {} | 301 : ControlScope(owner), target_(target), control_(control) {} |
302 | 302 |
303 protected: | 303 protected: |
304 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 304 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
305 if (target != target_) return false; // We are not the command target. | 305 if (target != target_) return false; // We are not the command target. |
306 switch (cmd) { | 306 switch (cmd) { |
307 case CMD_BREAK: | 307 case CMD_BREAK: |
308 control_->Break(); | 308 control_->Break(); |
309 return true; | 309 return true; |
310 case CMD_CONTINUE: | 310 case CMD_CONTINUE: |
311 control_->Continue(); | 311 control_->Continue(); |
312 return true; | 312 return true; |
313 case CMD_THROW: | 313 case CMD_THROW: |
314 case CMD_RETURN: | 314 case CMD_RETURN: |
315 break; | 315 break; |
316 } | 316 } |
317 return false; | 317 return false; |
318 } | 318 } |
319 | 319 |
320 private: | 320 private: |
321 BreakableStatement* target_; | 321 BreakableStatement* target_; |
322 LoopBuilder* control_; | 322 LoopBuilder* control_; |
323 }; | 323 }; |
324 | 324 |
325 | 325 |
326 // Control scope implementation for a TryCatchStatement. | 326 // Control scope implementation for a TryCatchStatement. |
327 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { | 327 class AstGraphBuilder::ControlScopeForCatch : public ControlScope { |
328 public: | 328 public: |
329 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) | 329 ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control) |
330 : ControlScope(owner, 0), control_(control) { | 330 : ControlScope(owner), control_(control) { |
331 builder()->try_nesting_level_++; // Increment nesting. | 331 builder()->try_nesting_level_++; // Increment nesting. |
332 } | 332 } |
333 ~ControlScopeForCatch() { | 333 ~ControlScopeForCatch() { |
334 builder()->try_nesting_level_--; // Decrement nesting. | 334 builder()->try_nesting_level_--; // Decrement nesting. |
335 } | 335 } |
336 | 336 |
337 protected: | 337 protected: |
338 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 338 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
339 switch (cmd) { | 339 switch (cmd) { |
340 case CMD_THROW: | 340 case CMD_THROW: |
(...skipping 10 matching lines...) Expand all Loading... | |
351 private: | 351 private: |
352 TryCatchBuilder* control_; | 352 TryCatchBuilder* control_; |
353 }; | 353 }; |
354 | 354 |
355 | 355 |
356 // Control scope implementation for a TryFinallyStatement. | 356 // Control scope implementation for a TryFinallyStatement. |
357 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { | 357 class AstGraphBuilder::ControlScopeForFinally : public ControlScope { |
358 public: | 358 public: |
359 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, | 359 ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands, |
360 TryFinallyBuilder* control) | 360 TryFinallyBuilder* control) |
361 : ControlScope(owner, 0), commands_(commands), control_(control) { | 361 : ControlScope(owner), commands_(commands), control_(control) { |
362 builder()->try_nesting_level_++; // Increment nesting. | 362 builder()->try_nesting_level_++; // Increment nesting. |
363 } | 363 } |
364 ~ControlScopeForFinally() { | 364 ~ControlScopeForFinally() { |
365 builder()->try_nesting_level_--; // Decrement nesting. | 365 builder()->try_nesting_level_--; // Decrement nesting. |
366 } | 366 } |
367 | 367 |
368 protected: | 368 protected: |
369 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { | 369 virtual bool Execute(Command cmd, Statement* target, Node* value) OVERRIDE { |
370 Node* token = commands_->RecordCommand(cmd, target, value); | 370 Node* token = commands_->RecordCommand(cmd, target, value); |
371 control_->LeaveTry(token); | 371 control_->LeaveTry(token); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 | 420 |
421 | 421 |
422 bool AstGraphBuilder::CreateGraph() { | 422 bool AstGraphBuilder::CreateGraph() { |
423 Scope* scope = info()->scope(); | 423 Scope* scope = info()->scope(); |
424 DCHECK(graph() != NULL); | 424 DCHECK(graph() != NULL); |
425 | 425 |
426 // Set up the basic structure of the graph. | 426 // Set up the basic structure of the graph. |
427 int parameter_count = info()->num_parameters(); | 427 int parameter_count = info()->num_parameters(); |
428 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); | 428 graph()->SetStart(graph()->NewNode(common()->Start(parameter_count))); |
429 | 429 |
430 // Initialize control scope. | |
431 ControlScope control(this, 0); | |
432 | |
433 // Initialize the top-level environment. | 430 // Initialize the top-level environment. |
434 Environment env(this, scope, graph()->start()); | 431 Environment env(this, scope, graph()->start()); |
435 set_environment(&env); | 432 set_environment(&env); |
436 | 433 |
434 // Initialize control scope. | |
435 ControlScope control(this); | |
436 | |
437 if (info()->is_osr()) { | 437 if (info()->is_osr()) { |
438 // Use OSR normal entry as the start of the top-level environment. | 438 // Use OSR normal entry as the start of the top-level environment. |
439 // It will be replaced with {Dead} after typing and optimizations. | 439 // It will be replaced with {Dead} after typing and optimizations. |
440 NewNode(common()->OsrNormalEntry()); | 440 NewNode(common()->OsrNormalEntry()); |
441 } | 441 } |
442 | 442 |
443 // Initialize the incoming context. | 443 // Initialize the incoming context. |
444 Node* incoming_context = GetFunctionContext(); | 444 Node* incoming_context = GetFunctionContext(); |
445 ContextScope incoming(this, scope, incoming_context); | 445 ContextScope incoming(this, scope, incoming_context); |
446 | 446 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
673 return execution_context_->context(); | 673 return execution_context_->context(); |
674 } | 674 } |
675 | 675 |
676 | 676 |
677 void AstGraphBuilder::ControlScope::PerformCommand(Command command, | 677 void AstGraphBuilder::ControlScope::PerformCommand(Command command, |
678 Statement* target, | 678 Statement* target, |
679 Node* value) { | 679 Node* value) { |
680 Environment* env = environment()->CopyAsUnreachable(); | 680 Environment* env = environment()->CopyAsUnreachable(); |
681 ControlScope* current = this; | 681 ControlScope* current = this; |
682 while (current != NULL) { | 682 while (current != NULL) { |
683 int stack_delta = environment()->stack_height() - current->stack_height(); | |
684 if (stack_delta > 0) environment()->Drop(stack_delta); | |
titzer
2015/02/19 12:33:00
environment()->TrimStack() ?
Michael Starzinger
2015/02/19 12:58:21
Done. Called it just "Trim" as per offline discuss
| |
683 if (current->Execute(command, target, value)) break; | 685 if (current->Execute(command, target, value)) break; |
684 environment()->Drop(current->stack_delta()); | |
685 current = current->outer_; | 686 current = current->outer_; |
686 } | 687 } |
687 builder()->set_environment(env); | 688 builder()->set_environment(env); |
688 DCHECK(current != NULL); // Always handled (unless stack is malformed). | 689 DCHECK(current != NULL); // Always handled (unless stack is malformed). |
689 } | 690 } |
690 | 691 |
691 | 692 |
692 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { | 693 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { |
693 PerformCommand(CMD_BREAK, stmt, nullptr); | 694 PerformCommand(CMD_BREAK, stmt, nullptr); |
694 } | 695 } |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
988 compare_switch.EndCase(); | 989 compare_switch.EndCase(); |
989 } | 990 } |
990 | 991 |
991 compare_switch.EndSwitch(); | 992 compare_switch.EndSwitch(); |
992 } | 993 } |
993 | 994 |
994 | 995 |
995 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 996 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
996 LoopBuilder while_loop(this); | 997 LoopBuilder while_loop(this); |
997 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 998 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
998 VisitIterationBody(stmt, &while_loop, 0); | 999 VisitIterationBody(stmt, &while_loop); |
999 while_loop.EndBody(); | 1000 while_loop.EndBody(); |
1000 VisitForTest(stmt->cond()); | 1001 VisitForTest(stmt->cond()); |
1001 Node* condition = environment()->Pop(); | 1002 Node* condition = environment()->Pop(); |
1002 while_loop.BreakUnless(condition); | 1003 while_loop.BreakUnless(condition); |
1003 while_loop.EndLoop(); | 1004 while_loop.EndLoop(); |
1004 } | 1005 } |
1005 | 1006 |
1006 | 1007 |
1007 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 1008 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
1008 LoopBuilder while_loop(this); | 1009 LoopBuilder while_loop(this); |
1009 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1010 while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1010 VisitForTest(stmt->cond()); | 1011 VisitForTest(stmt->cond()); |
1011 Node* condition = environment()->Pop(); | 1012 Node* condition = environment()->Pop(); |
1012 while_loop.BreakUnless(condition); | 1013 while_loop.BreakUnless(condition); |
1013 VisitIterationBody(stmt, &while_loop, 0); | 1014 VisitIterationBody(stmt, &while_loop); |
1014 while_loop.EndBody(); | 1015 while_loop.EndBody(); |
1015 while_loop.EndLoop(); | 1016 while_loop.EndLoop(); |
1016 } | 1017 } |
1017 | 1018 |
1018 | 1019 |
1019 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { | 1020 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) { |
1020 LoopBuilder for_loop(this); | 1021 LoopBuilder for_loop(this); |
1021 VisitIfNotNull(stmt->init()); | 1022 VisitIfNotNull(stmt->init()); |
1022 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1023 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1023 if (stmt->cond() != NULL) { | 1024 if (stmt->cond() != NULL) { |
1024 VisitForTest(stmt->cond()); | 1025 VisitForTest(stmt->cond()); |
1025 Node* condition = environment()->Pop(); | 1026 Node* condition = environment()->Pop(); |
1026 for_loop.BreakUnless(condition); | 1027 for_loop.BreakUnless(condition); |
1027 } else { | 1028 } else { |
1028 for_loop.BreakUnless(jsgraph()->TrueConstant()); | 1029 for_loop.BreakUnless(jsgraph()->TrueConstant()); |
1029 } | 1030 } |
1030 VisitIterationBody(stmt, &for_loop, 0); | 1031 VisitIterationBody(stmt, &for_loop); |
1031 for_loop.EndBody(); | 1032 for_loop.EndBody(); |
1032 VisitIfNotNull(stmt->next()); | 1033 VisitIfNotNull(stmt->next()); |
1033 for_loop.EndLoop(); | 1034 for_loop.EndLoop(); |
1034 } | 1035 } |
1035 | 1036 |
1036 | 1037 |
1037 // TODO(dcarney): this is a big function. Try to clean up some. | 1038 // TODO(dcarney): this is a big function. Try to clean up some. |
1038 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 1039 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
1039 VisitForValue(stmt->subject()); | 1040 VisitForValue(stmt->subject()); |
1040 Node* obj = environment()->Pop(); | 1041 Node* obj = environment()->Pop(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1159 is_property_missing.End(); | 1160 is_property_missing.End(); |
1160 } | 1161 } |
1161 // Replace 'value' in environment. | 1162 // Replace 'value' in environment. |
1162 environment()->Push(res); | 1163 environment()->Push(res); |
1163 test_should_filter.Else(); | 1164 test_should_filter.Else(); |
1164 test_should_filter.End(); | 1165 test_should_filter.End(); |
1165 } | 1166 } |
1166 value = environment()->Pop(); | 1167 value = environment()->Pop(); |
1167 // Bind value and do loop body. | 1168 // Bind value and do loop body. |
1168 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); | 1169 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); |
1169 VisitIterationBody(stmt, &for_loop, 5); | 1170 VisitIterationBody(stmt, &for_loop); |
1170 for_loop.EndBody(); | 1171 for_loop.EndBody(); |
1171 // Inc counter and continue. | 1172 // Inc counter and continue. |
1172 Node* index_inc = | 1173 Node* index_inc = |
1173 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); | 1174 NewNode(javascript()->Add(), index, jsgraph()->OneConstant()); |
1174 // TODO(jarin): provide real bailout id. | 1175 // TODO(jarin): provide real bailout id. |
1175 PrepareFrameState(index_inc, BailoutId::None()); | 1176 PrepareFrameState(index_inc, BailoutId::None()); |
1176 environment()->Poke(0, index_inc); | 1177 environment()->Poke(0, index_inc); |
1177 for_loop.EndLoop(); | 1178 for_loop.EndLoop(); |
1178 environment()->Drop(5); | 1179 environment()->Drop(5); |
1179 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1180 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1180 } | 1181 } |
1181 | 1182 |
1182 | 1183 |
1183 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { | 1184 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { |
1184 LoopBuilder for_loop(this); | 1185 LoopBuilder for_loop(this); |
1185 VisitForEffect(stmt->assign_iterator()); | 1186 VisitForEffect(stmt->assign_iterator()); |
1186 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); | 1187 for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt)); |
1187 VisitForEffect(stmt->next_result()); | 1188 VisitForEffect(stmt->next_result()); |
1188 VisitForTest(stmt->result_done()); | 1189 VisitForTest(stmt->result_done()); |
1189 Node* condition = environment()->Pop(); | 1190 Node* condition = environment()->Pop(); |
1190 for_loop.BreakWhen(condition); | 1191 for_loop.BreakWhen(condition); |
1191 VisitForEffect(stmt->assign_each()); | 1192 VisitForEffect(stmt->assign_each()); |
1192 VisitIterationBody(stmt, &for_loop, 0); | 1193 VisitIterationBody(stmt, &for_loop); |
1193 for_loop.EndBody(); | 1194 for_loop.EndBody(); |
1194 for_loop.EndLoop(); | 1195 for_loop.EndLoop(); |
1195 } | 1196 } |
1196 | 1197 |
1197 | 1198 |
1198 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1199 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
1199 TryCatchBuilder try_control(this); | 1200 TryCatchBuilder try_control(this); |
1200 | 1201 |
1201 // Evaluate the try-block inside a control scope. This simulates a handler | 1202 // Evaluate the try-block inside a control scope. This simulates a handler |
1202 // that is intercepting 'throw' control commands. | 1203 // that is intercepting 'throw' control commands. |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2272 } | 2273 } |
2273 | 2274 |
2274 | 2275 |
2275 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { | 2276 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) { |
2276 if (stmt == NULL) return; | 2277 if (stmt == NULL) return; |
2277 Visit(stmt); | 2278 Visit(stmt); |
2278 } | 2279 } |
2279 | 2280 |
2280 | 2281 |
2281 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt, | 2282 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt, |
2282 LoopBuilder* loop, int stack_delta) { | 2283 LoopBuilder* loop) { |
2283 ControlScopeForIteration scope(this, stmt, loop, stack_delta); | 2284 ControlScopeForIteration scope(this, stmt, loop); |
2284 Visit(stmt->body()); | 2285 Visit(stmt->body()); |
2285 } | 2286 } |
2286 | 2287 |
2287 | 2288 |
2288 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { | 2289 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { |
2289 Node* value; | 2290 Node* value; |
2290 if (expr->expression()->IsVariableProxy()) { | 2291 if (expr->expression()->IsVariableProxy()) { |
2291 // Delete of an unqualified identifier is only allowed in classic mode but | 2292 // Delete of an unqualified identifier is only allowed in classic mode but |
2292 // deleting "this" is allowed in all language modes. | 2293 // deleting "this" is allowed in all language modes. |
2293 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2294 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
(...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2994 } | 2995 } |
2995 if (!environment()->IsMarkedAsUnreachable()) { | 2996 if (!environment()->IsMarkedAsUnreachable()) { |
2996 // Update the current control dependency for control-producing nodes. | 2997 // Update the current control dependency for control-producing nodes. |
2997 if (NodeProperties::IsControl(result)) { | 2998 if (NodeProperties::IsControl(result)) { |
2998 environment_->UpdateControlDependency(result); | 2999 environment_->UpdateControlDependency(result); |
2999 } | 3000 } |
3000 // Add implicit exception continuation for throwing nodes. | 3001 // Add implicit exception continuation for throwing nodes. |
3001 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { | 3002 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) { |
3002 Node* on_exception = graph()->NewNode(common()->IfException(), result); | 3003 Node* on_exception = graph()->NewNode(common()->IfException(), result); |
3003 environment_->UpdateControlDependency(on_exception); | 3004 environment_->UpdateControlDependency(on_exception); |
3004 if (FLAG_turbo_exceptions) { | 3005 execution_control()->ThrowValue(jsgraph()->UndefinedConstant()); |
3005 execution_control()->ThrowValue(jsgraph()->UndefinedConstant()); | |
3006 } | |
3007 } | 3006 } |
3008 // Add implicit success continuation for throwing nodes. | 3007 // Add implicit success continuation for throwing nodes. |
3009 if (!result->op()->HasProperty(Operator::kNoThrow)) { | 3008 if (!result->op()->HasProperty(Operator::kNoThrow)) { |
3010 Node* on_success = graph()->NewNode(common()->IfSuccess(), result); | 3009 Node* on_success = graph()->NewNode(common()->IfSuccess(), result); |
3011 environment_->UpdateControlDependency(on_success); | 3010 environment_->UpdateControlDependency(on_success); |
3012 } | 3011 } |
3013 } | 3012 } |
3014 } | 3013 } |
3015 | 3014 |
3016 return result; | 3015 return result; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3176 // Phi does not exist yet, introduce one. | 3175 // Phi does not exist yet, introduce one. |
3177 value = NewPhi(inputs, value, control); | 3176 value = NewPhi(inputs, value, control); |
3178 value->ReplaceInput(inputs - 1, other); | 3177 value->ReplaceInput(inputs - 1, other); |
3179 } | 3178 } |
3180 return value; | 3179 return value; |
3181 } | 3180 } |
3182 | 3181 |
3183 } // namespace compiler | 3182 } // namespace compiler |
3184 } // namespace internal | 3183 } // namespace internal |
3185 } // namespace v8 | 3184 } // namespace v8 |
OLD | NEW |