OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1127 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1128 : FunctionLiteral::NAMED_EXPRESSION) | 1128 : FunctionLiteral::NAMED_EXPRESSION) |
1129 : FunctionLiteral::DECLARATION; | 1129 : FunctionLiteral::DECLARATION; |
1130 bool ok = true; | 1130 bool ok = true; |
1131 | 1131 |
1132 if (shared_info->is_arrow()) { | 1132 if (shared_info->is_arrow()) { |
1133 Scope* scope = NewScope(scope_, ARROW_SCOPE); | 1133 Scope* scope = NewScope(scope_, ARROW_SCOPE); |
1134 scope->set_start_position(shared_info->start_position()); | 1134 scope->set_start_position(shared_info->start_position()); |
1135 FormalParameterErrorLocations error_locs; | 1135 FormalParameterErrorLocations error_locs; |
1136 bool has_rest = false; | 1136 bool has_rest = false; |
1137 bool has_initializers = false; | |
1138 ZoneList<Expression*>* initializers = | |
1139 new (zone()) ZoneList<Expression*>(0, zone()); | |
1137 if (Check(Token::LPAREN)) { | 1140 if (Check(Token::LPAREN)) { |
1138 // '(' StrictFormalParameters ')' | 1141 // '(' StrictFormalParameters ')' |
1139 ParseFormalParameterList(scope, &error_locs, &has_rest, &ok); | 1142 ParseFormalParameterList(scope, &error_locs, initializers, |
1143 &has_initializers, &has_rest, &ok); | |
1140 if (ok) ok = Check(Token::RPAREN); | 1144 if (ok) ok = Check(Token::RPAREN); |
1141 } else { | 1145 } else { |
1142 // BindingIdentifier | 1146 // BindingIdentifier |
1143 ParseFormalParameter(scope, &error_locs, has_rest, &ok); | 1147 ParseFormalParameter(scope, &error_locs, nullptr, nullptr, has_rest, |
1148 &ok); | |
1144 } | 1149 } |
1145 | 1150 |
1146 if (ok) { | 1151 if (ok) { |
1147 ExpressionClassifier classifier; | 1152 ExpressionClassifier classifier; |
1148 Expression* expression = ParseArrowFunctionLiteral( | 1153 Expression* expression = ParseArrowFunctionLiteral( |
1149 scope, error_locs, has_rest, &classifier, &ok); | 1154 scope, error_locs, has_rest, &classifier, &ok); |
1150 ValidateExpression(&classifier, &ok); | 1155 ValidateExpression(&classifier, &ok); |
1151 if (ok) { | 1156 if (ok) { |
1152 // Scanning must end at the same position that was recorded | 1157 // Scanning must end at the same position that was recorded |
1153 // previously. If not, parsing has been interrupted due to a stack | 1158 // previously. If not, parsing has been interrupted due to a stack |
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2057 // initialization code. Thus, inside the 'with' statement, we need | 2062 // initialization code. Thus, inside the 'with' statement, we need |
2058 // both access to the static and the dynamic context chain; the | 2063 // both access to the static and the dynamic context chain; the |
2059 // runtime needs to provide both. | 2064 // runtime needs to provide both. |
2060 if (resolve && var != NULL) { | 2065 if (resolve && var != NULL) { |
2061 proxy->BindTo(var); | 2066 proxy->BindTo(var); |
2062 } | 2067 } |
2063 return var; | 2068 return var; |
2064 } | 2069 } |
2065 | 2070 |
2066 | 2071 |
2072 void Parser::ShadowParametersForExpressions(Scope* scope) { | |
2073 scope->ShadowParametersForExpressions(); | |
2074 } | |
2075 | |
2076 | |
2067 // Language extension which is only enabled for source files loaded | 2077 // Language extension which is only enabled for source files loaded |
2068 // through the API's extension mechanism. A native function | 2078 // through the API's extension mechanism. A native function |
2069 // declaration is resolved by looking up the function through a | 2079 // declaration is resolved by looking up the function through a |
2070 // callback provided by the extension. | 2080 // callback provided by the extension. |
2071 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 2081 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
2072 int pos = peek_position(); | 2082 int pos = peek_position(); |
2073 Expect(Token::FUNCTION, CHECK_OK); | 2083 Expect(Token::FUNCTION, CHECK_OK); |
2074 // Allow "eval" or "arguments" for backward compatibility. | 2084 // Allow "eval" or "arguments" for backward compatibility. |
2075 const AstRawString* name = | 2085 const AstRawString* name = |
2076 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); | 2086 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); |
(...skipping 1438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3515 | 3525 |
3516 inner_scope->set_end_position(scanner()->location().end_pos); | 3526 inner_scope->set_end_position(scanner()->location().end_pos); |
3517 inner_block->set_scope(inner_scope); | 3527 inner_block->set_scope(inner_scope); |
3518 scope_ = for_scope; | 3528 scope_ = for_scope; |
3519 | 3529 |
3520 outer_loop->Initialize(NULL, NULL, NULL, inner_block); | 3530 outer_loop->Initialize(NULL, NULL, NULL, inner_block); |
3521 return outer_block; | 3531 return outer_block; |
3522 } | 3532 } |
3523 | 3533 |
3524 | 3534 |
3535 ZoneList<Statement*>* Parser::DesugarInitializeParameters( | |
3536 Scope* scope, bool has_initializers, ZoneList<Expression*>* initializers) { | |
3537 DCHECK(scope->is_function_scope()); | |
3538 | |
arv (Not doing code reviews)
2015/05/06 20:32:38
How about adding a comment block explaining how th
| |
3539 if (has_initializers) { | |
3540 ShadowParametersForExpressions(scope); | |
3541 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone()); | |
3542 for (int i = 0; i < initializers->length(); ++i) { | |
3543 Expression* initializer = initializers->at(i); | |
3544 | |
3545 // Position of parameter VariableProxy, for hole-checking | |
3546 int pos = scope->parameter_position(i); | |
3547 | |
3548 // Lexically declare the initialized variable | |
3549 static const VariableMode mode = LET; | |
3550 VariableProxy* proxy = | |
3551 NewUnresolved(scope->parameter(i)->raw_name(), mode); | |
3552 VariableDeclaration* declaration = factory()->NewVariableDeclaration( | |
3553 proxy, mode, scope, RelocInfo::kNoPosition); | |
3554 bool ok = true; | |
3555 proxy = factory()->NewVariableProxy(Declare(declaration, true, &ok), pos); | |
3556 DCHECK(ok); | |
3557 proxy->var()->set_maybe_assigned(); | |
3558 | |
3559 const AstRawString* fn_name = ast_value_factory()->empty_string(); | |
3560 const Runtime::Function* arguments = | |
3561 Runtime::FunctionForId(Runtime::kInlineArguments); | |
arv (Not doing code reviews)
2015/05/06 20:32:38
I think Andreas wanted:
function f(x = expr) {}
caitp (gmail)
2015/05/06 20:42:55
I don't think bounds-checking is needed --- at lea
| |
3562 ZoneList<Expression*>* arguments_i0 = | |
3563 new (zone()) ZoneList<Expression*>(0, zone()); | |
3564 arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), | |
3565 zone()); | |
3566 | |
3567 // TODO(caitp): ensure proper TDZ behaviour --- need hole-check for | |
3568 // all parameter bindings, including ones without initializers | |
3569 if (initializer) { | |
3570 // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i); | |
3571 ZoneList<Expression*>* arguments_i1 = | |
3572 new (zone()) ZoneList<Expression*>(0, zone()); | |
3573 arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), | |
3574 zone()); | |
3575 | |
3576 Expression* arg_or_default = factory()->NewConditional( | |
3577 // condition: | |
3578 factory()->NewCompareOperation( | |
3579 Token::EQ_STRICT, | |
3580 factory()->NewCallRuntime(fn_name, arguments, arguments_i0, | |
3581 RelocInfo::kNoPosition), | |
3582 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | |
3583 RelocInfo::kNoPosition), | |
3584 // if true: | |
3585 initializer, | |
3586 // if false: | |
3587 factory()->NewCallRuntime(fn_name, arguments, arguments_i1, | |
3588 RelocInfo::kNoPosition), | |
3589 RelocInfo::kNoPosition); | |
3590 | |
3591 Expression* assign = factory()->NewAssignment( | |
3592 Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition); | |
3593 | |
3594 body->Add( | |
3595 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition), | |
3596 zone()); | |
3597 proxy->var()->set_initializer_position(initializer->position()); | |
3598 } else { | |
3599 // let <name> = %_Arguments(i) | |
3600 Expression* assign = factory()->NewAssignment( | |
3601 Token::INIT_LET, proxy, | |
3602 factory()->NewCallRuntime(fn_name, arguments, arguments_i0, | |
3603 RelocInfo::kNoPosition), | |
3604 RelocInfo::kNoPosition); | |
3605 body->Add( | |
3606 factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition), | |
3607 zone()); | |
3608 proxy->var()->set_initializer_position(pos); | |
3609 } | |
3610 } | |
3611 return body; | |
3612 } else { | |
arv (Not doing code reviews)
2015/05/06 20:32:38
no else after return
| |
3613 // If hasParameterExpressions is false, remove the unnecessary parameter | |
3614 // block scopes. | |
3615 ZoneList<Scope*>* scopes = scope->inner_scopes(); | |
3616 for (int i = 0; i < scopes->length(); ++i) { | |
3617 Scope* scope = scopes->at(i); | |
3618 DCHECK(scope->is_block_scope()); | |
3619 scope->FinalizeBlockScope(); | |
3620 } | |
3621 return nullptr; | |
3622 } | |
3623 } | |
3624 | |
3625 | |
3525 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, | 3626 Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
3526 bool* ok) { | 3627 bool* ok) { |
3527 // ForStatement :: | 3628 // ForStatement :: |
3528 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 3629 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
3529 | 3630 |
3530 int stmt_pos = peek_position(); | 3631 int stmt_pos = peek_position(); |
3531 bool is_const = false; | 3632 bool is_const = false; |
3532 Statement* init = NULL; | 3633 Statement* init = NULL; |
3533 ZoneList<const AstRawString*> lexical_bindings(1, zone()); | 3634 ZoneList<const AstRawString*> lexical_bindings(1, zone()); |
3534 | 3635 |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3925 error_locs->reserved = param_location; | 4026 error_locs->reserved = param_location; |
3926 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) | 4027 if (!error_locs->undefined.IsValid() && IsUndefined(raw_name)) |
3927 error_locs->undefined = param_location; | 4028 error_locs->undefined = param_location; |
3928 | 4029 |
3929 // When the formal parameter was originally seen, it was parsed as a | 4030 // When the formal parameter was originally seen, it was parsed as a |
3930 // VariableProxy and recorded as unresolved in the scope. Here we undo that | 4031 // VariableProxy and recorded as unresolved in the scope. Here we undo that |
3931 // parse-time side-effect. | 4032 // parse-time side-effect. |
3932 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); | 4033 parser_->scope_->RemoveUnresolved(expr->AsVariableProxy()); |
3933 | 4034 |
3934 bool is_rest = false; | 4035 bool is_rest = false; |
3935 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest); | 4036 int pos = expr->position(); |
4037 bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos); | |
3936 | 4038 |
3937 if (is_duplicate) { | 4039 if (is_duplicate) { |
3938 // Arrow function parameter lists are parsed as StrictFormalParameters, | 4040 // Arrow function parameter lists are parsed as StrictFormalParameters, |
3939 // which means that they cannot have duplicates. Note that this is a subset | 4041 // which means that they cannot have duplicates. Note that this is a subset |
3940 // of the restrictions placed on parameters to functions whose body is | 4042 // of the restrictions placed on parameters to functions whose body is |
3941 // strict. | 4043 // strict. |
3942 ReportMessageAt(param_location, | 4044 ReportMessageAt(param_location, |
3943 "duplicate_arrow_function_formal_parameter"); | 4045 "duplicate_arrow_function_formal_parameter"); |
3944 *ok = false; | 4046 *ok = false; |
3945 return; | 4047 return; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4054 // expressions. This also marks the FunctionState as a generator. | 4156 // expressions. This also marks the FunctionState as a generator. |
4055 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 4157 Variable* temp = scope_->DeclarationScope()->NewTemporary( |
4056 ast_value_factory()->dot_generator_object_string()); | 4158 ast_value_factory()->dot_generator_object_string()); |
4057 function_state.set_generator_object_variable(temp); | 4159 function_state.set_generator_object_variable(temp); |
4058 } | 4160 } |
4059 | 4161 |
4060 bool has_rest = false; | 4162 bool has_rest = false; |
4061 Expect(Token::LPAREN, CHECK_OK); | 4163 Expect(Token::LPAREN, CHECK_OK); |
4062 int start_position = scanner()->location().beg_pos; | 4164 int start_position = scanner()->location().beg_pos; |
4063 scope_->set_start_position(start_position); | 4165 scope_->set_start_position(start_position); |
4166 ZoneList<Expression*>* initializers = | |
4167 new (zone()) ZoneList<Expression*>(0, zone()); | |
4168 bool has_initializers = false; | |
4064 num_parameters = | 4169 num_parameters = |
4065 ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK); | 4170 ParseFormalParameterList(scope, &error_locs, initializers, |
4171 &has_initializers, &has_rest, CHECK_OK); | |
4066 Expect(Token::RPAREN, CHECK_OK); | 4172 Expect(Token::RPAREN, CHECK_OK); |
4067 int formals_end_position = scanner()->location().end_pos; | 4173 int formals_end_position = scanner()->location().end_pos; |
4068 | 4174 |
4069 CheckArityRestrictions(num_parameters, arity_restriction, start_position, | 4175 CheckArityRestrictions(num_parameters, arity_restriction, start_position, |
4070 formals_end_position, CHECK_OK); | 4176 formals_end_position, CHECK_OK); |
4071 | 4177 |
4072 Expect(Token::LBRACE, CHECK_OK); | 4178 Expect(Token::LBRACE, CHECK_OK); |
4073 | 4179 |
4074 // If we have a named function expression, we add a local variable | 4180 // If we have a named function expression, we add a local variable |
4075 // declaration to the body of the function with the name of the | 4181 // declaration to the body of the function with the name of the |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4134 parenthesized_function_ = false; // The bit was set for this function only. | 4240 parenthesized_function_ = false; // The bit was set for this function only. |
4135 | 4241 |
4136 if (is_lazily_parsed) { | 4242 if (is_lazily_parsed) { |
4137 for (Scope* s = scope_->outer_scope(); | 4243 for (Scope* s = scope_->outer_scope(); |
4138 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) { | 4244 s != nullptr && (s != s->DeclarationScope()); s = s->outer_scope()) { |
4139 s->ForceContextAllocation(); | 4245 s->ForceContextAllocation(); |
4140 } | 4246 } |
4141 SkipLazyFunctionBody(&materialized_literal_count, | 4247 SkipLazyFunctionBody(&materialized_literal_count, |
4142 &expected_property_count, CHECK_OK); | 4248 &expected_property_count, CHECK_OK); |
4143 } else { | 4249 } else { |
4144 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, | 4250 body = DesugarInitializeParameters(scope, has_initializers, initializers); |
4145 kind, CHECK_OK); | 4251 if (has_initializers) { |
4252 // TODO(caitp): Function body scope must be a declaration scope | |
4253 Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE); | |
4254 function_body_scope->set_start_position(scope->start_position()); | |
4255 function_body_scope->SetScopeName(function_name); | |
4256 BlockState function_body_state(&scope_, function_body_scope); | |
4257 ZoneList<Statement*>* inner_body = ParseEagerFunctionBody( | |
4258 function_name, pos, fvar, fvar_init_op, kind, CHECK_OK); | |
4259 scope->set_end_position(function_body_scope->end_position()); | |
4260 body->AddAll(*inner_body, zone()); | |
4261 } else { | |
4262 body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, | |
4263 kind, CHECK_OK); | |
4264 } | |
4146 materialized_literal_count = function_state.materialized_literal_count(); | 4265 materialized_literal_count = function_state.materialized_literal_count(); |
4147 expected_property_count = function_state.expected_property_count(); | 4266 expected_property_count = function_state.expected_property_count(); |
4148 handler_count = function_state.handler_count(); | 4267 handler_count = function_state.handler_count(); |
4149 | 4268 |
4150 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { | 4269 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { |
4151 if (!function_state.super_location().IsValid()) { | 4270 if (!function_state.super_location().IsValid()) { |
4152 ReportMessageAt(function_name_location, | 4271 ReportMessageAt(function_name_location, |
4153 "strong_super_call_missing", kReferenceError); | 4272 "strong_super_call_missing", kReferenceError); |
4154 *ok = false; | 4273 *ok = false; |
4155 return nullptr; | 4274 return nullptr; |
(...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5891 | 6010 |
5892 Expression* Parser::SpreadCallNew(Expression* function, | 6011 Expression* Parser::SpreadCallNew(Expression* function, |
5893 ZoneList<v8::internal::Expression*>* args, | 6012 ZoneList<v8::internal::Expression*>* args, |
5894 int pos) { | 6013 int pos) { |
5895 args->InsertAt(0, function, zone()); | 6014 args->InsertAt(0, function, zone()); |
5896 | 6015 |
5897 return factory()->NewCallRuntime( | 6016 return factory()->NewCallRuntime( |
5898 ast_value_factory()->reflect_construct_string(), NULL, args, pos); | 6017 ast_value_factory()->reflect_construct_string(), NULL, args, pos); |
5899 } | 6018 } |
5900 } } // namespace v8::internal | 6019 } } // namespace v8::internal |
OLD | NEW |