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/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 | 461 |
462 // Initialize the incoming context. | 462 // Initialize the incoming context. |
463 CreateFunctionContext(constant_context); | 463 CreateFunctionContext(constant_context); |
464 ContextScope incoming(this, scope, function_context_.get()); | 464 ContextScope incoming(this, scope, function_context_.get()); |
465 | 465 |
466 // Initialize control scope. | 466 // Initialize control scope. |
467 ControlScope control(this); | 467 ControlScope control(this); |
468 | 468 |
469 // Build receiver check for sloppy mode if necessary. | 469 // Build receiver check for sloppy mode if necessary. |
470 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? | 470 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC? |
471 Node* original_receiver = env.Lookup(scope->receiver()); | 471 if (scope->has_this_declaration()) { |
472 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); | 472 Node* original_receiver = env.Lookup(scope->receiver()); |
473 env.Bind(scope->receiver(), patched_receiver); | 473 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver); |
474 env.Bind(scope->receiver(), patched_receiver); | |
475 } | |
474 | 476 |
475 // Build function context only if there are context allocated variables. | 477 // Build function context only if there are context allocated variables. |
476 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 478 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
477 if (heap_slots > 0) { | 479 if (heap_slots > 0) { |
478 // Push a new inner context scope for the function. | 480 // Push a new inner context scope for the function. |
479 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); | 481 Node* inner_context = BuildLocalFunctionContext(function_context_.get()); |
480 ContextScope top_context(this, scope, inner_context); | 482 ContextScope top_context(this, scope, inner_context); |
481 CreateGraphBody(stack_check); | 483 CreateGraphBody(stack_check); |
482 } else { | 484 } else { |
483 // Simply use the outer function context in building the graph. | 485 // Simply use the outer function context in building the graph. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 // Split the liveness blocks. | 634 // Split the liveness blocks. |
633 copy->liveness_block_ = | 635 copy->liveness_block_ = |
634 builder_->liveness_analyzer()->NewBlock(copy->liveness_block()); | 636 builder_->liveness_analyzer()->NewBlock(copy->liveness_block()); |
635 liveness_block_ = | 637 liveness_block_ = |
636 builder_->liveness_analyzer()->NewBlock(copy->liveness_block()); | 638 builder_->liveness_analyzer()->NewBlock(copy->liveness_block()); |
637 } | 639 } |
638 } | 640 } |
639 | 641 |
640 | 642 |
641 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { | 643 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { |
644 // "this" may be context-allocated, but it's possible for us to look it up and | |
645 // patch it on the stack before it has been hoisted to the context. | |
646 if (variable->is_this()) { | |
Michael Starzinger
2015/04/21 18:13:44
AFAICT, this is only needed for patching the recei
wingo
2015/04/22 08:04:00
I had tried to do that, but I couldn't get at envi
Michael Starzinger
2015/04/22 10:59:21
Yes, I think for patching purposes Parameter(0) is
| |
647 values()->at(0) = node; | |
648 return; | |
649 } | |
650 | |
642 DCHECK(variable->IsStackAllocated()); | 651 DCHECK(variable->IsStackAllocated()); |
643 if (variable->IsParameter()) { | 652 if (variable->IsParameter()) { |
644 // The parameter indices are shifted by 1 (receiver is parameter | 653 // The parameter indices are shifted by 1 (receiver is parameter |
645 // index -1 but environment index 0). | 654 // index -1 but environment index 0). |
646 values()->at(variable->index() + 1) = node; | 655 values()->at(variable->index() + 1) = node; |
647 } else { | 656 } else { |
648 DCHECK(variable->IsStackLocal()); | 657 DCHECK(variable->IsStackLocal()); |
649 values()->at(variable->index() + parameters_count_) = node; | 658 values()->at(variable->index() + parameters_count_) = node; |
650 if (FLAG_analyze_environment_liveness) { | 659 if (FLAG_analyze_environment_liveness) { |
651 liveness_block()->Bind(variable->index()); | 660 liveness_block()->Bind(variable->index()); |
652 } | 661 } |
653 } | 662 } |
654 } | 663 } |
655 | 664 |
656 | 665 |
657 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { | 666 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { |
667 // "this" may be context-allocated, but it's possible for us to look it up and | |
668 // patch it on the stack before it has been hoisted to the context. | |
669 if (variable->is_this()) { | |
Michael Starzinger
2015/04/21 18:13:44
Likewise.
wingo
2015/04/22 08:04:00
Acknowledged.
| |
670 return values()->at(0); | |
671 } | |
672 | |
658 DCHECK(variable->IsStackAllocated()); | 673 DCHECK(variable->IsStackAllocated()); |
659 if (variable->IsParameter()) { | 674 if (variable->IsParameter()) { |
660 // The parameter indices are shifted by 1 (receiver is parameter | 675 // The parameter indices are shifted by 1 (receiver is parameter |
661 // index -1 but environment index 0). | 676 // index -1 but environment index 0). |
662 return values()->at(variable->index() + 1); | 677 return values()->at(variable->index() + 1); |
663 } else { | 678 } else { |
664 DCHECK(variable->IsStackLocal()); | 679 DCHECK(variable->IsStackLocal()); |
665 if (FLAG_analyze_environment_liveness) { | 680 if (FLAG_analyze_environment_liveness) { |
666 liveness_block()->Lookup(variable->index()); | 681 liveness_block()->Lookup(variable->index()); |
667 } | 682 } |
(...skipping 1473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2141 if (possibly_eval && args->length() > 0) { | 2156 if (possibly_eval && args->length() > 0) { |
2142 int arg_count = args->length(); | 2157 int arg_count = args->length(); |
2143 | 2158 |
2144 // Extract callee and source string from the environment. | 2159 // Extract callee and source string from the environment. |
2145 Node* callee = environment()->Peek(arg_count + 1); | 2160 Node* callee = environment()->Peek(arg_count + 1); |
2146 Node* source = environment()->Peek(arg_count - 1); | 2161 Node* source = environment()->Peek(arg_count - 1); |
2147 | 2162 |
2148 // Create node to ask for help resolving potential eval call. This will | 2163 // Create node to ask for help resolving potential eval call. This will |
2149 // provide a fully resolved callee and the corresponding receiver. | 2164 // provide a fully resolved callee and the corresponding receiver. |
2150 Node* function = GetFunctionClosure(); | 2165 Node* function = GetFunctionClosure(); |
2151 Node* receiver = environment()->Lookup(info()->scope()->receiver()); | 2166 Node* receiver = environment()->Lookup(info()->scope()->LookupThis()); |
2152 Node* language = jsgraph()->Constant(language_mode()); | 2167 Node* language = jsgraph()->Constant(language_mode()); |
2153 Node* position = jsgraph()->Constant(info()->scope()->start_position()); | 2168 Node* position = jsgraph()->Constant(info()->scope()->start_position()); |
2154 const Operator* op = | 2169 const Operator* op = |
2155 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2170 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2156 Node* pair = | 2171 Node* pair = |
2157 NewNode(op, callee, source, function, receiver, language, position); | 2172 NewNode(op, callee, source, function, receiver, language, position); |
2158 PrepareFrameState(pair, expr->EvalOrLookupId(), | 2173 PrepareFrameState(pair, expr->EvalOrLookupId(), |
2159 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2174 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
2160 Node* new_callee = NewNode(common()->Projection(0), pair); | 2175 Node* new_callee = NewNode(common()->Projection(0), pair); |
2161 Node* new_receiver = NewNode(common()->Projection(1), pair); | 2176 Node* new_receiver = NewNode(common()->Projection(1), pair); |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2644 Node* closure = GetFunctionClosure(); | 2659 Node* closure = GetFunctionClosure(); |
2645 | 2660 |
2646 // Allocate a new local context. | 2661 // Allocate a new local context. |
2647 Node* local_context = | 2662 Node* local_context = |
2648 info()->scope()->is_script_scope() | 2663 info()->scope()->is_script_scope() |
2649 ? BuildLocalScriptContext(info()->scope()) | 2664 ? BuildLocalScriptContext(info()->scope()) |
2650 : NewNode(javascript()->CreateFunctionContext(), closure); | 2665 : NewNode(javascript()->CreateFunctionContext(), closure); |
2651 | 2666 |
2652 // Copy parameters into context if necessary. | 2667 // Copy parameters into context if necessary. |
2653 int num_parameters = info()->scope()->num_parameters(); | 2668 int num_parameters = info()->scope()->num_parameters(); |
2654 for (int i = 0; i < num_parameters; i++) { | 2669 int first_parameter = info()->scope()->has_this_declaration() ? -1 : 0; |
2655 Variable* variable = info()->scope()->parameter(i); | 2670 for (int i = first_parameter; i < num_parameters; i++) { |
2671 Variable* variable = | |
2672 (i == -1) ? info()->scope()->receiver() : info()->scope()->parameter(i); | |
Michael Starzinger
2015/04/21 18:13:44
This is getting out of hand, please hoist handling
| |
2656 if (!variable->IsContextSlot()) continue; | 2673 if (!variable->IsContextSlot()) continue; |
2657 // Temporary parameter node. The parameter indices are shifted by 1 | 2674 // Temporary parameter node. The parameter indices are shifted by 1 |
2658 // (receiver is parameter index -1 but environment index 0). | 2675 // (receiver is parameter index -1 but environment index 0). |
2659 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); | 2676 Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start()); |
Michael Starzinger
2015/04/21 18:13:44
If the receiver parameter has been patched, then u
wingo
2015/04/22 08:04:00
I see. Thanks, I didn't realize that. Will updat
| |
2660 // Context variable (at bottom of the context chain). | 2677 // Context variable (at bottom of the context chain). |
2661 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); | 2678 DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope())); |
2662 const Operator* op = javascript()->StoreContext(0, variable->index()); | 2679 const Operator* op = javascript()->StoreContext(0, variable->index()); |
2663 NewNode(op, local_context, parameter); | 2680 NewNode(op, local_context, parameter); |
2664 } | 2681 } |
2665 | 2682 |
2666 return local_context; | 2683 return local_context; |
2667 } | 2684 } |
2668 | 2685 |
2669 | 2686 |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3550 // Phi does not exist yet, introduce one. | 3567 // Phi does not exist yet, introduce one. |
3551 value = NewPhi(inputs, value, control); | 3568 value = NewPhi(inputs, value, control); |
3552 value->ReplaceInput(inputs - 1, other); | 3569 value->ReplaceInput(inputs - 1, other); |
3553 } | 3570 } |
3554 return value; | 3571 return value; |
3555 } | 3572 } |
3556 | 3573 |
3557 } // namespace compiler | 3574 } // namespace compiler |
3558 } // namespace internal | 3575 } // namespace internal |
3559 } // namespace v8 | 3576 } // namespace v8 |
OLD | NEW |