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 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 Scope* scope = info()->scope(); | 559 Scope* scope = info()->scope(); |
560 | 560 |
561 // Build the arguments object if it is used. | 561 // Build the arguments object if it is used. |
562 BuildArgumentsObject(scope->arguments()); | 562 BuildArgumentsObject(scope->arguments()); |
563 | 563 |
564 // Build rest arguments array if it is used. | 564 // Build rest arguments array if it is used. |
565 int rest_index; | 565 int rest_index; |
566 Variable* rest_parameter = scope->rest_parameter(&rest_index); | 566 Variable* rest_parameter = scope->rest_parameter(&rest_index); |
567 BuildRestArgumentsArray(rest_parameter, rest_index); | 567 BuildRestArgumentsArray(rest_parameter, rest_index); |
568 | 568 |
569 // Build .this_function var if it is used. | 569 // Build assignment to {.this_function} variable if it is used. |
570 BuildThisFunctionVar(scope->this_function_var()); | 570 BuildThisFunctionVariable(scope->this_function_var()); |
571 | 571 |
572 if (scope->new_target_var() != nullptr) { | 572 // Build assignment to {new.target} variable if it is used. |
573 SetStackOverflow(); | 573 BuildNewTargetVariable(scope->new_target_var()); |
574 } | |
575 | 574 |
576 // Emit tracing call if requested to do so. | 575 // Emit tracing call if requested to do so. |
577 if (FLAG_trace) { | 576 if (FLAG_trace) { |
578 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); | 577 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); |
579 } | 578 } |
580 | 579 |
581 // Visit illegal re-declaration and bail out if it exists. | 580 // Visit illegal re-declaration and bail out if it exists. |
582 if (scope->HasIllegalRedeclaration()) { | 581 if (scope->HasIllegalRedeclaration()) { |
583 AstEffectContext for_effect(this); | 582 AstEffectContext for_effect(this); |
584 scope->VisitIllegalRedeclaration(this); | 583 scope->VisitIllegalRedeclaration(this); |
(...skipping 2552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3137 | 3136 |
3138 // Allocate and initialize a new arguments object. | 3137 // Allocate and initialize a new arguments object. |
3139 Node* callee = GetFunctionClosure(); | 3138 Node* callee = GetFunctionClosure(); |
3140 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); | 3139 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); |
3141 Node* object = NewNode(op, callee); | 3140 Node* object = NewNode(op, callee); |
3142 | 3141 |
3143 // Assign the object to the arguments variable. | 3142 // Assign the object to the arguments variable. |
3144 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 3143 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
3145 // This should never lazy deopt, so it is fine to send invalid bailout id. | 3144 // This should never lazy deopt, so it is fine to send invalid bailout id. |
3146 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3145 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3147 VectorSlotPair feedback; | 3146 BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(), |
3148 BuildVariableAssignment(arguments, object, Token::ASSIGN, feedback, | |
3149 BailoutId::None(), states); | 3147 BailoutId::None(), states); |
3150 | |
3151 return object; | 3148 return object; |
3152 } | 3149 } |
3153 | 3150 |
3154 | 3151 |
3155 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { | 3152 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { |
3156 if (rest == NULL) return NULL; | 3153 if (rest == NULL) return NULL; |
3157 | 3154 |
3158 DCHECK(index >= 0); | 3155 DCHECK(index >= 0); |
3159 const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 2); | 3156 const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 2); |
3160 Node* object = NewNode(op, jsgraph()->SmiConstant(index), | 3157 Node* object = NewNode(op, jsgraph()->SmiConstant(index), |
3161 jsgraph()->SmiConstant(language_mode())); | 3158 jsgraph()->SmiConstant(language_mode())); |
3162 | 3159 |
3163 // Assign the object to the rest array | 3160 // Assign the object to the rest parameter variable. |
3164 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3161 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
3165 // This should never lazy deopt, so it is fine to send invalid bailout id. | 3162 // This should never lazy deopt, so it is fine to send invalid bailout id. |
3166 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3163 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3167 VectorSlotPair feedback; | 3164 BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(), |
3168 BuildVariableAssignment(rest, object, Token::ASSIGN, feedback, | |
3169 BailoutId::None(), states); | 3165 BailoutId::None(), states); |
3170 | |
3171 return object; | 3166 return object; |
3172 } | 3167 } |
3173 | 3168 |
3174 | 3169 |
3175 Node* AstGraphBuilder::BuildThisFunctionVar(Variable* this_function_var) { | 3170 Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) { |
3176 if (this_function_var == nullptr) return nullptr; | 3171 if (this_function_var == nullptr) return nullptr; |
3177 | 3172 |
| 3173 // Retrieve the closure we were called with. |
3178 Node* this_function = GetFunctionClosure(); | 3174 Node* this_function = GetFunctionClosure(); |
| 3175 |
| 3176 // Assign the object to the {.this_function} variable. |
3179 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3177 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3180 VectorSlotPair feedback; | |
3181 BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST, | 3178 BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST, |
3182 feedback, BailoutId::None(), states); | 3179 VectorSlotPair(), BailoutId::None(), states); |
3183 return this_function; | 3180 return this_function; |
3184 } | 3181 } |
3185 | 3182 |
3186 | 3183 |
| 3184 Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) { |
| 3185 if (new_target_var == nullptr) return nullptr; |
| 3186 |
| 3187 // Retrieve the original constructor in case we are called as a constructor. |
| 3188 const Operator* op = |
| 3189 javascript()->CallRuntime(Runtime::kGetOriginalConstructor, 0); |
| 3190 Node* object = NewNode(op); |
| 3191 |
| 3192 // Assign the object to the {new.target} variable. |
| 3193 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
| 3194 BuildVariableAssignment(new_target_var, object, Token::INIT_CONST, |
| 3195 VectorSlotPair(), BailoutId::None(), states); |
| 3196 return object; |
| 3197 } |
| 3198 |
| 3199 |
3187 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 3200 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, |
3188 Node* not_hole) { | 3201 Node* not_hole) { |
3189 Node* the_hole = jsgraph()->TheHoleConstant(); | 3202 Node* the_hole = jsgraph()->TheHoleConstant(); |
3190 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 3203 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); |
3191 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 3204 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, |
3192 for_hole, not_hole); | 3205 for_hole, not_hole); |
3193 } | 3206 } |
3194 | 3207 |
3195 | 3208 |
3196 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable, | 3209 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable, |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4162 // Phi does not exist yet, introduce one. | 4175 // Phi does not exist yet, introduce one. |
4163 value = NewPhi(inputs, value, control); | 4176 value = NewPhi(inputs, value, control); |
4164 value->ReplaceInput(inputs - 1, other); | 4177 value->ReplaceInput(inputs - 1, other); |
4165 } | 4178 } |
4166 return value; | 4179 return value; |
4167 } | 4180 } |
4168 | 4181 |
4169 } // namespace compiler | 4182 } // namespace compiler |
4170 } // namespace internal | 4183 } // namespace internal |
4171 } // namespace v8 | 4184 } // namespace v8 |
OLD | NEW |