Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/parsing/parser.cc

Issue 2380663002: Revert of [parser] Refactor of ParseClass* and ParseNativeDeclaration (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 ReportMessage(MessageTemplate::kParamDupe); 1525 ReportMessage(MessageTemplate::kParamDupe);
1526 } 1526 }
1527 return nullptr; 1527 return nullptr;
1528 } 1528 }
1529 if (sloppy_mode_block_scope_function_redefinition) { 1529 if (sloppy_mode_block_scope_function_redefinition) {
1530 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; 1530 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1531 } 1531 }
1532 return variable; 1532 return variable;
1533 } 1533 }
1534 1534
1535 // Language extension which is only enabled for source files loaded
1536 // through the API's extension mechanism. A native function
1537 // declaration is resolved by looking up the function through a
1538 // callback provided by the extension.
1539 Statement* Parser::ParseNativeDeclaration(bool* ok) {
1540 int pos = peek_position();
1541 Expect(Token::FUNCTION, CHECK_OK);
1542 // Allow "eval" or "arguments" for backward compatibility.
1543 const AstRawString* name =
1544 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1545 Expect(Token::LPAREN, CHECK_OK);
1546 bool done = (peek() == Token::RPAREN);
1547 while (!done) {
1548 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
1549 done = (peek() == Token::RPAREN);
1550 if (!done) {
1551 Expect(Token::COMMA, CHECK_OK);
1552 }
1553 }
1554 Expect(Token::RPAREN, CHECK_OK);
1555 Expect(Token::SEMICOLON, CHECK_OK);
1556
1557 // Make sure that the function containing the native declaration
1558 // isn't lazily compiled. The extension structures are only
1559 // accessible while parsing the first time not when reparsing
1560 // because of lazy compilation.
1561 GetClosureScope()->ForceEagerCompilation();
1562
1563 // TODO(1240846): It's weird that native function declarations are
1564 // introduced dynamically when we meet their declarations, whereas
1565 // other functions are set up when entering the surrounding scope.
1566 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1567 NativeFunctionLiteral* lit =
1568 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1569 return factory()->NewExpressionStatement(
1570 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1571 kNoSourcePosition),
1572 pos);
1573 }
1574
1575 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
1576 bool default_export, bool* ok) {
1577 // ClassDeclaration ::
1578 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
1579 // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
1580 //
1581 // The anonymous form is allowed iff [default_export] is true.
1582 //
1583 // 'class' is expected to be consumed by the caller.
1584 //
1585 // A ClassDeclaration
1586 //
1587 // class C { ... }
1588 //
1589 // has the same semantics as:
1590 //
1591 // let C = class C { ... };
1592 //
1593 // so rewrite it as such.
1594
1595 int pos = position();
1596
1597 const AstRawString* name;
1598 bool is_strict_reserved;
1599 const AstRawString* variable_name;
1600 if (default_export && (peek() == Token::EXTENDS || peek() == Token::LBRACE)) {
1601 name = ast_value_factory()->default_string();
1602 is_strict_reserved = false;
1603 variable_name = ast_value_factory()->star_default_star_string();
1604 } else {
1605 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1606 variable_name = name;
1607 }
1608
1609 ExpressionClassifier no_classifier(this);
1610 Expression* value = ParseClassLiteral(name, scanner()->location(),
1611 is_strict_reserved, pos, CHECK_OK);
1612
1613 Declaration* decl = DeclareVariable(variable_name, LET, pos, CHECK_OK);
1614 decl->proxy()->var()->set_initializer_position(position());
1615 Assignment* assignment =
1616 factory()->NewAssignment(Token::INIT, decl->proxy(), value, pos);
1617 Statement* assignment_statement =
1618 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1619 if (names) names->Add(variable_name, zone());
1620 return assignment_statement;
1621 }
1622
1535 Block* Parser::BuildInitializationBlock( 1623 Block* Parser::BuildInitializationBlock(
1536 DeclarationParsingResult* parsing_result, 1624 DeclarationParsingResult* parsing_result,
1537 ZoneList<const AstRawString*>* names, bool* ok) { 1625 ZoneList<const AstRawString*>* names, bool* ok) {
1538 Block* result = factory()->NewBlock( 1626 Block* result = factory()->NewBlock(
1539 NULL, 1, true, parsing_result->descriptor.declaration_pos); 1627 NULL, 1, true, parsing_result->descriptor.declaration_pos);
1540 for (auto declaration : parsing_result->declarations) { 1628 for (auto declaration : parsing_result->declarations) {
1541 PatternRewriter::DeclareAndInitializeVariables( 1629 PatternRewriter::DeclareAndInitializeVariables(
1542 this, result, &(parsing_result->descriptor), &declaration, names, 1630 this, result, &(parsing_result->descriptor), &declaration, names,
1543 CHECK_OK); 1631 CHECK_OK);
1544 } 1632 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) { 1668 !is_async && !(allow_harmony_restrictive_generators() && is_generator)) {
1581 SloppyBlockFunctionStatement* delegate = 1669 SloppyBlockFunctionStatement* delegate =
1582 factory()->NewSloppyBlockFunctionStatement(scope()); 1670 factory()->NewSloppyBlockFunctionStatement(scope());
1583 DeclarationScope* target_scope = GetDeclarationScope(); 1671 DeclarationScope* target_scope = GetDeclarationScope();
1584 target_scope->DeclareSloppyBlockFunction(variable_name, delegate); 1672 target_scope->DeclareSloppyBlockFunction(variable_name, delegate);
1585 return delegate; 1673 return delegate;
1586 } 1674 }
1587 return factory()->NewEmptyStatement(kNoSourcePosition); 1675 return factory()->NewEmptyStatement(kNoSourcePosition);
1588 } 1676 }
1589 1677
1590 Statement* Parser::DeclareClass(const AstRawString* variable_name,
1591 Expression* value,
1592 ZoneList<const AstRawString*>* names,
1593 int class_token_pos, int end_pos, bool* ok) {
1594 Declaration* decl =
1595 DeclareVariable(variable_name, LET, class_token_pos, CHECK_OK);
1596 decl->proxy()->var()->set_initializer_position(end_pos);
1597 Assignment* assignment = factory()->NewAssignment(Token::INIT, decl->proxy(),
1598 value, class_token_pos);
1599 Statement* assignment_statement =
1600 factory()->NewExpressionStatement(assignment, kNoSourcePosition);
1601 if (names) names->Add(variable_name, zone());
1602 return assignment_statement;
1603 }
1604
1605 Statement* Parser::DeclareNative(const AstRawString* name, int pos, bool* ok) {
1606 // Make sure that the function containing the native declaration
1607 // isn't lazily compiled. The extension structures are only
1608 // accessible while parsing the first time not when reparsing
1609 // because of lazy compilation.
1610 GetClosureScope()->ForceEagerCompilation();
1611
1612 // TODO(1240846): It's weird that native function declarations are
1613 // introduced dynamically when we meet their declarations, whereas
1614 // other functions are set up when entering the surrounding scope.
1615 Declaration* decl = DeclareVariable(name, VAR, pos, CHECK_OK);
1616 NativeFunctionLiteral* lit =
1617 factory()->NewNativeFunctionLiteral(name, extension_, kNoSourcePosition);
1618 return factory()->NewExpressionStatement(
1619 factory()->NewAssignment(Token::INIT, decl->proxy(), lit,
1620 kNoSourcePosition),
1621 pos);
1622 }
1623
1624 ZoneList<const AstRawString*>* Parser::DeclareLabel( 1678 ZoneList<const AstRawString*>* Parser::DeclareLabel(
1625 ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) { 1679 ZoneList<const AstRawString*>* labels, VariableProxy* var, bool* ok) {
1626 const AstRawString* label = var->raw_name(); 1680 const AstRawString* label = var->raw_name();
1627 // TODO(1240780): We don't check for redeclaration of labels 1681 // TODO(1240780): We don't check for redeclaration of labels
1628 // during preparsing since keeping track of the set of active 1682 // during preparsing since keeping track of the set of active
1629 // labels requires nontrivial changes to the way scopes are 1683 // labels requires nontrivial changes to the way scopes are
1630 // structured. However, these are probably changes we want to 1684 // structured. However, these are probably changes we want to
1631 // make later anyway so we should go back and fix this then. 1685 // make later anyway so we should go back and fix this then.
1632 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 1686 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
1633 ReportMessage(MessageTemplate::kLabelRedeclaration, label); 1687 ReportMessage(MessageTemplate::kLabelRedeclaration, label);
(...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after
3451 CallClassFieldInitializer( 3505 CallClassFieldInitializer(
3452 constructor->scope(), 3506 constructor->scope(),
3453 constructor->scope()->NewUnresolved( 3507 constructor->scope()->NewUnresolved(
3454 factory(), ast_value_factory()->this_string(), kNoSourcePosition, 3508 factory(), ast_value_factory()->this_string(), kNoSourcePosition,
3455 kNoSourcePosition + 4, THIS_VARIABLE)), 3509 kNoSourcePosition + 4, THIS_VARIABLE)),
3456 kNoSourcePosition); 3510 kNoSourcePosition);
3457 constructor->body()->InsertAt(0, call_initializer, zone()); 3511 constructor->body()->InsertAt(0, call_initializer, zone());
3458 return constructor; 3512 return constructor;
3459 } 3513 }
3460 3514
3461 // If a class name is specified, this method declares the class variable 3515 Expression* Parser::ParseClassLiteral(const AstRawString* name,
3462 // and sets class_info->proxy to point to that name. 3516 Scanner::Location class_name_location,
3463 void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope, 3517 bool name_is_strict_reserved, int pos,
3464 ClassInfo* class_info, int class_token_pos, 3518 bool* ok) {
3465 bool* ok) { 3519 // All parts of a ClassDeclaration and ClassExpression are strict code.
3520 if (name_is_strict_reserved) {
3521 ReportMessageAt(class_name_location,
3522 MessageTemplate::kUnexpectedStrictReserved);
3523 *ok = false;
3524 return nullptr;
3525 }
3526 if (IsEvalOrArguments(name)) {
3527 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
3528 *ok = false;
3529 return nullptr;
3530 }
3531
3532 BlockState block_state(zone(), &scope_state_);
3533 RaiseLanguageMode(STRICT);
3466 #ifdef DEBUG 3534 #ifdef DEBUG
3467 scope()->SetScopeName(name); 3535 scope()->SetScopeName(name);
3468 #endif 3536 #endif
3469 3537
3538 VariableProxy* proxy = nullptr;
3470 if (name != nullptr) { 3539 if (name != nullptr) {
3471 class_info->proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE); 3540 proxy = factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3472 Declaration* declaration = factory()->NewVariableDeclaration( 3541 // TODO(verwaest): declare via block_state.
3473 class_info->proxy, block_scope, class_token_pos); 3542 Declaration* declaration =
3543 factory()->NewVariableDeclaration(proxy, block_state.scope(), pos);
3474 Declare(declaration, DeclarationDescriptor::NORMAL, CONST, 3544 Declare(declaration, DeclarationDescriptor::NORMAL, CONST,
3475 Variable::DefaultInitializationFlag(CONST), ok); 3545 Variable::DefaultInitializationFlag(CONST), CHECK_OK);
3476 }
3477 }
3478
3479 // This method declares a property of the given class. It updates the
3480 // following fields of class_info, as appropriate:
3481 // - constructor
3482 // - static_initializer_var
3483 // - instance_field_initializers
3484 // - properties
3485 void Parser::DeclareClassProperty(const AstRawString* class_name,
3486 ClassLiteralProperty* property,
3487 ClassInfo* class_info, bool* ok) {
3488 if (class_info->has_seen_constructor && class_info->constructor == nullptr) {
3489 class_info->constructor = GetPropertyValue(property)->AsFunctionLiteral();
3490 DCHECK_NOT_NULL(class_info->constructor);
3491 class_info->constructor->set_raw_name(
3492 class_name != nullptr ? class_name
3493 : ast_value_factory()->empty_string());
3494 return;
3495 } 3546 }
3496 3547
3497 if (property->kind() == ClassLiteralProperty::FIELD) { 3548 Expression* extends = nullptr;
3498 DCHECK(allow_harmony_class_fields()); 3549 if (Check(Token::EXTENDS)) {
3499 if (property->is_static()) { 3550 block_state.set_start_position(scanner()->location().end_pos);
3500 if (class_info->static_initializer_var == nullptr) { 3551 ExpressionClassifier extends_classifier(this);
3501 class_info->static_initializer_var = 3552 extends = ParseLeftHandSideExpression(CHECK_OK);
3502 NewTemporary(ast_value_factory()->empty_string()); 3553 RewriteNonPattern(CHECK_OK);
3503 } 3554 impl()->AccumulateFormalParameterContainmentErrors();
3504 // TODO(bakkot) only do this conditionally 3555 } else {
3505 Expression* function = InstallHomeObject( 3556 block_state.set_start_position(scanner()->location().end_pos);
3506 property->value(),
3507 factory()->NewVariableProxy(class_info->static_initializer_var));
3508 ZoneList<Expression*>* args =
3509 new (zone()) ZoneList<Expression*>(2, zone());
3510 args->Add(function, zone());
3511 args->Add(factory()->NewVariableProxy(class_info->static_initializer_var),
3512 zone());
3513 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
3514 kNoSourcePosition);
3515 property->set_value(call);
3516 } else {
3517 // if (is_computed_name) { // TODO(bakkot) figure out why this is
3518 // necessary for non-computed names in full-codegen
3519 ZoneList<Expression*>* to_name_args =
3520 new (zone()) ZoneList<Expression*>(1, zone());
3521 to_name_args->Add(property->key(), zone());
3522 property->set_key(factory()->NewCallRuntime(
3523 Runtime::kToName, to_name_args, kNoSourcePosition));
3524 //}
3525 const AstRawString* name = ClassFieldVariableName(
3526 true, ast_value_factory(),
3527 class_info->instance_field_initializers->length());
3528 VariableProxy* name_proxy =
3529 factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3530 Declaration* name_declaration = factory()->NewVariableDeclaration(
3531 name_proxy, scope(), kNoSourcePosition);
3532 Variable* name_var =
3533 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
3534 kNeedsInitialization, ok, scope());
3535 DCHECK(*ok);
3536 if (!*ok) return;
3537 class_info->instance_field_initializers->Add(property->value(), zone());
3538 property->set_value(factory()->NewVariableProxy(name_var));
3539 }
3540 } 3557 }
3541 class_info->properties->Add(property, zone());
3542 }
3543 3558
3544 // This method rewrites a class literal into a do-expression. 3559
3545 // It uses the following fields of class_info: 3560 ClassLiteralChecker checker(this);
3546 // - constructor (if missing, it updates it with a default constructor) 3561 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4);
3547 // - proxy 3562 ZoneList<Expression*>* instance_field_initializers =
3548 // - extends 3563 new (zone()) ZoneList<Expression*>(0, zone());
3549 // - static_initializer_var 3564 FunctionLiteral* constructor = nullptr;
3550 // - instance_field_initializers 3565 bool has_seen_constructor = false;
3551 // - properties 3566 Variable* static_initializer_var = nullptr;
3552 Expression* Parser::RewriteClassLiteral(const AstRawString* name, 3567
3553 ClassInfo* class_info, int pos,
3554 bool* ok) {
3555 int end_pos = scanner()->location().end_pos;
3556 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); 3568 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
3557 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); 3569 Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
3558 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); 3570 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
3559 3571
3560 bool has_extends = class_info->extends != nullptr; 3572 Expect(Token::LBRACE, CHECK_OK);
3561 bool has_instance_fields = 3573
3562 class_info->instance_field_initializers->length() > 0; 3574 const bool has_extends = extends != nullptr;
3563 DCHECK(!has_instance_fields || allow_harmony_class_fields()); 3575 while (peek() != Token::RBRACE) {
3564 bool has_default_constructor = class_info->constructor == nullptr; 3576 if (Check(Token::SEMICOLON)) continue;
3565 if (has_default_constructor) { 3577 FuncNameInferrer::State fni_state(fni_);
3566 class_info->constructor = 3578 bool is_computed_name = false; // Classes do not care about computed
3567 DefaultConstructor(name, has_extends, has_instance_fields, pos, end_pos, 3579 // property names here.
3568 scope()->language_mode()); 3580 ExpressionClassifier property_classifier(this);
3581 ClassLiteral::Property* property =
3582 ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name,
3583 &has_seen_constructor, CHECK_OK);
3584 RewriteNonPattern(CHECK_OK);
3585 impl()->AccumulateFormalParameterContainmentErrors();
3586
3587 if (has_seen_constructor && constructor == nullptr) {
3588 constructor = GetPropertyValue(property)->AsFunctionLiteral();
3589 DCHECK_NOT_NULL(constructor);
3590 constructor->set_raw_name(
3591 name != nullptr ? name : ast_value_factory()->empty_string());
3592 } else {
3593 if (property->kind() == ClassLiteralProperty::FIELD) {
3594 DCHECK(allow_harmony_class_fields());
3595 if (property->is_static()) {
3596 if (static_initializer_var == nullptr) {
3597 static_initializer_var =
3598 NewTemporary(ast_value_factory()->empty_string());
3599 }
3600 // TODO(bakkot) only do this conditionally
3601 Expression* function = InstallHomeObject(
3602 property->value(),
3603 factory()->NewVariableProxy(static_initializer_var));
3604 ZoneList<Expression*>* args =
3605 new (zone()) ZoneList<Expression*>(2, zone());
3606 args->Add(function, zone());
3607 args->Add(factory()->NewVariableProxy(static_initializer_var),
3608 zone());
3609 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall,
3610 args, kNoSourcePosition);
3611 property->set_value(call);
3612 } else {
3613 // if (is_computed_name) { // TODO(bakkot) figure out why this is
3614 // necessary for non-computed names in full-codegen
3615 ZoneList<Expression*>* to_name_args =
3616 new (zone()) ZoneList<Expression*>(1, zone());
3617 to_name_args->Add(property->key(), zone());
3618 property->set_key(factory()->NewCallRuntime(
3619 Runtime::kToName, to_name_args, kNoSourcePosition));
3620 //}
3621 const AstRawString* name = ClassFieldVariableName(
3622 true, ast_value_factory(), instance_field_initializers->length());
3623 VariableProxy* name_proxy =
3624 factory()->NewVariableProxy(name, NORMAL_VARIABLE);
3625 Declaration* name_declaration = factory()->NewVariableDeclaration(
3626 name_proxy, scope(), kNoSourcePosition);
3627 Variable* name_var =
3628 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
3629 kNeedsInitialization, ok, scope());
3630 DCHECK(ok);
3631 if (!ok) return nullptr;
3632 instance_field_initializers->Add(property->value(), zone());
3633 property->set_value(factory()->NewVariableProxy(name_var));
3634 }
3635 }
3636 properties->Add(property, zone());
3637 }
3638
3639 DCHECK_NOT_NULL(fni_);
3640 fni_->Infer();
3569 } 3641 }
3570 3642
3571 if (has_instance_fields && !has_extends) { 3643 Expect(Token::RBRACE, CHECK_OK);
3572 class_info->constructor = 3644 int end_pos = scanner()->location().end_pos;
3573 InsertClassFieldInitializer(class_info->constructor); 3645
3574 class_info->constructor->set_requires_class_field_init(true); 3646 bool has_instance_fields = instance_field_initializers->length() > 0;
3647 DCHECK(!has_instance_fields || allow_harmony_class_fields());
3648 bool has_default_constructor = constructor == nullptr;
3649 if (has_default_constructor) {
3650 constructor = DefaultConstructor(name, has_extends, has_instance_fields,
3651 pos, end_pos, block_state.language_mode());
3652 }
3653
3654 if (has_instance_fields && extends == nullptr) {
3655 constructor = InsertClassFieldInitializer(constructor);
3656 constructor->set_requires_class_field_init(true);
3575 } // The derived case is handled by rewriting super calls. 3657 } // The derived case is handled by rewriting super calls.
3576 3658
3577 scope()->set_end_position(end_pos); 3659 block_state.set_end_position(end_pos);
3578 3660
3579 if (name != nullptr) { 3661 if (name != nullptr) {
3580 DCHECK_NOT_NULL(class_info->proxy); 3662 DCHECK_NOT_NULL(proxy);
3581 class_info->proxy->var()->set_initializer_position(end_pos); 3663 proxy->var()->set_initializer_position(end_pos);
3582 } 3664 }
3583 3665
3584 ClassLiteral* class_literal = factory()->NewClassLiteral( 3666 ClassLiteral* class_literal = factory()->NewClassLiteral(
3585 class_info->proxy, class_info->extends, class_info->constructor, 3667 proxy, extends, constructor, properties, pos, end_pos);
3586 class_info->properties, pos, end_pos);
3587 3668
3588 if (class_info->static_initializer_var != nullptr) { 3669 if (static_initializer_var != nullptr) {
3589 class_literal->set_static_initializer_proxy( 3670 class_literal->set_static_initializer_proxy(
3590 factory()->NewVariableProxy(class_info->static_initializer_var)); 3671 factory()->NewVariableProxy(static_initializer_var));
3591 } 3672 }
3592 3673
3593 do_block->statements()->Add( 3674 do_block->statements()->Add(
3594 factory()->NewExpressionStatement( 3675 factory()->NewExpressionStatement(
3595 factory()->NewAssignment(Token::ASSIGN, 3676 factory()->NewAssignment(Token::ASSIGN,
3596 factory()->NewVariableProxy(result_var), 3677 factory()->NewVariableProxy(result_var),
3597 class_literal, kNoSourcePosition), 3678 class_literal, kNoSourcePosition),
3598 pos), 3679 pos),
3599 zone()); 3680 zone());
3600 if (allow_harmony_class_fields() && 3681 if (allow_harmony_class_fields() &&
3601 (has_instance_fields || (has_extends && !has_default_constructor))) { 3682 (has_instance_fields ||
3683 (extends != nullptr && !has_default_constructor))) {
3602 // Default constructors for derived classes without fields will not try to 3684 // Default constructors for derived classes without fields will not try to
3603 // read this variable, so there's no need to create it. 3685 // read this variable, so there's no need to create it.
3604 const AstRawString* init_fn_name = 3686 const AstRawString* init_fn_name =
3605 ast_value_factory()->dot_class_field_init_string(); 3687 ast_value_factory()->dot_class_field_init_string();
3606 Variable* init_fn_var = scope()->DeclareLocal( 3688 Variable* init_fn_var = scope()->DeclareLocal(
3607 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE); 3689 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE);
3608 Expression* initializer = 3690 Expression* initializer =
3609 has_instance_fields 3691 has_instance_fields
3610 ? static_cast<Expression*>(SynthesizeClassFieldInitializer( 3692 ? static_cast<Expression*>(SynthesizeClassFieldInitializer(
3611 class_info->instance_field_initializers->length())) 3693 instance_field_initializers->length()))
3612 : factory()->NewBooleanLiteral(false, kNoSourcePosition); 3694 : factory()->NewBooleanLiteral(false, kNoSourcePosition);
3613 Assignment* assignment = factory()->NewAssignment( 3695 Assignment* assignment = factory()->NewAssignment(
3614 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer, 3696 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer,
3615 kNoSourcePosition); 3697 kNoSourcePosition);
3616 do_block->statements()->Add( 3698 do_block->statements()->Add(
3617 factory()->NewExpressionStatement(assignment, kNoSourcePosition), 3699 factory()->NewExpressionStatement(assignment, kNoSourcePosition),
3618 zone()); 3700 zone());
3619 } 3701 }
3620 for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) { 3702 for (int i = 0; i < instance_field_initializers->length(); ++i) {
3621 const AstRawString* function_name = 3703 const AstRawString* function_name =
3622 ClassFieldVariableName(false, ast_value_factory(), i); 3704 ClassFieldVariableName(false, ast_value_factory(), i);
3623 VariableProxy* function_proxy = 3705 VariableProxy* function_proxy =
3624 factory()->NewVariableProxy(function_name, NORMAL_VARIABLE); 3706 factory()->NewVariableProxy(function_name, NORMAL_VARIABLE);
3625 Declaration* function_declaration = factory()->NewVariableDeclaration( 3707 Declaration* function_declaration = factory()->NewVariableDeclaration(
3626 function_proxy, scope(), kNoSourcePosition); 3708 function_proxy, scope(), kNoSourcePosition);
3627 Variable* function_var = 3709 Variable* function_var =
3628 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST, 3710 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST,
3629 kNeedsInitialization, ok, scope()); 3711 kNeedsInitialization, ok, scope());
3630 if (!*ok) return nullptr; 3712 DCHECK(ok);
3713 if (!ok) return nullptr;
3631 Property* prototype_property = factory()->NewProperty( 3714 Property* prototype_property = factory()->NewProperty(
3632 factory()->NewVariableProxy(result_var), 3715 factory()->NewVariableProxy(result_var),
3633 factory()->NewStringLiteral(ast_value_factory()->prototype_string(), 3716 factory()->NewStringLiteral(ast_value_factory()->prototype_string(),
3634 kNoSourcePosition), 3717 kNoSourcePosition),
3635 kNoSourcePosition); 3718 kNoSourcePosition);
3636 Expression* function_value = InstallHomeObject( 3719 Expression* function_value = InstallHomeObject(
3637 class_info->instance_field_initializers->at(i), 3720 instance_field_initializers->at(i),
3638 prototype_property); // TODO(bakkot) ideally this would be conditional, 3721 prototype_property); // TODO(bakkot) ideally this would be conditional,
3639 // especially in trivial cases 3722 // especially in trivial cases
3640 Assignment* function_assignment = factory()->NewAssignment( 3723 Assignment* function_assignment = factory()->NewAssignment(
3641 Token::INIT, factory()->NewVariableProxy(function_var), function_value, 3724 Token::INIT, factory()->NewVariableProxy(function_var), function_value,
3642 kNoSourcePosition); 3725 kNoSourcePosition);
3643 do_block->statements()->Add(factory()->NewExpressionStatement( 3726 do_block->statements()->Add(factory()->NewExpressionStatement(
3644 function_assignment, kNoSourcePosition), 3727 function_assignment, kNoSourcePosition),
3645 zone()); 3728 zone());
3646 } 3729 }
3647 do_block->set_scope(scope()->FinalizeBlockScope()); 3730 do_block->set_scope(block_state.FinalizedBlockScope());
3648 do_expr->set_represented_function(class_info->constructor); 3731 do_expr->set_represented_function(constructor);
3649 3732
3650 return do_expr; 3733 return do_expr;
3651 } 3734 }
3652 3735
3736
3653 Literal* Parser::GetLiteralUndefined(int position) { 3737 Literal* Parser::GetLiteralUndefined(int position) {
3654 return factory()->NewUndefinedLiteral(position); 3738 return factory()->NewUndefinedLiteral(position);
3655 } 3739 }
3656 3740
3657 3741
3658 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 3742 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
3659 Declaration* decl = scope->CheckConflictingVarDeclarations(); 3743 Declaration* decl = scope->CheckConflictingVarDeclarations();
3660 if (decl != NULL) { 3744 if (decl != NULL) {
3661 // In ES6, conflicting variable bindings are early errors. 3745 // In ES6, conflicting variable bindings are early errors.
3662 const AstRawString* name = decl->proxy()->raw_name(); 3746 const AstRawString* name = decl->proxy()->raw_name();
(...skipping 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after
5452 5536
5453 return final_loop; 5537 return final_loop;
5454 } 5538 }
5455 5539
5456 #undef CHECK_OK 5540 #undef CHECK_OK
5457 #undef CHECK_OK_VOID 5541 #undef CHECK_OK_VOID
5458 #undef CHECK_FAILED 5542 #undef CHECK_FAILED
5459 5543
5460 } // namespace internal 5544 } // namespace internal
5461 } // namespace v8 5545 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698