| 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 |