| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 1599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 } | 1610 } |
| 1611 } | 1611 } |
| 1612 if (!found) { | 1612 if (!found) { |
| 1613 ErrorMsg("final field '%s' not initialized", | 1613 ErrorMsg("final field '%s' not initialized", |
| 1614 String::Handle(field.name()).ToCString()); | 1614 String::Handle(field.name()).ToCString()); |
| 1615 } | 1615 } |
| 1616 } | 1616 } |
| 1617 } | 1617 } |
| 1618 | 1618 |
| 1619 | 1619 |
| 1620 struct FieldInitExpression { | |
| 1621 Field* inst_field; | |
| 1622 AstNode* expr; | |
| 1623 }; | |
| 1624 | |
| 1625 | |
| 1626 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1620 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 1627 GrowableArray<FieldInitExpression>* initializers, | 1621 LocalVariable* receiver, |
| 1628 GrowableArray<Field*>* initialized_fields) { | 1622 GrowableArray<Field*>* initialized_fields) { |
| 1629 TRACE_PARSER("ParseInitializedInstanceFields"); | 1623 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 1630 const Array& fields = Array::Handle(cls.fields()); | 1624 const Array& fields = Array::Handle(cls.fields()); |
| 1631 Field& f = Field::Handle(); | 1625 Field& f = Field::Handle(); |
| 1632 const intptr_t saved_pos = TokenPos(); | 1626 const intptr_t saved_pos = TokenPos(); |
| 1633 for (int i = 0; i < fields.Length(); i++) { | 1627 for (int i = 0; i < fields.Length(); i++) { |
| 1634 f ^= fields.At(i); | 1628 f ^= fields.At(i); |
| 1635 if (!f.is_static() && f.has_initializer()) { | 1629 if (!f.is_static() && f.has_initializer()) { |
| 1636 Field& field = Field::ZoneHandle(); | 1630 Field& field = Field::ZoneHandle(); |
| 1637 field ^= fields.At(i); | 1631 field ^= fields.At(i); |
| 1638 if (field.is_final()) { | 1632 if (field.is_final()) { |
| 1639 // Final fields with initializer expression may not be initialized | 1633 // Final fields with initializer expression may not be initialized |
| 1640 // again by constructors. Remember that this field is already | 1634 // again by constructors. Remember that this field is already |
| 1641 // initialized. | 1635 // initialized. |
| 1642 initialized_fields->Add(&field); | 1636 initialized_fields->Add(&field); |
| 1643 } | 1637 } |
| 1644 intptr_t field_pos = field.token_pos(); | 1638 intptr_t field_pos = field.token_pos(); |
| 1645 SetPosition(field_pos); | 1639 SetPosition(field_pos); |
| 1646 ASSERT(IsIdentifier()); | 1640 ASSERT(IsIdentifier()); |
| 1647 ConsumeToken(); | 1641 ConsumeToken(); |
| 1648 ExpectToken(Token::kASSIGN); | 1642 ExpectToken(Token::kASSIGN); |
| 1649 // TODO(hausner): Allow non-const expressions here for final fields. | 1643 |
| 1650 AstNode* init_expr = ParseConstExpr(); | 1644 AstNode* init_expr = NULL; |
| 1645 if (field.is_const()) { |
| 1646 init_expr = ParseConstExpr(); |
| 1647 } else { |
| 1648 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1649 if (init_expr->EvalConstExpr() != NULL) { |
| 1650 init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr)); |
| 1651 } |
| 1652 } |
| 1651 ASSERT(init_expr != NULL); | 1653 ASSERT(init_expr != NULL); |
| 1652 FieldInitExpression initializer; | 1654 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
| 1653 initializer.inst_field = &field; | 1655 AstNode* field_init = |
| 1654 initializer.expr = init_expr; | 1656 new StoreInstanceFieldNode(field.token_pos(), |
| 1655 initializers->Add(initializer); | 1657 instance, |
| 1658 field, |
| 1659 init_expr); |
| 1660 current_block_->statements->Add(field_init); |
| 1656 } | 1661 } |
| 1657 } | 1662 } |
| 1658 SetPosition(saved_pos); | 1663 SetPosition(saved_pos); |
| 1659 } | 1664 } |
| 1660 | 1665 |
| 1661 | 1666 |
| 1662 void Parser::CheckDuplicateFieldInit(intptr_t init_pos, | 1667 void Parser::CheckDuplicateFieldInit(intptr_t init_pos, |
| 1663 GrowableArray<Field*>* initialized_fields, | 1668 GrowableArray<Field*>* initialized_fields, |
| 1664 Field* field) { | 1669 Field* field) { |
| 1665 ASSERT(!field->is_static()); | 1670 ASSERT(!field->is_static()); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 } | 1769 } |
| 1765 CheckFunctionIsCallable(call_pos, redirect_ctor); | 1770 CheckFunctionIsCallable(call_pos, redirect_ctor); |
| 1766 current_block_->statements->Add( | 1771 current_block_->statements->Add( |
| 1767 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 1772 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 1768 } | 1773 } |
| 1769 | 1774 |
| 1770 | 1775 |
| 1771 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 1776 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 1772 ASSERT(func.IsConstructor()); | 1777 ASSERT(func.IsConstructor()); |
| 1773 const intptr_t ctor_pos = TokenPos(); | 1778 const intptr_t ctor_pos = TokenPos(); |
| 1774 | |
| 1775 // Implicit 'this' is the only parameter/local variable. | |
| 1776 OpenFunctionBlock(func); | 1779 OpenFunctionBlock(func); |
| 1777 | 1780 const Class& cls = Class::Handle(func.owner()); |
| 1778 // Parse expressions of instance fields that have an explicit | |
| 1779 // initializers. | |
| 1780 GrowableArray<FieldInitExpression> initializers; | |
| 1781 GrowableArray<Field*> initialized_fields; | |
| 1782 Class& cls = Class::Handle(func.owner()); | |
| 1783 ParseInitializedInstanceFields(cls, &initializers, &initialized_fields); | |
| 1784 | |
| 1785 LocalVariable* receiver = new LocalVariable( | 1781 LocalVariable* receiver = new LocalVariable( |
| 1786 ctor_pos, | 1782 ctor_pos, |
| 1787 String::ZoneHandle(Symbols::This()), | 1783 String::ZoneHandle(Symbols::This()), |
| 1788 Type::ZoneHandle(Type::DynamicType())); | 1784 Type::ZoneHandle(Type::DynamicType())); |
| 1789 current_block_->scope->AddVariable(receiver); | 1785 current_block_->scope->AddVariable(receiver); |
| 1790 | 1786 |
| 1791 LocalVariable* phase_parameter = new LocalVariable( | 1787 LocalVariable* phase_parameter = new LocalVariable( |
| 1792 ctor_pos, | 1788 ctor_pos, |
| 1793 String::ZoneHandle(Symbols::PhaseParameter()), | 1789 String::ZoneHandle(Symbols::PhaseParameter()), |
| 1794 Type::ZoneHandle(Type::IntInterface())); | 1790 Type::ZoneHandle(Type::IntInterface())); |
| 1795 current_block_->scope->AddVariable(phase_parameter); | 1791 current_block_->scope->AddVariable(phase_parameter); |
| 1796 | 1792 |
| 1797 // Now that the "this" parameter is in scope, we can generate the code | 1793 // Parse expressions of instance fields that have an explicit |
| 1798 // to strore the initializer expressions in the respective instance fields. | 1794 // initializer expression. |
| 1799 for (int i = 0; i < initializers.length(); i++) { | 1795 // The receiver must not be visible to field initializer expressions. |
| 1800 const Field* field = initializers[i].inst_field; | 1796 receiver->set_invisible(true); |
| 1801 AstNode* instance = new LoadLocalNode(field->token_pos(), receiver); | 1797 GrowableArray<Field*> initialized_fields; |
| 1802 AstNode* field_init = | 1798 ParseInitializedInstanceFields(cls, receiver, &initialized_fields); |
| 1803 new StoreInstanceFieldNode(field->token_pos(), | 1799 receiver->set_invisible(false); |
| 1804 instance, | |
| 1805 *field, | |
| 1806 initializers[i].expr); | |
| 1807 current_block_->statements->Add(field_init); | |
| 1808 } | |
| 1809 | 1800 |
| 1810 GenerateSuperConstructorCall(cls, receiver); | 1801 GenerateSuperConstructorCall(cls, receiver); |
| 1811 CheckConstFieldsInitialized(cls); | 1802 CheckConstFieldsInitialized(cls); |
| 1812 | 1803 |
| 1813 // Empty constructor body. | 1804 // Empty constructor body. |
| 1814 SequenceNode* statements = CloseBlock(); | 1805 SequenceNode* statements = CloseBlock(); |
| 1815 return statements; | 1806 return statements; |
| 1816 } | 1807 } |
| 1817 | 1808 |
| 1818 | 1809 |
| 1810 // Helper function to make the first num_variables variables in the |
| 1811 // given scope visible/invisible. |
| 1812 static void SetInvisible(LocalScope* scope, int num_variables, bool invisible) { |
| 1813 ASSERT(num_variables <= scope->num_variables()); |
| 1814 for (int i = 0; i < num_variables; i++) { |
| 1815 scope->VariableAt(i)->set_invisible(invisible); |
| 1816 } |
| 1817 } |
| 1818 |
| 1819 |
| 1819 // Parser is at the opening parenthesis of the formal parameter declaration | 1820 // Parser is at the opening parenthesis of the formal parameter declaration |
| 1820 // of function. Parse the formal parameters, initializers and code. | 1821 // of function. Parse the formal parameters, initializers and code. |
| 1821 SequenceNode* Parser::ParseConstructor(const Function& func, | 1822 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 1822 Array& default_parameter_values) { | 1823 Array& default_parameter_values) { |
| 1823 TRACE_PARSER("ParseConstructor"); | 1824 TRACE_PARSER("ParseConstructor"); |
| 1824 ASSERT(func.IsConstructor()); | 1825 ASSERT(func.IsConstructor()); |
| 1825 ASSERT(!func.IsFactory()); | 1826 ASSERT(!func.IsFactory()); |
| 1826 ASSERT(!func.is_static()); | 1827 ASSERT(!func.is_static()); |
| 1827 ASSERT(!func.IsLocalFunction()); | 1828 ASSERT(!func.IsLocalFunction()); |
| 1828 const Class& cls = Class::Handle(func.owner()); | 1829 const Class& cls = Class::Handle(func.owner()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1858 | 1859 |
| 1859 if (func.is_const()) { | 1860 if (func.is_const()) { |
| 1860 params.SetImplicitlyFinal(); | 1861 params.SetImplicitlyFinal(); |
| 1861 } | 1862 } |
| 1862 ParseFormalParameterList(allow_explicit_default_values, ¶ms); | 1863 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
| 1863 | 1864 |
| 1864 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 1865 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 1865 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 1866 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 1866 ASSERT(func.NumberOfParameters() == params.parameters->length()); | 1867 ASSERT(func.NumberOfParameters() == params.parameters->length()); |
| 1867 | 1868 |
| 1868 // Initialize instance fields that have an explicit initializer expression. | |
| 1869 // This has to be done before code for field initializer parameters | |
| 1870 // is generated. | |
| 1871 // NB: the instance field initializers have to be compiled before | |
| 1872 // the parameters are added to the scope, so that a parameter | |
| 1873 // name cannot shadow a name used in the field initializer expression. | |
| 1874 GrowableArray<FieldInitExpression> initializers; | |
| 1875 GrowableArray<Field*> initialized_fields; | |
| 1876 ParseInitializedInstanceFields(cls, &initializers, &initialized_fields); | |
| 1877 | |
| 1878 // Now populate function scope with the formal parameters. | 1869 // Now populate function scope with the formal parameters. |
| 1879 AddFormalParamsToScope(¶ms, current_block_->scope); | 1870 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1871 |
| 1872 // Initialize instance fields that have an explicit initializer expression. |
| 1873 // The formal parameter names must not be visible to the instance |
| 1874 // field initializer expressions, yet the parameters must be added to |
| 1875 // the scope so the expressions use the correct offsets for 'this' when |
| 1876 // storing values. We make the formal parameters temporarily invisible |
| 1877 // while parsing the instance field initializer expressions. |
| 1878 SetInvisible(current_block_->scope, params.parameters->length(), true); |
| 1879 GrowableArray<Field*> initialized_fields; |
| 1880 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1880 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1881 | |
| 1882 // Now that the "this" parameter is in scope, we can generate the code | |
| 1883 // to store the initializer expressions in the respective instance fields. | |
| 1884 // We do this before the field parameters and the initializers from the | |
| 1885 // constructor's initializer list get compiled. | |
| 1886 OpenBlock(); | 1881 OpenBlock(); |
| 1887 for (int i = 0; i < initializers.length(); i++) { | 1882 ParseInitializedInstanceFields(cls, receiver, &initialized_fields); |
| 1888 const Field* field = initializers[i].inst_field; | 1883 // Make the parameters (which are in the outer scope) visible again. |
| 1889 AstNode* instance = new LoadLocalNode(field->token_pos(), receiver); | 1884 SetInvisible(current_block_->scope->parent(), |
| 1890 AstNode* field_init = | 1885 params.parameters->length(), false); |
| 1891 new StoreInstanceFieldNode(field->token_pos(), | |
| 1892 instance, | |
| 1893 *field, | |
| 1894 initializers[i].expr); | |
| 1895 current_block_->statements->Add(field_init); | |
| 1896 } | |
| 1897 | 1886 |
| 1898 // Turn formal field parameters into field initializers or report error | 1887 // Turn formal field parameters into field initializers or report error |
| 1899 // if the function is not a constructor. | 1888 // if the function is not a constructor. |
| 1900 if (params.has_field_initializer) { | 1889 if (params.has_field_initializer) { |
| 1901 for (int i = 0; i < params.parameters->length(); i++) { | 1890 for (int i = 0; i < params.parameters->length(); i++) { |
| 1902 ParamDesc& param = (*params.parameters)[i]; | 1891 ParamDesc& param = (*params.parameters)[i]; |
| 1903 if (param.is_field_initializer) { | 1892 if (param.is_field_initializer) { |
| 1904 const String& field_name = *param.name; | 1893 const String& field_name = *param.name; |
| 1905 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); | 1894 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); |
| 1906 if (field.IsNull()) { | 1895 if (field.IsNull()) { |
| (...skipping 7147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9054 void Parser::SkipQualIdent() { | 9043 void Parser::SkipQualIdent() { |
| 9055 ASSERT(IsIdentifier()); | 9044 ASSERT(IsIdentifier()); |
| 9056 ConsumeToken(); | 9045 ConsumeToken(); |
| 9057 if (CurrentToken() == Token::kPERIOD) { | 9046 if (CurrentToken() == Token::kPERIOD) { |
| 9058 ConsumeToken(); // Consume the kPERIOD token. | 9047 ConsumeToken(); // Consume the kPERIOD token. |
| 9059 ExpectIdentifier("identifier expected after '.'"); | 9048 ExpectIdentifier("identifier expected after '.'"); |
| 9060 } | 9049 } |
| 9061 } | 9050 } |
| 9062 | 9051 |
| 9063 } // namespace dart | 9052 } // namespace dart |
| OLD | NEW |