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/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 if (!function_context_.is_set()) { | 328 if (!function_context_.is_set()) { |
329 int params = info()->num_parameters_including_this(); | 329 int params = info()->num_parameters_including_this(); |
330 int index = Linkage::GetJSCallContextParamIndex(params); | 330 int index = Linkage::GetJSCallContextParamIndex(params); |
331 const Operator* op = common()->Parameter(index, "%context"); | 331 const Operator* op = common()->Parameter(index, "%context"); |
332 Node* node = NewNode(op, graph()->start()); | 332 Node* node = NewNode(op, graph()->start()); |
333 function_context_.set(node); | 333 function_context_.set(node); |
334 } | 334 } |
335 return function_context_.get(); | 335 return function_context_.get(); |
336 } | 336 } |
337 | 337 |
338 | |
339 Node* AstGraphBuilder::GetNewTarget() { | |
340 if (!new_target_.is_set()) { | |
341 int params = info()->num_parameters_including_this(); | |
342 int index = Linkage::GetJSCallNewTargetParamIndex(params); | |
343 const Operator* op = common()->Parameter(index, "%new.target"); | |
344 Node* node = NewNode(op, graph()->start()); | |
345 new_target_.set(node); | |
346 } | |
347 return new_target_.get(); | |
348 } | |
349 | |
350 Node* AstGraphBuilder::GetEmptyFrameState() { | 338 Node* AstGraphBuilder::GetEmptyFrameState() { |
351 if (!empty_frame_state_.is_set()) { | 339 if (!empty_frame_state_.is_set()) { |
352 const Operator* op = common()->FrameState( | 340 const Operator* op = common()->FrameState( |
353 BailoutId::None(), OutputFrameStateCombine::Ignore(), nullptr); | 341 BailoutId::None(), OutputFrameStateCombine::Ignore(), nullptr); |
354 Node* node = graph()->NewNode( | 342 Node* node = graph()->NewNode( |
355 op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), | 343 op, jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(), |
356 jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(), | 344 jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(), |
357 jsgraph()->UndefinedConstant(), graph()->start()); | 345 jsgraph()->UndefinedConstant(), graph()->start()); |
358 empty_frame_state_.set(node); | 346 empty_frame_state_.set(node); |
359 } | 347 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 return !HasStackOverflow(); | 406 return !HasStackOverflow(); |
419 } | 407 } |
420 | 408 |
421 | 409 |
422 void AstGraphBuilder::CreateGraphBody(bool stack_check) { | 410 void AstGraphBuilder::CreateGraphBody(bool stack_check) { |
423 DeclarationScope* scope = info()->scope(); | 411 DeclarationScope* scope = info()->scope(); |
424 | 412 |
425 // Build the arguments object if it is used. | 413 // Build the arguments object if it is used. |
426 BuildArgumentsObject(scope->arguments()); | 414 BuildArgumentsObject(scope->arguments()); |
427 | 415 |
428 // Build rest arguments array if it is used. | 416 // We don't support new.target and rest parameters here. |
429 Variable* rest_parameter = scope->rest_parameter(); | 417 DCHECK_NULL(scope->new_target_var()); |
430 BuildRestArgumentsArray(rest_parameter); | 418 DCHECK_NULL(scope->rest_parameter()); |
431 | 419 DCHECK_NULL(scope->this_function_var()); |
432 // Build assignment to {.this_function} variable if it is used. | |
433 BuildThisFunctionVariable(scope->this_function_var()); | |
434 | |
435 // Build assignment to {new.target} variable if it is used. | |
436 BuildNewTargetVariable(scope->new_target_var()); | |
437 | 420 |
438 // Emit tracing call if requested to do so. | 421 // Emit tracing call if requested to do so. |
439 if (FLAG_trace) { | 422 if (FLAG_trace) { |
440 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter)); | 423 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter)); |
441 } | 424 } |
442 | 425 |
443 // Visit declarations within the function scope. | 426 // Visit declarations within the function scope. |
444 VisitDeclarations(scope->declarations()); | 427 VisitDeclarations(scope->declarations()); |
445 | 428 |
446 // Build a stack-check before the body. | 429 // Build a stack-check before the body. |
(...skipping 2340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2787 PrepareFrameState(object, BailoutId::None()); | 2770 PrepareFrameState(object, BailoutId::None()); |
2788 | 2771 |
2789 // Assign the object to the {arguments} variable. This should never lazy | 2772 // Assign the object to the {arguments} variable. This should never lazy |
2790 // deopt, so it is fine to send invalid bailout id. | 2773 // deopt, so it is fine to send invalid bailout id. |
2791 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 2774 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
2792 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), | 2775 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), |
2793 BailoutId::None()); | 2776 BailoutId::None()); |
2794 return object; | 2777 return object; |
2795 } | 2778 } |
2796 | 2779 |
2797 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest) { | |
2798 if (rest == nullptr) return nullptr; | |
2799 | |
2800 // Allocate and initialize a new arguments object. | |
2801 CreateArgumentsType type = CreateArgumentsType::kRestParameter; | |
2802 const Operator* op = javascript()->CreateArguments(type); | |
2803 Node* object = NewNode(op, GetFunctionClosure()); | |
2804 PrepareFrameState(object, BailoutId::None()); | |
2805 | |
2806 // Assign the object to the {rest} variable. This should never lazy | |
2807 // deopt, so it is fine to send invalid bailout id. | |
2808 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | |
2809 BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(), | |
2810 BailoutId::None()); | |
2811 return object; | |
2812 } | |
2813 | |
2814 | |
2815 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) { | |
2816 if (this_function_var == nullptr) return nullptr; | |
2817 | |
2818 // Retrieve the closure we were called with. | |
2819 Node* this_function = GetFunctionClosure(); | |
2820 | |
2821 // Assign the object to the {.this_function} variable. This should never lazy | |
2822 // deopt, so it is fine to send invalid bailout id. | |
2823 BuildVariableAssignment(this_function_var, this_function, Token::INIT, | |
2824 VectorSlotPair(), BailoutId::None()); | |
2825 return this_function; | |
2826 } | |
2827 | |
2828 | |
2829 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) { | |
2830 if (new_target_var == nullptr) return nullptr; | |
2831 | |
2832 // Retrieve the new target we were called with. | |
2833 Node* object = GetNewTarget(); | |
2834 | |
2835 // Assign the object to the {new.target} variable. This should never lazy | |
2836 // deopt, so it is fine to send invalid bailout id. | |
2837 BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(), | |
2838 BailoutId::None()); | |
2839 return object; | |
2840 } | |
2841 | |
2842 | |
2843 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, | 2780 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, |
2844 Node* not_hole, | 2781 Node* not_hole, |
2845 BailoutId bailout_id) { | 2782 BailoutId bailout_id) { |
2846 IfBuilder hole_check(this); | 2783 IfBuilder hole_check(this); |
2847 Node* the_hole = jsgraph()->TheHoleConstant(); | 2784 Node* the_hole = jsgraph()->TheHoleConstant(); |
2848 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 2785 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
2849 value, the_hole); | 2786 value, the_hole); |
2850 hole_check.If(check); | 2787 hole_check.If(check); |
2851 hole_check.Then(); | 2788 hole_check.Then(); |
2852 Node* error = BuildThrowReferenceError(variable, bailout_id); | 2789 Node* error = BuildThrowReferenceError(variable, bailout_id); |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3734 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, | 3671 float invocation_frequency, LoopAssignmentAnalysis* loop_assignment, |
3735 SourcePositionTable* source_positions, int inlining_id) | 3672 SourcePositionTable* source_positions, int inlining_id) |
3736 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, | 3673 : AstGraphBuilder(local_zone, info, jsgraph, invocation_frequency, |
3737 loop_assignment), | 3674 loop_assignment), |
3738 source_positions_(source_positions), | 3675 source_positions_(source_positions), |
3739 start_position_(info->shared_info()->start_position(), inlining_id) {} | 3676 start_position_(info->shared_info()->start_position(), inlining_id) {} |
3740 | 3677 |
3741 } // namespace compiler | 3678 } // namespace compiler |
3742 } // namespace internal | 3679 } // namespace internal |
3743 } // namespace v8 | 3680 } // namespace v8 |
OLD | NEW |