| 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 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 // Initialize the incoming context. | 444 // Initialize the incoming context. |
| 445 function_context_ = NewOuterContextParam(); | 445 function_context_ = NewOuterContextParam(); |
| 446 ContextScope incoming(this, scope, function_context_); | 446 ContextScope incoming(this, scope, function_context_); |
| 447 | 447 |
| 448 // Build receiver check for sloppy mode if necessary. | 448 // Build receiver check for sloppy mode if necessary. |
| 449 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 449 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
| 450 Node* original_receiver = env.Lookup(scope->receiver()); | 450 Node* original_receiver = env.Lookup(scope->receiver()); |
| 451 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 451 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
| 452 env.Bind(scope->receiver(), patched_receiver); | 452 env.Bind(scope->receiver(), patched_receiver); |
| 453 | 453 |
| 454 bool ok; | 454 // Build function context only if there are context allocated variables. |
| 455 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 455 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| 456 if (heap_slots > 0) { | 456 if (heap_slots > 0) { |
| 457 // Push a new inner context scope for the function. | 457 // Push a new inner context scope for the function. |
| 458 Node* closure = GetFunctionClosure(); | 458 Node* closure = GetFunctionClosure(); |
| 459 Node* inner_context = BuildLocalFunctionContext(function_context_, closure); | 459 Node* inner_context = BuildLocalFunctionContext(function_context_, closure); |
| 460 ContextScope top_context(this, scope, inner_context); | 460 ContextScope top_context(this, scope, inner_context); |
| 461 ok = CreateGraphBody(); | 461 CreateGraphBody(); |
| 462 } else { | 462 } else { |
| 463 // Simply use the outer function context in building the graph. | 463 // Simply use the outer function context in building the graph. |
| 464 ok = CreateGraphBody(); | 464 CreateGraphBody(); |
| 465 } | 465 } |
| 466 | 466 |
| 467 // Finish the basic structure of the graph. | 467 // Finish the basic structure of the graph. |
| 468 if (ok) { | 468 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); |
| 469 environment()->UpdateControlDependency(exit_control()); | |
| 470 graph()->SetEnd(NewNode(common()->End())); | |
| 471 } | |
| 472 | 469 |
| 473 return ok; | 470 // Failures indicated by stack overflow. |
| 471 return !HasStackOverflow(); |
| 474 } | 472 } |
| 475 | 473 |
| 476 | 474 |
| 477 bool AstGraphBuilder::CreateGraphBody() { | 475 void AstGraphBuilder::CreateGraphBody() { |
| 478 Scope* scope = info()->scope(); | 476 Scope* scope = info()->scope(); |
| 477 |
| 479 // Build the arguments object if it is used. | 478 // Build the arguments object if it is used. |
| 480 BuildArgumentsObject(scope->arguments()); | 479 BuildArgumentsObject(scope->arguments()); |
| 481 | 480 |
| 482 // Build rest arguments array if it is used. | 481 // Build rest arguments array if it is used. |
| 483 int rest_index; | 482 int rest_index; |
| 484 Variable* rest_parameter = scope->rest_parameter(&rest_index); | 483 Variable* rest_parameter = scope->rest_parameter(&rest_index); |
| 485 BuildRestArgumentsArray(rest_parameter, rest_index); | 484 BuildRestArgumentsArray(rest_parameter, rest_index); |
| 486 | 485 |
| 487 // Emit tracing call if requested to do so. | 486 // Emit tracing call if requested to do so. |
| 488 if (FLAG_trace) { | 487 if (FLAG_trace) { |
| 489 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); | 488 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); |
| 490 } | 489 } |
| 491 | 490 |
| 492 // Visit implicit declaration of the function name. | 491 // Visit implicit declaration of the function name. |
| 493 if (scope->is_function_scope() && scope->function() != NULL) { | 492 if (scope->is_function_scope() && scope->function() != NULL) { |
| 494 VisitVariableDeclaration(scope->function()); | 493 VisitVariableDeclaration(scope->function()); |
| 495 } | 494 } |
| 496 | 495 |
| 497 // Visit declarations within the function scope. | 496 // Visit declarations within the function scope. |
| 498 VisitDeclarations(scope->declarations()); | 497 VisitDeclarations(scope->declarations()); |
| 499 | 498 |
| 500 // Build a stack-check before the body. | 499 // Build a stack-check before the body. |
| 501 Node* node = BuildStackCheck(); | 500 Node* node = BuildStackCheck(); |
| 502 PrepareFrameState(node, BailoutId::FunctionEntry()); | 501 PrepareFrameState(node, BailoutId::FunctionEntry()); |
| 503 | 502 |
| 504 // Visit statements in the function body. | 503 // Visit statements in the function body. |
| 505 VisitStatements(info()->function()->body()); | 504 VisitStatements(info()->function()->body()); |
| 506 if (HasStackOverflow()) return false; | |
| 507 | 505 |
| 508 // Emit tracing call if requested to do so. | 506 // Emit tracing call if requested to do so. |
| 509 if (FLAG_trace) { | 507 if (FLAG_trace) { |
| 510 // TODO(mstarzinger): Only traces implicit return. | 508 // TODO(mstarzinger): Only traces implicit return. |
| 511 Node* return_value = jsgraph()->UndefinedConstant(); | 509 Node* return_value = jsgraph()->UndefinedConstant(); |
| 512 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); | 510 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); |
| 513 } | 511 } |
| 514 | 512 |
| 515 // Return 'undefined' in case we can fall off the end. | 513 // Return 'undefined' in case we can fall off the end. |
| 516 BuildReturn(jsgraph()->UndefinedConstant()); | 514 BuildReturn(jsgraph()->UndefinedConstant()); |
| 517 | |
| 518 return true; | |
| 519 } | 515 } |
| 520 | 516 |
| 521 | 517 |
| 522 // Left-hand side can only be a property, a global or a variable slot. | 518 // Left-hand side can only be a property, a global or a variable slot. |
| 523 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 519 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
| 524 | 520 |
| 525 | 521 |
| 526 // Determine the left-hand side kind of an assignment. | 522 // Determine the left-hand side kind of an assignment. |
| 527 static LhsKind DetermineLhsKind(Expression* expr) { | 523 static LhsKind DetermineLhsKind(Expression* expr) { |
| 528 Property* property = expr->AsProperty(); | 524 Property* property = expr->AsProperty(); |
| (...skipping 2678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3207 // Phi does not exist yet, introduce one. | 3203 // Phi does not exist yet, introduce one. |
| 3208 value = NewPhi(inputs, value, control); | 3204 value = NewPhi(inputs, value, control); |
| 3209 value->ReplaceInput(inputs - 1, other); | 3205 value->ReplaceInput(inputs - 1, other); |
| 3210 } | 3206 } |
| 3211 return value; | 3207 return value; |
| 3212 } | 3208 } |
| 3213 | 3209 |
| 3214 } // namespace compiler | 3210 } // namespace compiler |
| 3215 } // namespace internal | 3211 } // namespace internal |
| 3216 } // namespace v8 | 3212 } // namespace v8 |
| OLD | NEW |