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 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
7 | 7 |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/hashmap.h" | 10 #include "src/base/hashmap.h" |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 typedef typename Types::Expression ExpressionT; | 207 typedef typename Types::Expression ExpressionT; |
208 typedef typename Types::Identifier IdentifierT; | 208 typedef typename Types::Identifier IdentifierT; |
209 typedef typename Types::FormalParameter FormalParameterT; | 209 typedef typename Types::FormalParameter FormalParameterT; |
210 typedef typename Types::FormalParameters FormalParametersT; | 210 typedef typename Types::FormalParameters FormalParametersT; |
211 typedef typename Types::FunctionLiteral FunctionLiteralT; | 211 typedef typename Types::FunctionLiteral FunctionLiteralT; |
212 typedef typename Types::Literal LiteralT; | 212 typedef typename Types::Literal LiteralT; |
213 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; | 213 typedef typename Types::ObjectLiteralProperty ObjectLiteralPropertyT; |
214 typedef typename Types::StatementList StatementListT; | 214 typedef typename Types::StatementList StatementListT; |
215 typedef typename v8::internal::ExpressionClassifier<Types> | 215 typedef typename v8::internal::ExpressionClassifier<Types> |
216 ExpressionClassifier; | 216 ExpressionClassifier; |
| 217 typedef typename Types::Block BlockT; |
217 | 218 |
218 // All implementation-specific methods must be called through this. | 219 // All implementation-specific methods must be called through this. |
219 Impl* impl() { return static_cast<Impl*>(this); } | 220 Impl* impl() { return static_cast<Impl*>(this); } |
220 const Impl* impl() const { return static_cast<const Impl*>(this); } | 221 const Impl* impl() const { return static_cast<const Impl*>(this); } |
221 | 222 |
222 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, | 223 ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit, |
223 v8::Extension* extension, AstValueFactory* ast_value_factory, | 224 v8::Extension* extension, AstValueFactory* ast_value_factory, |
224 ParserRecorder* log) | 225 ParserRecorder* log) |
225 : scope_state_(nullptr), | 226 : scope_state_(nullptr), |
226 function_state_(nullptr), | 227 function_state_(nullptr), |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 1171 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
1171 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1172 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
1172 ExpressionT ParseNewTargetExpression(bool* ok); | 1173 ExpressionT ParseNewTargetExpression(bool* ok); |
1173 | 1174 |
1174 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); | 1175 void ParseFormalParameter(FormalParametersT* parameters, bool* ok); |
1175 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); | 1176 void ParseFormalParameterList(FormalParametersT* parameters, bool* ok); |
1176 void CheckArityRestrictions(int param_count, FunctionKind function_type, | 1177 void CheckArityRestrictions(int param_count, FunctionKind function_type, |
1177 bool has_rest, int formals_start_pos, | 1178 bool has_rest, int formals_start_pos, |
1178 int formals_end_pos, bool* ok); | 1179 int formals_end_pos, bool* ok); |
1179 | 1180 |
| 1181 BlockT ParseVariableDeclarations(VariableDeclarationContext var_context, |
| 1182 DeclarationParsingResult* parsing_result, |
| 1183 ZoneList<const AstRawString*>* names, |
| 1184 bool* ok); |
| 1185 |
1180 bool IsNextLetKeyword(); | 1186 bool IsNextLetKeyword(); |
1181 bool IsTrivialExpression(); | 1187 bool IsTrivialExpression(); |
1182 | 1188 |
1183 // Checks if the expression is a valid reference expression (e.g., on the | 1189 // Checks if the expression is a valid reference expression (e.g., on the |
1184 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 1190 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
1185 // we allow calls for web compatibility and rewrite them to a runtime throw. | 1191 // we allow calls for web compatibility and rewrite them to a runtime throw. |
1186 ExpressionT CheckAndRewriteReferenceExpression( | 1192 ExpressionT CheckAndRewriteReferenceExpression( |
1187 ExpressionT expression, int beg_pos, int end_pos, | 1193 ExpressionT expression, int beg_pos, int end_pos, |
1188 MessageTemplate::Template message, bool* ok); | 1194 MessageTemplate::Template message, bool* ok); |
1189 ExpressionT CheckAndRewriteReferenceExpression( | 1195 ExpressionT CheckAndRewriteReferenceExpression( |
(...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3403 } | 3409 } |
3404 } | 3410 } |
3405 | 3411 |
3406 for (int i = 0; i < parameters->Arity(); ++i) { | 3412 for (int i = 0; i < parameters->Arity(); ++i) { |
3407 auto parameter = parameters->at(i); | 3413 auto parameter = parameters->at(i); |
3408 impl()->DeclareFormalParameter(parameters->scope, parameter); | 3414 impl()->DeclareFormalParameter(parameters->scope, parameter); |
3409 } | 3415 } |
3410 } | 3416 } |
3411 | 3417 |
3412 template <typename Impl> | 3418 template <typename Impl> |
| 3419 typename ParserBase<Impl>::BlockT ParserBase<Impl>::ParseVariableDeclarations( |
| 3420 VariableDeclarationContext var_context, |
| 3421 DeclarationParsingResult* parsing_result, |
| 3422 ZoneList<const AstRawString*>* names, bool* ok) { |
| 3423 // VariableDeclarations :: |
| 3424 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
| 3425 // |
| 3426 // ES6: |
| 3427 // FIXME(marja, nikolaos): Add an up-to-date comment about ES6 variable |
| 3428 // declaration syntax. |
| 3429 |
| 3430 DeclarationParsingResult temp_result; |
| 3431 if (parsing_result == nullptr) { |
| 3432 parsing_result = &temp_result; |
| 3433 } |
| 3434 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| 3435 parsing_result->descriptor.declaration_pos = peek_position(); |
| 3436 parsing_result->descriptor.initialization_pos = peek_position(); |
| 3437 |
| 3438 BlockT init_block = impl()->NullBlock(); |
| 3439 if (var_context != kForStatement) { |
| 3440 init_block = impl()->NewBlock(nullptr, 1, true, |
| 3441 parsing_result->descriptor.declaration_pos); |
| 3442 } |
| 3443 |
| 3444 switch (peek()) { |
| 3445 case Token::VAR: |
| 3446 parsing_result->descriptor.mode = VAR; |
| 3447 Consume(Token::VAR); |
| 3448 break; |
| 3449 case Token::CONST: |
| 3450 Consume(Token::CONST); |
| 3451 DCHECK(var_context != kStatement); |
| 3452 parsing_result->descriptor.mode = CONST; |
| 3453 break; |
| 3454 case Token::LET: |
| 3455 Consume(Token::LET); |
| 3456 DCHECK(var_context != kStatement); |
| 3457 parsing_result->descriptor.mode = LET; |
| 3458 break; |
| 3459 default: |
| 3460 UNREACHABLE(); // by current callers |
| 3461 break; |
| 3462 } |
| 3463 |
| 3464 parsing_result->descriptor.scope = scope(); |
| 3465 parsing_result->descriptor.hoist_scope = nullptr; |
| 3466 |
| 3467 // The scope of a var/const declared variable anywhere inside a function |
| 3468 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
| 3469 // of a let declared variable is the scope of the immediately enclosing |
| 3470 // block. |
| 3471 int bindings_start = peek_position(); |
| 3472 do { |
| 3473 // Parse binding pattern. |
| 3474 FuncNameInferrer::State fni_state(fni_); |
| 3475 |
| 3476 ExpressionT pattern = impl()->EmptyExpression(); |
| 3477 int decl_pos = peek_position(); |
| 3478 { |
| 3479 ExpressionClassifier pattern_classifier(this); |
| 3480 pattern = ParsePrimaryExpression(CHECK_OK_CUSTOM(NullBlock)); |
| 3481 |
| 3482 ValidateBindingPattern(CHECK_OK_CUSTOM(NullBlock)); |
| 3483 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) { |
| 3484 ValidateLetPattern(CHECK_OK_CUSTOM(NullBlock)); |
| 3485 } |
| 3486 } |
| 3487 |
| 3488 Scanner::Location variable_loc = scanner()->location(); |
| 3489 bool single_name = impl()->IsIdentifier(pattern); |
| 3490 |
| 3491 if (single_name && fni_ != nullptr) { |
| 3492 impl()->PushVariableName(fni_, impl()->AsIdentifier(pattern)); |
| 3493 } |
| 3494 |
| 3495 ExpressionT value = impl()->EmptyExpression(); |
| 3496 int initializer_position = kNoSourcePosition; |
| 3497 if (Check(Token::ASSIGN)) { |
| 3498 ExpressionClassifier classifier(this); |
| 3499 value = ParseAssignmentExpression(var_context != kForStatement, |
| 3500 CHECK_OK_CUSTOM(NullBlock)); |
| 3501 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullBlock)); |
| 3502 variable_loc.end_pos = scanner()->location().end_pos; |
| 3503 |
| 3504 if (!parsing_result->first_initializer_loc.IsValid()) { |
| 3505 parsing_result->first_initializer_loc = variable_loc; |
| 3506 } |
| 3507 |
| 3508 // Don't infer if it is "a = function(){...}();"-like expression. |
| 3509 if (single_name && fni_ != nullptr) { |
| 3510 if (!value->IsCall() && !value->IsCallNew()) { |
| 3511 fni_->Infer(); |
| 3512 } else { |
| 3513 fni_->RemoveLastFunction(); |
| 3514 } |
| 3515 } |
| 3516 |
| 3517 impl()->SetFunctionNameFromIdentifierRef(value, pattern); |
| 3518 |
| 3519 // End position of the initializer is after the assignment expression. |
| 3520 initializer_position = scanner()->location().end_pos; |
| 3521 } else { |
| 3522 if (var_context != kForStatement || !PeekInOrOf()) { |
| 3523 // ES6 'const' and binding patterns require initializers. |
| 3524 if (parsing_result->descriptor.mode == CONST || |
| 3525 !impl()->IsIdentifier(pattern)) { |
| 3526 impl()->ReportMessageAt( |
| 3527 Scanner::Location(decl_pos, scanner()->location().end_pos), |
| 3528 MessageTemplate::kDeclarationMissingInitializer, |
| 3529 !impl()->IsIdentifier(pattern) ? "destructuring" : "const"); |
| 3530 *ok = false; |
| 3531 return impl()->NullBlock(); |
| 3532 } |
| 3533 // 'let x' initializes 'x' to undefined. |
| 3534 if (parsing_result->descriptor.mode == LET) { |
| 3535 value = impl()->GetLiteralUndefined(position()); |
| 3536 } |
| 3537 } |
| 3538 |
| 3539 // End position of the initializer is after the variable. |
| 3540 initializer_position = position(); |
| 3541 } |
| 3542 |
| 3543 typename DeclarationParsingResult::Declaration decl( |
| 3544 pattern, initializer_position, value); |
| 3545 if (var_context == kForStatement) { |
| 3546 // Save the declaration for further handling in ParseForStatement. |
| 3547 parsing_result->declarations.Add(decl); |
| 3548 } else { |
| 3549 // Immediately declare the variable otherwise. This avoids O(N^2) |
| 3550 // behavior (where N is the number of variables in a single |
| 3551 // declaration) in the PatternRewriter having to do with removing |
| 3552 // and adding VariableProxies to the Scope (see bug 4699). |
| 3553 impl()->DeclareAndInitializeVariables(init_block, |
| 3554 &parsing_result->descriptor, &decl, |
| 3555 names, CHECK_OK_CUSTOM(NullBlock)); |
| 3556 } |
| 3557 } while (Check(Token::COMMA)); |
| 3558 |
| 3559 parsing_result->bindings_loc = |
| 3560 Scanner::Location(bindings_start, scanner()->location().end_pos); |
| 3561 |
| 3562 DCHECK(*ok); |
| 3563 return init_block; |
| 3564 } |
| 3565 |
| 3566 template <typename Impl> |
3413 void ParserBase<Impl>::CheckArityRestrictions(int param_count, | 3567 void ParserBase<Impl>::CheckArityRestrictions(int param_count, |
3414 FunctionKind function_kind, | 3568 FunctionKind function_kind, |
3415 bool has_rest, | 3569 bool has_rest, |
3416 int formals_start_pos, | 3570 int formals_start_pos, |
3417 int formals_end_pos, bool* ok) { | 3571 int formals_end_pos, bool* ok) { |
3418 if (IsGetterFunction(function_kind)) { | 3572 if (IsGetterFunction(function_kind)) { |
3419 if (param_count != 0) { | 3573 if (param_count != 0) { |
3420 impl()->ReportMessageAt( | 3574 impl()->ReportMessageAt( |
3421 Scanner::Location(formals_start_pos, formals_end_pos), | 3575 Scanner::Location(formals_start_pos, formals_end_pos), |
3422 MessageTemplate::kBadGetterArity); | 3576 MessageTemplate::kBadGetterArity); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3823 has_seen_constructor_ = true; | 3977 has_seen_constructor_ = true; |
3824 return; | 3978 return; |
3825 } | 3979 } |
3826 } | 3980 } |
3827 | 3981 |
3828 | 3982 |
3829 } // namespace internal | 3983 } // namespace internal |
3830 } // namespace v8 | 3984 } // namespace v8 |
3831 | 3985 |
3832 #endif // V8_PARSING_PARSER_BASE_H | 3986 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |