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

Side by Side Diff: runtime/vm/parser.cc

Issue 8417056: Separating constructor parsing from function parsing (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 GenerateSuperConstructorCall(cls, receiver); 1516 GenerateSuperConstructorCall(cls, receiver);
1517 CheckConstFieldsInitialized(cls); 1517 CheckConstFieldsInitialized(cls);
1518 1518
1519 // Empty constructor body. 1519 // Empty constructor body.
1520 SequenceNode* statements = CloseBlock(); 1520 SequenceNode* statements = CloseBlock();
1521 return statements; 1521 return statements;
1522 } 1522 }
1523 1523
1524 1524
1525 // Parser is at the opening parenthesis of the formal parameter declaration 1525 // Parser is at the opening parenthesis of the formal parameter declaration
1526 // of function. Parse the formal parameters and code. 1526 // of function. Parse the formal parameters, initializers and code.
1527 SequenceNode* Parser::ParseFunc(const Function& func, 1527 SequenceNode* Parser::ParseConstructor(const Function& func,
1528 Array& default_parameter_values) { 1528 Array& default_parameter_values) {
1529 ASSERT(func.IsConstructor());
1530 ASSERT(!func.IsFactory());
1531 ASSERT(!func.is_static());
1532 ASSERT(!func.IsLocalFunction());
1533 const Class& cls = Class::Handle(func.owner());
1534 ASSERT(!cls.IsNull());
1535
1529 if (IsLiteral("class")) { 1536 if (IsLiteral("class")) {
regis 2011/11/03 23:58:22 This is not new code, but I was nevertheless puzzl
hausner 2011/11/04 17:04:55 Done.
1530 // Special case: implicit constructor. There is no source text to 1537 // Special case: implicit constructor. There is no source text to
1531 // parse. We just build the sequence node by hand. 1538 // parse. We just build the sequence node by hand.
1532 return MakeImplicitConstructor(func); 1539 return MakeImplicitConstructor(func);
1533 } 1540 }
1534 1541
1535 const Class& cls = Class::Handle(func.owner());
1536 ASSERT(!cls.IsNull());
1537
1538 // Build local scope for function.
1539 OpenFunctionBlock(func); 1542 OpenFunctionBlock(func);
1540
1541 ParamList params; 1543 ParamList params;
1542 // Static functions do not have a receiver, except constructors, which are 1544 const bool allow_explicit_default_values = true;
1543 // passed the allocated but uninitialized instance to construct. 1545 ASSERT(CurrentToken() == Token::kLPAREN);
1546
1547 // Add implicit receiver parameter which is passed the allocated
1548 // but uninitialized instance to construct.
1549 params.AddReceiver(token_index_);
1550
1551 // Add implicit parameter for constructor phase.
regis 2011/11/03 23:58:22 Should you use "construction phase" here and elsew
hausner 2011/11/04 17:04:55 True. Done in all places.
1552 params.AddFinalParameter(token_index_, kPhaseParameterName,
1553 &Type::ZoneHandle(Type::DynamicType()));
1554
1555 if (func.is_const()) {
1556 params.SetImplicitlyFinal();
1557 }
1558 ParseFormalParameterList(allow_explicit_default_values, &params);
1559
1560 SetupDefaultsForOptionalParams(&params, default_parameter_values);
1561 ASSERT(Type::Handle(func.result_type()).IsResolved());
1562 ASSERT(func.NumberOfParameters() == params.parameters->length());
1563
1564 // Initialize instance fields that have an explicit initializer expression.
1565 // This has to be done before code for field initializer parameters
1566 // are is generated.
regis 2011/11/03 23:58:22 Comment parsing error.
hausner 2011/11/04 17:04:55 Done.
1567 // NB: the instance field initializers have to be compiled before
1568 // the parameters are added to the scope, so that a parameter
1569 // name cannot shadow a name used in the field initializer expression.
1570 GrowableArray<FieldInitExpression> initializers;
1571 ParseInitializedInstanceFields(cls, &initializers);
1572
1573 // Now populate function scope with the formal parameters.
1574 AddFormalParamsToScope(&params, current_block_->scope);
1575 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1576
1577 // Now that the "this" parameter is in scope, we can generate the code
1578 // to strore the initializer expressions in the respective instance fields.
regis 2011/11/03 23:58:22 strore -> store
hausner 2011/11/04 17:04:55 Done.
1579 // We do this before the field parameters and the initializers from the
1580 // constructor's initializer list get compiled.
1581 OpenBlock();
1582 for (int i = 0; i < initializers.length(); i++) {
1583 const Field* field = initializers[i].inst_field;
1584 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver);
1585 AstNode* field_init =
1586 new StoreInstanceFieldNode(field->token_index(),
1587 instance,
1588 *field,
1589 initializers[i].expr);
1590 current_block_->statements->Add(field_init);
1591 }
1592
1593 // Turn formal field parameters into field initializers or report error
1594 // if the function is not a constructor
1595 if (params.has_field_initializer) {
1596 for (int i = 0; i < params.parameters->length(); i++) {
1597 ParamDesc& param = (*params.parameters)[i];
1598 if (param.is_field_initializer) {
1599 const String& field_name = *param.name;
1600 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1601 if (field.IsNull()) {
1602 ErrorMsg(param.name_pos,
1603 "unresolved reference to instance field '%s'",
1604 field_name.ToCString());
1605 }
1606 const String& mangled_name =
1607 String::ZoneHandle(MangledInitParamName(field_name));
1608 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver);
1609 LocalVariable* p =
1610 current_block_->scope->LookupVariable(mangled_name, false);
1611 ASSERT(p != NULL);
1612 AstNode* value = new LoadLocalNode(param.name_pos, *p);
1613 AstNode* initializer = new StoreInstanceFieldNode(
1614 param.name_pos, instance, field, value);
1615 current_block_->statements->Add(initializer);
1616 }
1617 }
1618 }
1619
1620 // Now parse the explicit initializer list or constructor redirection.
1621 ParseInitializers(cls, receiver);
1622
1623 SequenceNode* init_statements = CloseBlock();
1624 if (init_statements->length() > 0) {
1625 // Generate guard around the initializer code.
1626 LocalVariable* phase_param = LookupPhaseParameter();
1627 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param);
1628 AstNode* phase_check = new BinaryOpNode(
1629 token_index_, Token::kBIT_AND, phase_value,
1630 new LiteralNode(token_index_,
1631 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1632 AstNode* comparison =
1633 new ComparisonNode(token_index_, Token::kNE_STRICT,
1634 phase_check,
1635 new LiteralNode(token_index_,
1636 Smi::ZoneHandle(Smi::New(0))));
1637 AstNode* guarded_init_statements =
1638 new IfNode(token_index_, comparison, init_statements, NULL);
1639 current_block_->statements->Add(guarded_init_statements);
1640 }
1641
1642 // Parsing of initializers done. Now we parse the constructor body
1643 // and add the implicit super call to the super construcotr's body
regis 2011/11/03 23:58:22 construcotr -> ...
hausner 2011/11/04 17:04:55 Done.
1644 // if necessary.
1645 StaticCallNode* super_call = NULL;
1646 // Look for the super initializer call in the sequence of initializer
1647 // statements. If it exists and is not the last initializer statement,
1648 // we need to create an implicit super call to the super constructor's
1649 // body.
1650 // Thus, iterate over all but the last initializer to see whether
1651 // it's a super constructor call.
1652 for (int i = 0; i < init_statements->length() - 1; i++) {
1653 if (init_statements->NodeAt(i)->IsStaticCallNode()) {
1654 StaticCallNode* static_call =
1655 init_statements->NodeAt(i)->AsStaticCallNode();
1656 if (static_call->function().IsConstructor()) {
1657 super_call = static_call;
1658 break;
1659 }
1660 }
1661 }
1662 if (super_call != NULL) {
1663 // Generate an implicit call to the super constructor's body.
1664 // We need to patch the super _initializer_ call so that it
1665 // saves the evaluated actual arguments in temporary variables.
1666 // The temporary variables are necessary so that the argument
1667 // expressions are not evaluated twice.
1668 ArgumentListNode* ctor_args = super_call->arguments();
1669 // The super initializer call has at least 2 arguments: the
1670 // implicit receiver, and the hidden constructor phase.
1671 ASSERT(ctor_args->length() >= 2);
1672 for (int i = 2; i < ctor_args->length(); i++) {
1673 AstNode* arg = ctor_args->NodeAt(i);
1674 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) {
1675 LocalVariable* temp =
1676 CreateTempConstVariable(arg->token_index(), arg->id(), "sca");
1677 AstNode* save_temp =
1678 new StoreLocalNode(arg->token_index(), *temp, arg);
1679 ctor_args->SetNodeAt(i, save_temp);
1680 }
1681 }
1682 }
1683 OpenBlock(); // Block to collect constructor body nodes.
1684
1685 // Insert the implicit super call to the super constructor body.
1686 if (super_call != NULL) {
1687 ArgumentListNode* initializer_args = super_call->arguments();
1688 const Function& super_ctor = super_call->function();
1689 // Patch the initializer call so it only executes the super
1690 // initializer.
regis 2011/11/03 23:58:22 Doesn't the above comment fit on one line?
hausner 2011/11/04 17:04:55 Done.
1691 initializer_args->SetNodeAt(1,
1692 new LiteralNode(token_index_,
1693 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1694
1695 ArgumentListNode* super_call_args = new ArgumentListNode(token_index_);
1696 // First argument is the receiver.
1697 super_call_args->Add(new LoadLocalNode(token_index_, *receiver));
1698 // Second argument is the constructor phase argument.
1699 AstNode* phase_parameter =
1700 new LiteralNode(token_index_,
1701 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)));
1702 super_call_args->Add(phase_parameter);
1703 super_call_args->set_names(initializer_args->names());
1704 for (int i = 2; i < initializer_args->length(); i++) {
1705 AstNode* arg = initializer_args->NodeAt(i);
1706 if (arg->IsLiteralNode()) {
1707 LiteralNode* lit = arg->AsLiteralNode();
1708 super_call_args->Add(new LiteralNode(token_index_, lit->literal()));
1709 } else {
1710 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
1711 if (arg->IsLoadLocalNode()) {
1712 const LocalVariable& temp = arg->AsLoadLocalNode()->local();
1713 super_call_args->Add(new LoadLocalNode(token_index_, temp));
1714 } else if (arg->IsStoreLocalNode()) {
1715 const LocalVariable& temp = arg->AsStoreLocalNode()->local();
1716 super_call_args->Add(new LoadLocalNode(token_index_, temp));
1717 }
1718 }
1719 }
1720 ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
1721 super_call_args->names()));
1722 current_block_->statements->Add(
1723 new StaticCallNode(token_index_, super_ctor, super_call_args));
1724 }
1725
1726 if (CurrentToken() == Token::kLBRACE) {
1727 ConsumeToken();
1728 ParseStatementSequence();
1729 ExpectToken(Token::kRBRACE);
1730 } else if (CurrentToken() == Token::kARROW) {
1731 ErrorMsg("constructors may not return a value");
1732 } else if (IsLiteral("native")) {
1733 ParseNativeFunctionBlock(&params, func);
1734 } else if (CurrentToken() == Token::kSEMICOLON) {
1735 // Some constructors have no function body.
1736 ConsumeToken();
1737 } else {
1738 UnexpectedToken();
1739 }
1740
1741 SequenceNode* ctor_block = CloseBlock();
1742 if (ctor_block->length() > 0) {
1743 // Generate guard around the constructor body code.
1744 LocalVariable* phase_param = LookupPhaseParameter();
1745 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param);
1746 AstNode* phase_check =
1747 new BinaryOpNode(token_index_, Token::kBIT_AND,
1748 phase_value,
1749 new LiteralNode(token_index_,
1750 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
1751 AstNode* comparison =
1752 new ComparisonNode(token_index_, Token::kNE_STRICT,
1753 phase_check,
1754 new LiteralNode(token_index_,
1755 Smi::ZoneHandle(Smi::New(0))));
1756 AstNode* guarded_block_statements =
1757 new IfNode(token_index_, comparison, ctor_block, NULL);
1758 current_block_->statements->Add(guarded_block_statements);
1759 }
1760
1761 SequenceNode* statements = CloseBlock();
1762 return statements;
1763 }
1764
1765
1766 // Parser is at the opening parenthesis of the formal parameter
1767 // declaration of the function or constructor.
1768 // Parse the formal parameters and code.
1769 SequenceNode* Parser::ParseFunc(const Function& func,
1770 Array& default_parameter_values) {
1771 if (func.IsConstructor()) {
1772 return ParseConstructor(func, default_parameter_values);
1773 }
1774
1775 ASSERT(!func.IsConstructor());
1776 OpenFunctionBlock(func); // Build local scope for function.
1777
1778 ParamList params;
1779 // Static functions do not have a receiver.
1544 // An instance closure may capture and access the receiver, but via the 1780 // An instance closure may capture and access the receiver, but via the
1545 // context and not via the first formal parameter. 1781 // context and not via the first formal parameter.
1546 // The first parameter of a factory is the TypeArguments vector of the type 1782 // The first parameter of a factory is the TypeArguments vector of the type
1547 // of the instance to be allocated. We name this hidden parameter 'this'. 1783 // of the instance to be allocated. We name this hidden parameter 'this'.
1548 const bool has_receiver = !func.IsClosureFunction() && 1784 const bool has_receiver = !func.IsClosureFunction() &&
1549 (!func.is_static() || func.IsConstructor() || func.IsFactory()); 1785 (!func.is_static() || func.IsFactory());
1550 const bool are_implicitly_final = func.is_const() && func.IsConstructor();
1551 const bool allow_explicit_default_values = true; 1786 const bool allow_explicit_default_values = true;
1552 ASSERT(CurrentToken() == Token::kLPAREN);
1553 if (has_receiver) { 1787 if (has_receiver) {
1554 params.AddReceiver(token_index_); 1788 params.AddReceiver(token_index_);
1555 } 1789 }
1556 if (func.IsConstructor()) { 1790 ASSERT(CurrentToken() == Token::kLPAREN);
1557 // Add implicit parameter for constructor phase.
1558 params.AddFinalParameter(token_index_, kPhaseParameterName,
1559 &Type::ZoneHandle(Type::DynamicType()));
1560 }
1561 if (are_implicitly_final) {
1562 params.SetImplicitlyFinal();
1563 }
1564 ParseFormalParameterList(allow_explicit_default_values, &params); 1791 ParseFormalParameterList(allow_explicit_default_values, &params);
1565 1792
1566 // The number of parameters and their type are not yet set in local functions, 1793 // The number of parameters and their type are not yet set in local functions,
1567 // since they are not 'top-level' parsed. 1794 // since they are not 'top-level' parsed.
1568 if (func.IsLocalFunction()) { 1795 if (func.IsLocalFunction()) {
1569 AddFormalParamsToFunction(&params, func); 1796 AddFormalParamsToFunction(&params, func);
1570 } 1797 }
1571 SetupDefaultsForOptionalParams(&params, default_parameter_values); 1798 SetupDefaultsForOptionalParams(&params, default_parameter_values);
1572 ASSERT(Type::Handle(func.result_type()).IsResolved()); 1799 ASSERT(Type::Handle(func.result_type()).IsResolved());
1573 ASSERT(func.NumberOfParameters() == params.parameters->length()); 1800 ASSERT(func.NumberOfParameters() == params.parameters->length());
1574 1801
1575 // If this is a constructor, initialize instance fields that have an 1802 // Check whether the function has any field initializer formal parameters,
1576 // explicit initializer expression. This has to be done before code 1803 // which are not allowed in non-constructor functions.
1577 // for field initializer parameters are is generated. 1804 if (params.has_field_initializer) {
1578 // NB: the instance field initializers have to be compiled before 1805 for (int i = 0; i < params.parameters->length(); i++) {
1579 // the parameters are added to the scope, so that a parameter 1806 ParamDesc& param = (*params.parameters)[i];
1580 // name cannot shadow a name used in the field initializer expression. 1807 if (param.is_field_initializer) {
1581 SequenceNode* init_statements = NULL; 1808 ErrorMsg(param.name_pos,
1582 if (func.IsConstructor()) { 1809 "field initializer only allowed in constructors");
1583 GrowableArray<FieldInitExpression> initializers; 1810 }
1584 ParseInitializedInstanceFields(cls, &initializers); 1811 }
1585 1812 }
1586 // Now populate function scope with the formal parameters. 1813 // Populate function scope with the formal parameters.
1587 AddFormalParamsToScope(&params, current_block_->scope); 1814 AddFormalParamsToScope(&params, current_block_->scope);
1588 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1589
1590 // Now that the "this" parameter is in scope, we can generate the code
1591 // to strore the initializer expressions in the respective instance fields.
1592 // We do this before the field parameters and the initializers from the
1593 // constructor's initializer list get compiled.
1594 OpenBlock();
1595 if (initializers.length() > 0) {
1596 for (int i = 0; i < initializers.length(); i++) {
1597 const Field* field = initializers[i].inst_field;
1598 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver);
1599 AstNode* field_init =
1600 new StoreInstanceFieldNode(field->token_index(),
1601 instance,
1602 *field,
1603 initializers[i].expr);
1604 current_block_->statements->Add(field_init);
1605 }
1606 }
1607
1608 // Turn formal field parameters into field initializers or report error
1609 // if the function is not a constructor
1610 if (params.has_field_initializer) {
1611 for (int i = 0; i < params.parameters->length(); i++) {
1612 ParamDesc& param = (*params.parameters)[i];
1613 if (param.is_field_initializer) {
1614 if (!func.IsConstructor()) {
1615 ErrorMsg(param.name_pos,
1616 "field initializer only allowed in constructors");
1617 }
1618
1619 const String& field_name = *param.name;
1620 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1621 if (field.IsNull()) {
1622 ErrorMsg(param.name_pos,
1623 "unresolved reference to instance field '%s'",
1624 field_name.ToCString());
1625 }
1626 const String& mangled_name =
1627 String::ZoneHandle(MangledInitParamName(field_name));
1628 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver);
1629 LocalVariable* p =
1630 current_block_->scope->LookupVariable(mangled_name, false);
1631 ASSERT(p != NULL);
1632 AstNode* value = new LoadLocalNode(param.name_pos, *p);
1633 AstNode* initializer = new StoreInstanceFieldNode(
1634 param.name_pos, instance, field, value);
1635 current_block_->statements->Add(initializer);
1636 }
1637 }
1638 }
1639 ParseInitializers(cls, receiver);
1640 init_statements = CloseBlock();
1641 LocalVariable* phase_param = LookupPhaseParameter();
1642 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param);
1643 AstNode* phase_check =
1644 new BinaryOpNode(token_index_, Token::kBIT_AND,
1645 phase_value,
1646 new LiteralNode(token_index_,
1647 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1648 AstNode* comparison =
1649 new ComparisonNode(token_index_, Token::kNE_STRICT,
1650 phase_check,
1651 new LiteralNode(token_index_, Smi::ZoneHandle(Smi::New(0))));
1652 AstNode* guarded_init_statements =
1653 new IfNode(token_index_, comparison, init_statements, NULL);
1654 current_block_->statements->Add(guarded_init_statements);
1655 } else {
1656 // Parsing a function that is not a constructor.
1657 if (params.has_field_initializer) {
1658 for (int i = 0; i < params.parameters->length(); i++) {
1659 ParamDesc& param = (*params.parameters)[i];
1660 if (param.is_field_initializer) {
1661 ErrorMsg(param.name_pos,
1662 "field initializer only allowed in constructors");
1663 }
1664 }
1665 }
1666 // Populate function scope with the formal parameters.
1667 AddFormalParamsToScope(&params, current_block_->scope);
1668 }
1669 1815
1670 if (FLAG_enable_type_checks && 1816 if (FLAG_enable_type_checks &&
1671 (current_block_->scope->function_level() > 0)) { 1817 (current_block_->scope->function_level() > 0)) {
1672 // We are parsing, but not compiling, a local function. 1818 // We are parsing, but not compiling, a local function.
1673 // The instantiator may be required at run time for generic type checks. 1819 // The instantiator may be required at run time for generic type checks.
1674 if ((current_class().NumTypeParameters() > 0) && 1820 if ((current_class().NumTypeParameters() > 0) &&
1675 (!current_function().is_static() || 1821 (!current_function().is_static() ||
1676 current_function().IsInFactoryScope())) { 1822 current_function().IsInFactoryScope())) {
1677 // Make sure that the receiver of the enclosing instance function 1823 // Make sure that the receiver of the enclosing instance function
1678 // (or implicit first parameter of an enclosing factory) is marked as 1824 // (or implicit first parameter of an enclosing factory) is marked as
1679 // captured if type checks are enabled, because they may access the 1825 // captured if type checks are enabled, because they may access the
1680 // receiver to instantiate types. 1826 // receiver to instantiate types.
1681 CaptureReceiver(); 1827 CaptureReceiver();
1682 } 1828 }
1683 } 1829 }
1684 1830
1685 if (func.IsConstructor()) {
1686 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1687 StaticCallNode* super_call = NULL;
1688 ASSERT(init_statements != NULL);
1689 // Look for the super initializer call in the sequence of initializer
1690 // statements. If it exists and is not the last initializer statement,
1691 // we need to create an implicit super call to the super constructor's
1692 // body.
1693 // Thus, iterate over all but the last initializer to see whether
1694 // it's a super constructor call.
1695 for (int i = 0; i < init_statements->length() - 1; i++) {
1696 if (init_statements->NodeAt(i)->IsStaticCallNode()) {
1697 StaticCallNode* static_call =
1698 init_statements->NodeAt(i)->AsStaticCallNode();
1699 if (static_call->function().IsConstructor()) {
1700 super_call = static_call;
1701 break;
1702 }
1703 }
1704 }
1705 if (super_call != NULL) {
1706 // Generate an implicit call to the super constructor's body.
1707 // We need to patch the super _initializer_ call so that it
1708 // saves the evaluated actual arguments in temporary variables.
1709 // The temporary variables are necessary so that the argument
1710 // expressions are not evaluated twice.
1711 ArgumentListNode* ctor_args = super_call->arguments();
1712 // The super initializer call has at least 2 arguments: the
1713 // implicit receiver, and the hidden constructor phase.
1714 ASSERT(ctor_args->length() >= 2);
1715 for (int i = 2; i < ctor_args->length(); i++) {
1716 AstNode* arg = ctor_args->NodeAt(i);
1717 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) {
1718 LocalVariable* temp =
1719 CreateTempConstVariable(arg->token_index(), arg->id(), "sca");
1720 AstNode* save_temp =
1721 new StoreLocalNode(arg->token_index(), *temp, arg);
1722 ctor_args->SetNodeAt(i, save_temp);
1723 }
1724 }
1725 }
1726 OpenBlock();
1727 if (super_call != NULL) {
1728 ArgumentListNode* initializer_args = super_call->arguments();
1729 const Function& super_ctor = super_call->function();
1730 // Patch the initializer call so it only executes the super
1731 // initializer.
1732 initializer_args->SetNodeAt(1,
1733 new LiteralNode(token_index_,
1734 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1735
1736 ArgumentListNode* super_call_args = new ArgumentListNode(token_index_);
1737 // First argument is the receiver.
1738 super_call_args->Add(new LoadLocalNode(token_index_, *receiver));
1739 // Second argument is the constructor phase argument.
1740 AstNode* phase_parameter =
1741 new LiteralNode(token_index_,
1742 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)));
1743 super_call_args->Add(phase_parameter);
1744 super_call_args->set_names(initializer_args->names());
1745 for (int i = 2; i < initializer_args->length(); i++) {
1746 AstNode* arg = initializer_args->NodeAt(i);
1747 if (arg->IsLiteralNode()) {
1748 LiteralNode* lit = arg->AsLiteralNode();
1749 super_call_args->Add(new LiteralNode(token_index_, lit->literal()));
1750 } else {
1751 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
1752 if (arg->IsLoadLocalNode()) {
1753 const LocalVariable& temp = arg->AsLoadLocalNode()->local();
1754 super_call_args->Add(new LoadLocalNode(token_index_, temp));
1755 } else if (arg->IsStoreLocalNode()) {
1756 const LocalVariable& temp = arg->AsStoreLocalNode()->local();
1757 super_call_args->Add(new LoadLocalNode(token_index_, temp));
1758 }
1759 }
1760 }
1761 ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
1762 super_call_args->names()));
1763 current_block_->statements->Add(
1764 new StaticCallNode(token_index_, super_ctor, super_call_args));
1765 }
1766 }
1767 if (CurrentToken() == Token::kLBRACE) { 1831 if (CurrentToken() == Token::kLBRACE) {
1768 ConsumeToken(); 1832 ConsumeToken();
1769 ParseStatementSequence(); 1833 ParseStatementSequence();
1770 ExpectToken(Token::kRBRACE); 1834 ExpectToken(Token::kRBRACE);
1771 } else if (CurrentToken() == Token::kARROW) { 1835 } else if (CurrentToken() == Token::kARROW) {
1772 ConsumeToken(); 1836 ConsumeToken();
1773 if (func.IsConstructor()) {
1774 ErrorMsg("constructors may not return a value");
1775 }
1776 intptr_t expr_pos = token_index_; 1837 intptr_t expr_pos = token_index_;
1777 AstNode* expr = ParseExpr(kAllowConst); 1838 AstNode* expr = ParseExpr(kAllowConst);
1778 ASSERT(expr != NULL); 1839 ASSERT(expr != NULL);
1779 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 1840 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
1780 } else if (IsLiteral("native")) { 1841 } else if (IsLiteral("native")) {
1781 ParseNativeFunctionBlock(&params, func); 1842 ParseNativeFunctionBlock(&params, func);
1782 } else if (CurrentToken() == Token::kSEMICOLON) {
1783 ConsumeToken();
1784 ASSERT(func.IsConstructor());
1785 // Some constructors have no function body.
1786 } else { 1843 } else {
1787 UnexpectedToken(); 1844 UnexpectedToken();
1788 } 1845 }
1789 if (func.IsConstructor()) {
1790 SequenceNode* ctor_block = CloseBlock();
1791 LocalVariable* phase_param = LookupPhaseParameter();
1792 AstNode* phase_value = new LoadLocalNode(token_index_, *phase_param);
1793 AstNode* phase_check =
1794 new BinaryOpNode(token_index_, Token::kBIT_AND,
1795 phase_value,
1796 new LiteralNode(token_index_,
1797 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
1798 AstNode* comparison =
1799 new ComparisonNode(token_index_, Token::kNE_STRICT,
1800 phase_check,
1801 new LiteralNode(token_index_, Smi::ZoneHandle(Smi::New(0))));
1802 AstNode* guarded_block_statements =
1803 new IfNode(token_index_, comparison, ctor_block, NULL);
1804 current_block_->statements->Add(guarded_block_statements);
1805 }
1806 1846
1807 SequenceNode* statements = CloseBlock(); 1847 SequenceNode* statements = CloseBlock();
1808 return statements; 1848 return statements;
1809 } 1849 }
1810 1850
1811 1851
1812 void Parser::SkipIf(Token::Kind token) { 1852 void Parser::SkipIf(Token::Kind token) {
1813 if (CurrentToken() == token) { 1853 if (CurrentToken() == token) {
1814 ConsumeToken(); 1854 ConsumeToken();
1815 } 1855 }
(...skipping 5391 matching lines...) Expand 10 before | Expand all | Expand 10 after
7207 } 7247 }
7208 7248
7209 7249
7210 void Parser::SkipNestedExpr() { 7250 void Parser::SkipNestedExpr() {
7211 const bool saved_mode = SetAllowFunctionLiterals(true); 7251 const bool saved_mode = SetAllowFunctionLiterals(true);
7212 SkipExpr(); 7252 SkipExpr();
7213 SetAllowFunctionLiterals(saved_mode); 7253 SetAllowFunctionLiterals(saved_mode);
7214 } 7254 }
7215 7255
7216 } // namespace dart 7256 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698