Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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, ¶ms); | |
| 1559 | |
| 1560 SetupDefaultsForOptionalParams(¶ms, 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(¶ms, 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(¶ms, 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, ¶ms); | 1791 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 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(¶ms, func); | 1796 AddFormalParamsToFunction(¶ms, func); |
| 1570 } | 1797 } |
| 1571 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 1798 SetupDefaultsForOptionalParams(¶ms, 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(¶ms, current_block_->scope); | 1814 AddFormalParamsToScope(¶ms, 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(¶ms, 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(¶ms, func); | 1842 ParseNativeFunctionBlock(¶ms, 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 Loading... | |
| 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 |
| OLD | NEW |