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

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

Issue 10832126: Store pointer instead of reference to LocalVariable in ast and flow graph. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scopes.cc » ('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 (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 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 const bool kTestOnly = true; 702 const bool kTestOnly = true;
703 if (parser.current_function().IsInFactoryScope()) { 703 if (parser.current_function().IsInFactoryScope()) {
704 instantiator = parser.LookupTypeArgumentsParameter(node_sequence->scope(), 704 instantiator = parser.LookupTypeArgumentsParameter(node_sequence->scope(),
705 kTestOnly); 705 kTestOnly);
706 } else { 706 } else {
707 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly); 707 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly);
708 } 708 }
709 if (!parser.current_function().IsLocalFunction() || 709 if (!parser.current_function().IsLocalFunction() ||
710 ((instantiator != NULL) && instantiator->is_captured())) { 710 ((instantiator != NULL) && instantiator->is_captured())) {
711 parsed_function->set_instantiator( 711 parsed_function->set_instantiator(
712 new LoadLocalNode(node_sequence->token_pos(), *instantiator)); 712 new LoadLocalNode(node_sequence->token_pos(), instantiator));
713 } 713 }
714 } 714 }
715 715
716 parsed_function->set_default_parameter_values(default_parameter_values); 716 parsed_function->set_default_parameter_values(default_parameter_values);
717 } 717 }
718 718
719 719
720 // TODO(regis): Implement support for non-const final static fields (currently 720 // TODO(regis): Implement support for non-const final static fields (currently
721 // supported "final" fields are actually const fields). 721 // supported "final" fields are actually const fields).
722 // TODO(regis): Since a const variable is implicitly final, 722 // TODO(regis): Since a const variable is implicitly final,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 ASSERT(func.num_fixed_parameters() == 1); // receiver. 844 ASSERT(func.num_fixed_parameters() == 1); // receiver.
845 ASSERT(func.num_optional_parameters() == 0); 845 ASSERT(func.num_optional_parameters() == 0);
846 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 846 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
847 847
848 // Build local scope for function and populate with the formal parameters. 848 // Build local scope for function and populate with the formal parameters.
849 OpenFunctionBlock(func); 849 OpenFunctionBlock(func);
850 AddFormalParamsToScope(&params, current_block_->scope); 850 AddFormalParamsToScope(&params, current_block_->scope);
851 851
852 // Receiver is local 0. 852 // Receiver is local 0.
853 LocalVariable* receiver = current_block_->scope->VariableAt(0); 853 LocalVariable* receiver = current_block_->scope->VariableAt(0);
854 LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), *receiver); 854 LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), receiver);
855 // TokenPos() returns the function's token position which points to the 855 // TokenPos() returns the function's token position which points to the
856 // name of the field; 856 // name of the field;
857 ASSERT(IsIdentifier()); 857 ASSERT(IsIdentifier());
858 const String& field_name = *CurrentLiteral(); 858 const String& field_name = *CurrentLiteral();
859 const Class& field_class = Class::Handle(func.owner()); 859 const Class& field_class = Class::Handle(func.owner());
860 const Field& field = 860 const Field& field =
861 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); 861 Field::ZoneHandle(field_class.LookupInstanceField(field_name));
862 862
863 LoadInstanceFieldNode* load_field = 863 LoadInstanceFieldNode* load_field =
864 new LoadInstanceFieldNode(TokenPos(), load_receiver, field); 864 new LoadInstanceFieldNode(TokenPos(), load_receiver, field);
(...skipping 27 matching lines...) Expand all
892 &field_type); 892 &field_type);
893 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. 893 ASSERT(func.num_fixed_parameters() == 2); // receiver, value.
894 ASSERT(func.num_optional_parameters() == 0); 894 ASSERT(func.num_optional_parameters() == 0);
895 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); 895 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType());
896 896
897 // Build local scope for function and populate with the formal parameters. 897 // Build local scope for function and populate with the formal parameters.
898 OpenFunctionBlock(func); 898 OpenFunctionBlock(func);
899 AddFormalParamsToScope(&params, current_block_->scope); 899 AddFormalParamsToScope(&params, current_block_->scope);
900 900
901 LoadLocalNode* receiver = 901 LoadLocalNode* receiver =
902 new LoadLocalNode(TokenPos(), *current_block_->scope->VariableAt(0)); 902 new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(0));
903 LoadLocalNode* value = 903 LoadLocalNode* value =
904 new LoadLocalNode(TokenPos(), *current_block_->scope->VariableAt(1)); 904 new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(1));
905 905
906 StoreInstanceFieldNode* store_field = 906 StoreInstanceFieldNode* store_field =
907 new StoreInstanceFieldNode(TokenPos(), receiver, field, value); 907 new StoreInstanceFieldNode(TokenPos(), receiver, field, value);
908 908
909 current_block_->statements->Add(store_field); 909 current_block_->statements->Add(store_field);
910 current_block_->statements->Add(new ReturnNode(TokenPos())); 910 current_block_->statements->Add(new ReturnNode(TokenPos()));
911 return CloseBlock(); 911 return CloseBlock();
912 } 912 }
913 913
914 914
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 ExpectToken(Token::kRBRACK); 1319 ExpectToken(Token::kRBRACK);
1320 1320
1321 if (Token::IsAssignmentOperator(CurrentToken()) && 1321 if (Token::IsAssignmentOperator(CurrentToken()) &&
1322 (CurrentToken() != Token::kASSIGN)) { 1322 (CurrentToken() != Token::kASSIGN)) {
1323 // Compound assignment. Ensure side effects in index expression 1323 // Compound assignment. Ensure side effects in index expression
1324 // only execute once. If the index is not a local variable or an 1324 // only execute once. If the index is not a local variable or an
1325 // literal, evaluate and save in a temporary local. 1325 // literal, evaluate and save in a temporary local.
1326 if (!IsSimpleLocalOrLiteralNode(index_expr)) { 1326 if (!IsSimpleLocalOrLiteralNode(index_expr)) {
1327 LocalVariable* temp = 1327 LocalVariable* temp =
1328 CreateTempConstVariable(operator_pos, "lix"); 1328 CreateTempConstVariable(operator_pos, "lix");
1329 AstNode* save = 1329 AstNode* save = new StoreLocalNode(operator_pos, temp, index_expr);
1330 new StoreLocalNode(operator_pos, *temp, index_expr);
1331 current_block_->statements->Add(save); 1330 current_block_->statements->Add(save);
1332 index_expr = new LoadLocalNode(operator_pos, *temp); 1331 index_expr = new LoadLocalNode(operator_pos, temp);
1333 } 1332 }
1334 } 1333 }
1335 1334
1336 // Resolve the [] operator function in the superclass. 1335 // Resolve the [] operator function in the superclass.
1337 const String& index_operator_name = 1336 const String& index_operator_name =
1338 String::ZoneHandle(Symbols::IndexToken()); 1337 String::ZoneHandle(Symbols::IndexToken());
1339 bool is_no_such_method = false; 1338 bool is_no_such_method = false;
1340 const Function& index_operator = Function::ZoneHandle( 1339 const Function& index_operator = Function::ZoneHandle(
1341 GetSuperFunction(operator_pos, 1340 GetSuperFunction(operator_pos,
1342 index_operator_name, 1341 index_operator_name,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 // we're not compiling class Object), or if the super class is an 1504 // we're not compiling class Object), or if the super class is an
1506 // artificially generated "wrapper class" that has no constructor. 1505 // artificially generated "wrapper class" that has no constructor.
1507 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { 1506 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) {
1508 return; 1507 return;
1509 } 1508 }
1510 String& ctor_name = String::Handle(super_class.Name()); 1509 String& ctor_name = String::Handle(super_class.Name());
1511 String& ctor_suffix = String::Handle(Symbols::Dot()); 1510 String& ctor_suffix = String::Handle(Symbols::Dot());
1512 ctor_name = String::Concat(ctor_name, ctor_suffix); 1511 ctor_name = String::Concat(ctor_name, ctor_suffix);
1513 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1512 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1514 // Implicit 'this' parameter is the first argument. 1513 // Implicit 'this' parameter is the first argument.
1515 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); 1514 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
1516 arguments->Add(implicit_argument); 1515 arguments->Add(implicit_argument);
1517 // Implicit construction phase parameter is second argument. 1516 // Implicit construction phase parameter is second argument.
1518 AstNode* phase_parameter = 1517 AstNode* phase_parameter =
1519 new LiteralNode(supercall_pos, 1518 new LiteralNode(supercall_pos,
1520 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 1519 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
1521 arguments->Add(phase_parameter); 1520 arguments->Add(phase_parameter);
1522 const Function& super_ctor = Function::ZoneHandle( 1521 const Function& super_ctor = Function::ZoneHandle(
1523 super_class.LookupConstructor(ctor_name)); 1522 super_class.LookupConstructor(ctor_name));
1524 if (super_ctor.IsNull()) { 1523 if (super_ctor.IsNull()) {
1525 ErrorMsg(supercall_pos, 1524 ErrorMsg(supercall_pos,
(...skipping 30 matching lines...) Expand all
1556 ctor_suffix = String::Concat( 1555 ctor_suffix = String::Concat(
1557 ctor_suffix, *ExpectIdentifier("constructor name expected")); 1556 ctor_suffix, *ExpectIdentifier("constructor name expected"));
1558 } 1557 }
1559 ctor_name = String::Concat(ctor_name, ctor_suffix); 1558 ctor_name = String::Concat(ctor_name, ctor_suffix);
1560 if (CurrentToken() != Token::kLPAREN) { 1559 if (CurrentToken() != Token::kLPAREN) {
1561 ErrorMsg("parameter list expected"); 1560 ErrorMsg("parameter list expected");
1562 } 1561 }
1563 1562
1564 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1563 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1565 // 'this' parameter is the first argument to super class constructor. 1564 // 'this' parameter is the first argument to super class constructor.
1566 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); 1565 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
1567 arguments->Add(implicit_argument); 1566 arguments->Add(implicit_argument);
1568 // Second implicit parameter is the construction phase. We optimistically 1567 // Second implicit parameter is the construction phase. We optimistically
1569 // assume that we can execute both the super initializer and the super 1568 // assume that we can execute both the super initializer and the super
1570 // constructor body. We may later change this to only execute the 1569 // constructor body. We may later change this to only execute the
1571 // super initializer. 1570 // super initializer.
1572 AstNode* phase_parameter = 1571 AstNode* phase_parameter =
1573 new LiteralNode(supercall_pos, 1572 new LiteralNode(supercall_pos,
1574 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 1573 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
1575 arguments->Add(phase_parameter); 1574 arguments->Add(phase_parameter);
1576 // 'this' parameter must not be accessible to the other super call arguments. 1575 // 'this' parameter must not be accessible to the other super call arguments.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 receiver->set_invisible(true); 1616 receiver->set_invisible(true);
1618 AstNode* init_expr = ParseConditionalExpr(); 1617 AstNode* init_expr = ParseConditionalExpr();
1619 receiver->set_invisible(false); 1618 receiver->set_invisible(false);
1620 SetAllowFunctionLiterals(saved_mode); 1619 SetAllowFunctionLiterals(saved_mode);
1621 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); 1620 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1622 if (field.IsNull()) { 1621 if (field.IsNull()) {
1623 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", 1622 ErrorMsg(field_pos, "unresolved reference to instance field '%s'",
1624 field_name.ToCString()); 1623 field_name.ToCString());
1625 } 1624 }
1626 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); 1625 CheckDuplicateFieldInit(field_pos, initialized_fields, &field);
1627 AstNode* instance = new LoadLocalNode(field_pos, *receiver); 1626 AstNode* instance = new LoadLocalNode(field_pos, receiver);
1628 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); 1627 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr);
1629 } 1628 }
1630 1629
1631 1630
1632 void Parser::CheckConstFieldsInitialized(const Class& cls) { 1631 void Parser::CheckConstFieldsInitialized(const Class& cls) {
1633 const Array& fields = Array::Handle(cls.fields()); 1632 const Array& fields = Array::Handle(cls.fields());
1634 Field& field = Field::Handle(); 1633 Field& field = Field::Handle();
1635 SequenceNode* initializers = current_block_->statements; 1634 SequenceNode* initializers = current_block_->statements;
1636 for (int field_num = 0; field_num < fields.Length(); field_num++) { 1635 for (int field_num = 0; field_num < fields.Length(); field_num++) {
1637 field ^= fields.At(field_num); 1636 field ^= fields.At(field_num);
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 ctor_suffix = String::Concat( 1771 ctor_suffix = String::Concat(
1773 ctor_suffix, *ExpectIdentifier("constructor name expected")); 1772 ctor_suffix, *ExpectIdentifier("constructor name expected"));
1774 } 1773 }
1775 ctor_name = String::Concat(ctor_name, ctor_suffix); 1774 ctor_name = String::Concat(ctor_name, ctor_suffix);
1776 if (CurrentToken() != Token::kLPAREN) { 1775 if (CurrentToken() != Token::kLPAREN) {
1777 ErrorMsg("parameter list expected"); 1776 ErrorMsg("parameter list expected");
1778 } 1777 }
1779 1778
1780 ArgumentListNode* arguments = new ArgumentListNode(call_pos); 1779 ArgumentListNode* arguments = new ArgumentListNode(call_pos);
1781 // 'this' parameter is the first argument to constructor. 1780 // 'this' parameter is the first argument to constructor.
1782 AstNode* implicit_argument = new LoadLocalNode(call_pos, *receiver); 1781 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver);
1783 arguments->Add(implicit_argument); 1782 arguments->Add(implicit_argument);
1784 // Construction phase parameter is second argument. 1783 // Construction phase parameter is second argument.
1785 LocalVariable* phase_param = LookupPhaseParameter(); 1784 LocalVariable* phase_param = LookupPhaseParameter();
1786 ASSERT(phase_param != NULL); 1785 ASSERT(phase_param != NULL);
1787 AstNode* phase_argument = new LoadLocalNode(call_pos, *phase_param); 1786 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param);
1788 arguments->Add(phase_argument); 1787 arguments->Add(phase_argument);
1789 ParseActualParameters(arguments, kAllowConst); 1788 ParseActualParameters(arguments, kAllowConst);
1790 1789
1791 // Resolve the constructor. 1790 // Resolve the constructor.
1792 const Function& redirect_ctor = Function::ZoneHandle( 1791 const Function& redirect_ctor = Function::ZoneHandle(
1793 cls.LookupConstructor(ctor_name)); 1792 cls.LookupConstructor(ctor_name));
1794 if (redirect_ctor.IsNull()) { 1793 if (redirect_ctor.IsNull()) {
1795 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString()); 1794 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString());
1796 } 1795 }
1797 String& error_message = String::Handle(); 1796 String& error_message = String::Handle();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 LocalVariable* phase_parameter = new LocalVariable( 1831 LocalVariable* phase_parameter = new LocalVariable(
1833 ctor_pos, 1832 ctor_pos,
1834 String::ZoneHandle(Symbols::PhaseParameter()), 1833 String::ZoneHandle(Symbols::PhaseParameter()),
1835 Type::ZoneHandle(Type::IntInterface())); 1834 Type::ZoneHandle(Type::IntInterface()));
1836 current_block_->scope->AddVariable(phase_parameter); 1835 current_block_->scope->AddVariable(phase_parameter);
1837 1836
1838 // Now that the "this" parameter is in scope, we can generate the code 1837 // Now that the "this" parameter is in scope, we can generate the code
1839 // to strore the initializer expressions in the respective instance fields. 1838 // to strore the initializer expressions in the respective instance fields.
1840 for (int i = 0; i < initializers.length(); i++) { 1839 for (int i = 0; i < initializers.length(); i++) {
1841 const Field* field = initializers[i].inst_field; 1840 const Field* field = initializers[i].inst_field;
1842 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); 1841 AstNode* instance = new LoadLocalNode(field->token_pos(), receiver);
1843 AstNode* field_init = 1842 AstNode* field_init =
1844 new StoreInstanceFieldNode(field->token_pos(), 1843 new StoreInstanceFieldNode(field->token_pos(),
1845 instance, 1844 instance,
1846 *field, 1845 *field,
1847 initializers[i].expr); 1846 initializers[i].expr);
1848 current_block_->statements->Add(field_init); 1847 current_block_->statements->Add(field_init);
1849 } 1848 }
1850 1849
1851 GenerateSuperConstructorCall(cls, receiver); 1850 GenerateSuperConstructorCall(cls, receiver);
1852 CheckConstFieldsInitialized(cls); 1851 CheckConstFieldsInitialized(cls);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 AddFormalParamsToScope(&params, current_block_->scope); 1919 AddFormalParamsToScope(&params, current_block_->scope);
1921 LocalVariable* receiver = current_block_->scope->VariableAt(0); 1920 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1922 1921
1923 // Now that the "this" parameter is in scope, we can generate the code 1922 // Now that the "this" parameter is in scope, we can generate the code
1924 // to store the initializer expressions in the respective instance fields. 1923 // to store the initializer expressions in the respective instance fields.
1925 // We do this before the field parameters and the initializers from the 1924 // We do this before the field parameters and the initializers from the
1926 // constructor's initializer list get compiled. 1925 // constructor's initializer list get compiled.
1927 OpenBlock(); 1926 OpenBlock();
1928 for (int i = 0; i < initializers.length(); i++) { 1927 for (int i = 0; i < initializers.length(); i++) {
1929 const Field* field = initializers[i].inst_field; 1928 const Field* field = initializers[i].inst_field;
1930 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); 1929 AstNode* instance = new LoadLocalNode(field->token_pos(), receiver);
1931 AstNode* field_init = 1930 AstNode* field_init =
1932 new StoreInstanceFieldNode(field->token_pos(), 1931 new StoreInstanceFieldNode(field->token_pos(),
1933 instance, 1932 instance,
1934 *field, 1933 *field,
1935 initializers[i].expr); 1934 initializers[i].expr);
1936 current_block_->statements->Add(field_init); 1935 current_block_->statements->Add(field_init);
1937 } 1936 }
1938 1937
1939 // Turn formal field parameters into field initializers or report error 1938 // Turn formal field parameters into field initializers or report error
1940 // if the function is not a constructor. 1939 // if the function is not a constructor.
1941 if (params.has_field_initializer) { 1940 if (params.has_field_initializer) {
1942 for (int i = 0; i < params.parameters->length(); i++) { 1941 for (int i = 0; i < params.parameters->length(); i++) {
1943 ParamDesc& param = (*params.parameters)[i]; 1942 ParamDesc& param = (*params.parameters)[i];
1944 if (param.is_field_initializer) { 1943 if (param.is_field_initializer) {
1945 const String& field_name = *param.name; 1944 const String& field_name = *param.name;
1946 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); 1945 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1947 if (field.IsNull()) { 1946 if (field.IsNull()) {
1948 ErrorMsg(param.name_pos, 1947 ErrorMsg(param.name_pos,
1949 "unresolved reference to instance field '%s'", 1948 "unresolved reference to instance field '%s'",
1950 field_name.ToCString()); 1949 field_name.ToCString());
1951 } 1950 }
1952 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); 1951 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field);
1953 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver); 1952 AstNode* instance = new LoadLocalNode(param.name_pos, receiver);
1954 LocalVariable* p = 1953 LocalVariable* p =
1955 current_block_->scope->LookupVariable(*param.name, false); 1954 current_block_->scope->LookupVariable(*param.name, false);
1956 ASSERT(p != NULL); 1955 ASSERT(p != NULL);
1957 // Initializing formals cannot be used in the explicit initializer 1956 // Initializing formals cannot be used in the explicit initializer
1958 // list, nor can they be used in the constructor body. 1957 // list, nor can they be used in the constructor body.
1959 // Thus, make the parameter invisible. 1958 // Thus, make the parameter invisible.
1960 p->set_invisible(true); 1959 p->set_invisible(true);
1961 AstNode* value = new LoadLocalNode(param.name_pos, *p); 1960 AstNode* value = new LoadLocalNode(param.name_pos, p);
1962 AstNode* initializer = new StoreInstanceFieldNode( 1961 AstNode* initializer = new StoreInstanceFieldNode(
1963 param.name_pos, instance, field, value); 1962 param.name_pos, instance, field, value);
1964 current_block_->statements->Add(initializer); 1963 current_block_->statements->Add(initializer);
1965 } 1964 }
1966 } 1965 }
1967 } 1966 }
1968 1967
1969 // Now parse the explicit initializer list or constructor redirection. 1968 // Now parse the explicit initializer list or constructor redirection.
1970 ParseInitializers(cls, receiver, &initialized_fields); 1969 ParseInitializers(cls, receiver, &initialized_fields);
1971 1970
1972 SequenceNode* init_statements = CloseBlock(); 1971 SequenceNode* init_statements = CloseBlock();
1973 if (init_statements->length() > 0) { 1972 if (init_statements->length() > 0) {
1974 // Generate guard around the initializer code. 1973 // Generate guard around the initializer code.
1975 LocalVariable* phase_param = LookupPhaseParameter(); 1974 LocalVariable* phase_param = LookupPhaseParameter();
1976 AstNode* phase_value = new LoadLocalNode(TokenPos(), *phase_param); 1975 AstNode* phase_value = new LoadLocalNode(TokenPos(), phase_param);
1977 AstNode* phase_check = new BinaryOpNode( 1976 AstNode* phase_check = new BinaryOpNode(
1978 TokenPos(), Token::kBIT_AND, phase_value, 1977 TokenPos(), Token::kBIT_AND, phase_value,
1979 new LiteralNode(TokenPos(), 1978 new LiteralNode(TokenPos(),
1980 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); 1979 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1981 AstNode* comparison = 1980 AstNode* comparison =
1982 new ComparisonNode(TokenPos(), Token::kNE_STRICT, 1981 new ComparisonNode(TokenPos(), Token::kNE_STRICT,
1983 phase_check, 1982 phase_check,
1984 new LiteralNode(TokenPos(), 1983 new LiteralNode(TokenPos(),
1985 Smi::ZoneHandle(Smi::New(0)))); 1984 Smi::ZoneHandle(Smi::New(0))));
1986 AstNode* guarded_init_statements = 1985 AstNode* guarded_init_statements =
(...skipping 29 matching lines...) Expand all
2016 // expressions are not evaluated twice. 2015 // expressions are not evaluated twice.
2017 ArgumentListNode* ctor_args = super_call->arguments(); 2016 ArgumentListNode* ctor_args = super_call->arguments();
2018 // The super initializer call has at least 2 arguments: the 2017 // The super initializer call has at least 2 arguments: the
2019 // implicit receiver, and the hidden construction phase. 2018 // implicit receiver, and the hidden construction phase.
2020 ASSERT(ctor_args->length() >= 2); 2019 ASSERT(ctor_args->length() >= 2);
2021 for (int i = 2; i < ctor_args->length(); i++) { 2020 for (int i = 2; i < ctor_args->length(); i++) {
2022 AstNode* arg = ctor_args->NodeAt(i); 2021 AstNode* arg = ctor_args->NodeAt(i);
2023 if (!IsSimpleLocalOrLiteralNode(arg)) { 2022 if (!IsSimpleLocalOrLiteralNode(arg)) {
2024 LocalVariable* temp = 2023 LocalVariable* temp =
2025 CreateTempConstVariable(arg->token_pos(), "sca"); 2024 CreateTempConstVariable(arg->token_pos(), "sca");
2026 AstNode* save_temp = 2025 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg);
2027 new StoreLocalNode(arg->token_pos(), *temp, arg);
2028 ctor_args->SetNodeAt(i, save_temp); 2026 ctor_args->SetNodeAt(i, save_temp);
2029 } 2027 }
2030 } 2028 }
2031 } 2029 }
2032 OpenBlock(); // Block to collect constructor body nodes. 2030 OpenBlock(); // Block to collect constructor body nodes.
2033 2031
2034 // Insert the implicit super call to the super constructor body. 2032 // Insert the implicit super call to the super constructor body.
2035 if (super_call != NULL) { 2033 if (super_call != NULL) {
2036 ArgumentListNode* initializer_args = super_call->arguments(); 2034 ArgumentListNode* initializer_args = super_call->arguments();
2037 const Function& super_ctor = super_call->function(); 2035 const Function& super_ctor = super_call->function();
2038 // Patch the initializer call so it only executes the super initializer. 2036 // Patch the initializer call so it only executes the super initializer.
2039 initializer_args->SetNodeAt(1, 2037 initializer_args->SetNodeAt(1,
2040 new LiteralNode(TokenPos(), 2038 new LiteralNode(TokenPos(),
2041 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); 2039 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
2042 2040
2043 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos()); 2041 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos());
2044 // First argument is the receiver. 2042 // First argument is the receiver.
2045 super_call_args->Add(new LoadLocalNode(TokenPos(), *receiver)); 2043 super_call_args->Add(new LoadLocalNode(TokenPos(), receiver));
2046 // Second argument is the construction phase argument. 2044 // Second argument is the construction phase argument.
2047 AstNode* phase_parameter = 2045 AstNode* phase_parameter =
2048 new LiteralNode(TokenPos(), 2046 new LiteralNode(TokenPos(),
2049 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); 2047 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)));
2050 super_call_args->Add(phase_parameter); 2048 super_call_args->Add(phase_parameter);
2051 super_call_args->set_names(initializer_args->names()); 2049 super_call_args->set_names(initializer_args->names());
2052 for (int i = 2; i < initializer_args->length(); i++) { 2050 for (int i = 2; i < initializer_args->length(); i++) {
2053 AstNode* arg = initializer_args->NodeAt(i); 2051 AstNode* arg = initializer_args->NodeAt(i);
2054 if (arg->IsLiteralNode()) { 2052 if (arg->IsLiteralNode()) {
2055 LiteralNode* lit = arg->AsLiteralNode(); 2053 LiteralNode* lit = arg->AsLiteralNode();
2056 super_call_args->Add(new LiteralNode(TokenPos(), lit->literal())); 2054 super_call_args->Add(new LiteralNode(TokenPos(), lit->literal()));
2057 } else { 2055 } else {
2058 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); 2056 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
2059 if (arg->IsLoadLocalNode()) { 2057 if (arg->IsLoadLocalNode()) {
2060 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); 2058 const LocalVariable& temp = arg->AsLoadLocalNode()->local();
2061 super_call_args->Add(new LoadLocalNode(TokenPos(), temp)); 2059 super_call_args->Add(new LoadLocalNode(TokenPos(), &temp));
2062 } else if (arg->IsStoreLocalNode()) { 2060 } else if (arg->IsStoreLocalNode()) {
2063 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); 2061 const LocalVariable& temp = arg->AsStoreLocalNode()->local();
2064 super_call_args->Add(new LoadLocalNode(TokenPos(), temp)); 2062 super_call_args->Add(new LoadLocalNode(TokenPos(), &temp));
2065 } 2063 }
2066 } 2064 }
2067 } 2065 }
2068 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), 2066 ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
2069 super_call_args->names(), 2067 super_call_args->names(),
2070 NULL)); 2068 NULL));
2071 current_block_->statements->Add( 2069 current_block_->statements->Add(
2072 new StaticCallNode(TokenPos(), super_ctor, super_call_args)); 2070 new StaticCallNode(TokenPos(), super_ctor, super_call_args));
2073 } 2071 }
2074 2072
2075 if (CurrentToken() == Token::kLBRACE) { 2073 if (CurrentToken() == Token::kLBRACE) {
2076 ConsumeToken(); 2074 ConsumeToken();
2077 ParseStatementSequence(); 2075 ParseStatementSequence();
2078 ExpectToken(Token::kRBRACE); 2076 ExpectToken(Token::kRBRACE);
2079 } else if (CurrentToken() == Token::kARROW) { 2077 } else if (CurrentToken() == Token::kARROW) {
2080 ErrorMsg("constructors may not return a value"); 2078 ErrorMsg("constructors may not return a value");
2081 } else if (IsLiteral("native")) { 2079 } else if (IsLiteral("native")) {
2082 ErrorMsg("native constructors not supported"); 2080 ErrorMsg("native constructors not supported");
2083 } else if (CurrentToken() == Token::kSEMICOLON) { 2081 } else if (CurrentToken() == Token::kSEMICOLON) {
2084 // Some constructors have no function body. 2082 // Some constructors have no function body.
2085 ConsumeToken(); 2083 ConsumeToken();
2086 } else { 2084 } else {
2087 UnexpectedToken(); 2085 UnexpectedToken();
2088 } 2086 }
2089 2087
2090 SequenceNode* ctor_block = CloseBlock(); 2088 SequenceNode* ctor_block = CloseBlock();
2091 if (ctor_block->length() > 0) { 2089 if (ctor_block->length() > 0) {
2092 // Generate guard around the constructor body code. 2090 // Generate guard around the constructor body code.
2093 LocalVariable* phase_param = LookupPhaseParameter(); 2091 LocalVariable* phase_param = LookupPhaseParameter();
2094 AstNode* phase_value = new LoadLocalNode(TokenPos(), *phase_param); 2092 AstNode* phase_value = new LoadLocalNode(TokenPos(), phase_param);
2095 AstNode* phase_check = 2093 AstNode* phase_check =
2096 new BinaryOpNode(TokenPos(), Token::kBIT_AND, 2094 new BinaryOpNode(TokenPos(), Token::kBIT_AND,
2097 phase_value, 2095 phase_value,
2098 new LiteralNode(TokenPos(), 2096 new LiteralNode(TokenPos(),
2099 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); 2097 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
2100 AstNode* comparison = 2098 AstNode* comparison =
2101 new ComparisonNode(TokenPos(), Token::kNE_STRICT, 2099 new ComparisonNode(TokenPos(), Token::kNE_STRICT,
2102 phase_check, 2100 phase_check,
2103 new LiteralNode(TokenPos(), 2101 new LiteralNode(TokenPos(),
2104 Smi::ZoneHandle(Smi::New(0)))); 2102 Smi::ZoneHandle(Smi::New(0))));
(...skipping 2099 matching lines...) Expand 10 before | Expand all | Expand 10 after
4204 4202
4205 4203
4206 AstNode* Parser::LoadReceiver(intptr_t token_pos) { 4204 AstNode* Parser::LoadReceiver(intptr_t token_pos) {
4207 // A nested function may access 'this', referring to the receiver of the 4205 // A nested function may access 'this', referring to the receiver of the
4208 // outermost enclosing function. 4206 // outermost enclosing function.
4209 const bool kTestOnly = false; 4207 const bool kTestOnly = false;
4210 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); 4208 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly);
4211 if (receiver == NULL) { 4209 if (receiver == NULL) {
4212 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); 4210 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'");
4213 } 4211 }
4214 return new LoadLocalNode(TokenPos(), *receiver); 4212 return new LoadLocalNode(TokenPos(), receiver);
4215 } 4213 }
4216 4214
4217 4215
4218 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) { 4216 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) {
4219 // A nested function may access ':type_arguments' to use as instantiator, 4217 // A nested function may access ':type_arguments' to use as instantiator,
4220 // referring to the implicit first parameter of the outermost enclosing 4218 // referring to the implicit first parameter of the outermost enclosing
4221 // factory function. 4219 // factory function.
4222 const bool kTestOnly = false; 4220 const bool kTestOnly = false;
4223 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope, 4221 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope,
4224 kTestOnly); 4222 kTestOnly);
4225 ASSERT(param != NULL); 4223 ASSERT(param != NULL);
4226 return new LoadLocalNode(TokenPos(), *param); 4224 return new LoadLocalNode(TokenPos(), param);
4227 } 4225 }
4228 4226
4229 4227
4230 AstNode* Parser::CallGetter(intptr_t token_pos, 4228 AstNode* Parser::CallGetter(intptr_t token_pos,
4231 AstNode* object, 4229 AstNode* object,
4232 const String& name) { 4230 const String& name) {
4233 return new InstanceGetterNode(TokenPos(), object, name); 4231 return new InstanceGetterNode(TokenPos(), object, name);
4234 } 4232 }
4235 4233
4236 4234
4237 // Returns ast nodes of the variable initialization. 4235 // Returns ast nodes of the variable initialization.
4238 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, 4236 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type,
4239 bool is_final, 4237 bool is_final,
4240 bool is_const) { 4238 bool is_const) {
4241 TRACE_PARSER("ParseVariableDeclaration"); 4239 TRACE_PARSER("ParseVariableDeclaration");
4242 ASSERT(IsIdentifier()); 4240 ASSERT(IsIdentifier());
4243 const intptr_t ident_pos = TokenPos(); 4241 const intptr_t ident_pos = TokenPos();
4244 LocalVariable* variable = 4242 LocalVariable* variable =
4245 new LocalVariable(ident_pos, *CurrentLiteral(), type); 4243 new LocalVariable(ident_pos, *CurrentLiteral(), type);
4246 ASSERT(current_block_ != NULL); 4244 ASSERT(current_block_ != NULL);
4247 ASSERT(current_block_->scope != NULL); 4245 ASSERT(current_block_->scope != NULL);
4248 ConsumeToken(); // Variable identifier. 4246 ConsumeToken(); // Variable identifier.
4249 AstNode* initialization = NULL; 4247 AstNode* initialization = NULL;
4250 if (CurrentToken() == Token::kASSIGN) { 4248 if (CurrentToken() == Token::kASSIGN) {
4251 // Variable initialization. 4249 // Variable initialization.
4252 const intptr_t assign_pos = TokenPos(); 4250 const intptr_t assign_pos = TokenPos();
4253 ConsumeToken(); 4251 ConsumeToken();
4254 AstNode* expr = ParseExpr(is_const, kConsumeCascades); 4252 AstNode* expr = ParseExpr(is_const, kConsumeCascades);
4255 initialization = new StoreLocalNode(assign_pos, *variable, expr); 4253 initialization = new StoreLocalNode(assign_pos, variable, expr);
4256 } else if (is_final || is_const) { 4254 } else if (is_final || is_const) {
4257 ErrorMsg(ident_pos, 4255 ErrorMsg(ident_pos,
4258 "missing initialization of 'final' or 'const' variable"); 4256 "missing initialization of 'final' or 'const' variable");
4259 } else { 4257 } else {
4260 // Initialize variable with null. 4258 // Initialize variable with null.
4261 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); 4259 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle());
4262 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); 4260 initialization = new StoreLocalNode(ident_pos, variable, null_expr);
4263 } 4261 }
4264 // Add variable to scope after parsing the initalizer expression. 4262 // Add variable to scope after parsing the initalizer expression.
4265 // The expression must not be able to refer to the variable. 4263 // The expression must not be able to refer to the variable.
4266 if (!current_block_->scope->AddVariable(variable)) { 4264 if (!current_block_->scope->AddVariable(variable)) {
4267 ErrorMsg(ident_pos, "identifier '%s' already defined", 4265 ErrorMsg(ident_pos, "identifier '%s' already defined",
4268 variable->name().ToCString()); 4266 variable->name().ToCString());
4269 } 4267 }
4270 if (is_final || is_const) { 4268 if (is_final || is_const) {
4271 variable->set_is_final(); 4269 variable->set_is_final();
4272 } 4270 }
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4528 // This pruning is done by omitting to hook the local scope in its parent 4526 // This pruning is done by omitting to hook the local scope in its parent
4529 // scope in the constructor of LocalScope. 4527 // scope in the constructor of LocalScope.
4530 AstNode* closure = 4528 AstNode* closure =
4531 new ClosureNode(ident_pos, function, NULL, statements->scope()); 4529 new ClosureNode(ident_pos, function, NULL, statements->scope());
4532 4530
4533 if (function_variable == NULL) { 4531 if (function_variable == NULL) {
4534 ASSERT(is_literal); 4532 ASSERT(is_literal);
4535 return closure; 4533 return closure;
4536 } else { 4534 } else {
4537 AstNode* initialization = 4535 AstNode* initialization =
4538 new StoreLocalNode(ident_pos, *function_variable, closure); 4536 new StoreLocalNode(ident_pos, function_variable, closure);
4539 return initialization; 4537 return initialization;
4540 } 4538 }
4541 } 4539 }
4542 4540
4543 4541
4544 // Returns true if the current and next tokens can be parsed as type 4542 // Returns true if the current and next tokens can be parsed as type
4545 // parameters. Current token position is not saved and restored. 4543 // parameters. Current token position is not saved and restored.
4546 bool Parser::TryParseTypeParameter() { 4544 bool Parser::TryParseTypeParameter() {
4547 if (CurrentToken() == Token::kLT) { 4545 if (CurrentToken() == Token::kLT) {
4548 // We are possibly looking at type parameters. Find closing ">". 4546 // We are possibly looking at type parameters. Find closing ">".
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
4911 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); 4909 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL);
4912 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { 4910 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) {
4913 if (CurrentToken() == Token::kCASE) { 4911 if (CurrentToken() == Token::kCASE) {
4914 if (default_seen) { 4912 if (default_seen) {
4915 ErrorMsg("default clause must be last case"); 4913 ErrorMsg("default clause must be last case");
4916 } 4914 }
4917 ConsumeToken(); // Keyword case. 4915 ConsumeToken(); // Keyword case.
4918 const intptr_t expr_pos = TokenPos(); 4916 const intptr_t expr_pos = TokenPos();
4919 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 4917 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
4920 AstNode* switch_expr_load = new LoadLocalNode(case_pos, 4918 AstNode* switch_expr_load = new LoadLocalNode(case_pos,
4921 *switch_expr_value); 4919 switch_expr_value);
4922 AstNode* case_comparison = new ComparisonNode(expr_pos, 4920 AstNode* case_comparison = new ComparisonNode(expr_pos,
4923 Token::kEQ, 4921 Token::kEQ,
4924 expr, 4922 expr,
4925 switch_expr_load); 4923 switch_expr_load);
4926 case_expressions->Add(case_comparison); 4924 case_expressions->Add(case_comparison);
4927 } else { 4925 } else {
4928 if (default_seen) { 4926 if (default_seen) {
4929 ErrorMsg("only one default clause is allowed"); 4927 ErrorMsg("only one default clause is allowed");
4930 } 4928 }
4931 ConsumeToken(); // Keyword default. 4929 ConsumeToken(); // Keyword default.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
5002 OpenBlock(); 5000 OpenBlock();
5003 current_block_->scope->AddLabel(label); 5001 current_block_->scope->AddLabel(label);
5004 5002
5005 // Store switch expression in temporary local variable. 5003 // Store switch expression in temporary local variable.
5006 LocalVariable* temp_variable = 5004 LocalVariable* temp_variable =
5007 new LocalVariable(expr_pos, 5005 new LocalVariable(expr_pos,
5008 String::ZoneHandle(Symbols::New(":switch_expr")), 5006 String::ZoneHandle(Symbols::New(":switch_expr")),
5009 Type::ZoneHandle(Type::DynamicType())); 5007 Type::ZoneHandle(Type::DynamicType()));
5010 current_block_->scope->AddVariable(temp_variable); 5008 current_block_->scope->AddVariable(temp_variable);
5011 AstNode* save_switch_expr = 5009 AstNode* save_switch_expr =
5012 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); 5010 new StoreLocalNode(expr_pos, temp_variable, switch_expr);
5013 current_block_->statements->Add(save_switch_expr); 5011 current_block_->statements->Add(save_switch_expr);
5014 5012
5015 // Parse case clauses 5013 // Parse case clauses
5016 bool default_seen = false; 5014 bool default_seen = false;
5017 while (true) { 5015 while (true) {
5018 // Check for statement label 5016 // Check for statement label
5019 SourceLabel* case_label = NULL; 5017 SourceLabel* case_label = NULL;
5020 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { 5018 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) {
5021 // Case statements start with a label. 5019 // Case statements start with a label.
5022 String* label_name = CurrentLiteral(); 5020 String* label_name = CurrentLiteral();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
5147 new LocalVariable(collection_pos, iterator_name, iterator_type); 5145 new LocalVariable(collection_pos, iterator_name, iterator_type);
5148 current_block_->scope->AddVariable(iterator_var); 5146 current_block_->scope->AddVariable(iterator_var);
5149 5147
5150 // Generate initialization of iterator variable. 5148 // Generate initialization of iterator variable.
5151 const String& iterator_method_name = 5149 const String& iterator_method_name =
5152 String::ZoneHandle(Symbols::GetIterator()); 5150 String::ZoneHandle(Symbols::GetIterator());
5153 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); 5151 ArgumentListNode* no_args = new ArgumentListNode(collection_pos);
5154 AstNode* get_iterator = new InstanceCallNode( 5152 AstNode* get_iterator = new InstanceCallNode(
5155 collection_pos, collection_expr, iterator_method_name, no_args); 5153 collection_pos, collection_expr, iterator_method_name, no_args);
5156 AstNode* iterator_init = 5154 AstNode* iterator_init =
5157 new StoreLocalNode(collection_pos, *iterator_var, get_iterator); 5155 new StoreLocalNode(collection_pos, iterator_var, get_iterator);
5158 current_block_->statements->Add(iterator_init); 5156 current_block_->statements->Add(iterator_init);
5159 5157
5160 // Generate while loop condition. 5158 // Generate while loop condition.
5161 AstNode* iterator_has_next = new InstanceCallNode( 5159 AstNode* iterator_has_next = new InstanceCallNode(
5162 collection_pos, 5160 collection_pos,
5163 new LoadLocalNode(collection_pos, *iterator_var), 5161 new LoadLocalNode(collection_pos, iterator_var),
5164 String::ZoneHandle(Symbols::HasNext()), 5162 String::ZoneHandle(Symbols::HasNext()),
5165 no_args); 5163 no_args);
5166 5164
5167 // Parse the for loop body. Ideally, we would use ParseNestedStatement() 5165 // Parse the for loop body. Ideally, we would use ParseNestedStatement()
5168 // here, but that does not work well because we have to insert an implicit 5166 // here, but that does not work well because we have to insert an implicit
5169 // variable assignment and potentially a variable declaration in the 5167 // variable assignment and potentially a variable declaration in the
5170 // loop body. 5168 // loop body.
5171 OpenLoopBlock(); 5169 OpenLoopBlock();
5172 current_block_->scope->AddLabel(label); 5170 current_block_->scope->AddLabel(label);
5173 5171
5174 AstNode* iterator_next = new InstanceCallNode( 5172 AstNode* iterator_next = new InstanceCallNode(
5175 collection_pos, 5173 collection_pos,
5176 new LoadLocalNode(collection_pos, *iterator_var), 5174 new LoadLocalNode(collection_pos, iterator_var),
5177 String::ZoneHandle(Symbols::Next()), 5175 String::ZoneHandle(Symbols::Next()),
5178 no_args); 5176 no_args);
5179 5177
5180 // Generate assignment of next iterator value to loop variable. 5178 // Generate assignment of next iterator value to loop variable.
5181 AstNode* loop_var_assignment = NULL; 5179 AstNode* loop_var_assignment = NULL;
5182 if (loop_var != NULL) { 5180 if (loop_var != NULL) {
5183 // The for loop declares a new variable. Add it to the loop body scope. 5181 // The for loop declares a new variable. Add it to the loop body scope.
5184 current_block_->scope->AddVariable(loop_var); 5182 current_block_->scope->AddVariable(loop_var);
5185 loop_var_assignment = 5183 loop_var_assignment =
5186 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); 5184 new StoreLocalNode(loop_var_pos, loop_var, iterator_next);
5187 } else { 5185 } else {
5188 AstNode* loop_var_primary = 5186 AstNode* loop_var_primary =
5189 ResolveIdent(loop_var_pos, *loop_var_name, false); 5187 ResolveIdent(loop_var_pos, *loop_var_name, false);
5190 ASSERT(!loop_var_primary->IsPrimaryNode()); 5188 ASSERT(!loop_var_primary->IsPrimaryNode());
5191 loop_var_assignment = 5189 loop_var_assignment =
5192 CreateAssignmentNode(loop_var_primary, iterator_next); 5190 CreateAssignmentNode(loop_var_primary, iterator_next);
5193 if (loop_var_assignment == NULL) { 5191 if (loop_var_assignment == NULL) {
5194 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", 5192 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable",
5195 loop_var_name->ToCString()); 5193 loop_var_name->ToCString());
5196 } 5194 }
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
5587 OpenBlock(); 5585 OpenBlock();
5588 5586
5589 // Generate code to load the exception object (:exception_var) into 5587 // Generate code to load the exception object (:exception_var) into
5590 // the exception variable specified in this block. 5588 // the exception variable specified in this block.
5591 ASSERT(exception_param.var != NULL); 5589 ASSERT(exception_param.var != NULL);
5592 LocalVariable* var = LookupLocalScope(*exception_param.var); 5590 LocalVariable* var = LookupLocalScope(*exception_param.var);
5593 ASSERT(var != NULL); 5591 ASSERT(var != NULL);
5594 ASSERT(catch_excp_var != NULL); 5592 ASSERT(catch_excp_var != NULL);
5595 current_block_->statements->Add( 5593 current_block_->statements->Add(
5596 new StoreLocalNode(catch_pos, 5594 new StoreLocalNode(catch_pos,
5597 *var, 5595 var,
5598 new LoadLocalNode(catch_pos, *catch_excp_var))); 5596 new LoadLocalNode(catch_pos, catch_excp_var)));
5599 if (stack_trace_param.var != NULL) { 5597 if (stack_trace_param.var != NULL) {
5600 // A stack trace variable is specified in this block, so generate code 5598 // A stack trace variable is specified in this block, so generate code
5601 // to load the stack trace object (:stacktrace_var) into the stack trace 5599 // to load the stack trace object (:stacktrace_var) into the stack trace
5602 // variable specified in this block. 5600 // variable specified in this block.
5603 LocalVariable* trace = LookupLocalScope(*stack_trace_param.var); 5601 LocalVariable* trace = LookupLocalScope(*stack_trace_param.var);
5604 ASSERT(catch_trace_var != NULL); 5602 ASSERT(catch_trace_var != NULL);
5605 current_block_->statements->Add( 5603 current_block_->statements->Add(
5606 new StoreLocalNode(catch_pos, 5604 new StoreLocalNode(catch_pos,
5607 *trace, 5605 trace,
5608 new LoadLocalNode(catch_pos, *catch_trace_var))); 5606 new LoadLocalNode(catch_pos, catch_trace_var)));
5609 } 5607 }
5610 5608
5611 ParseStatementSequence(); // Parse the catch handler code. 5609 ParseStatementSequence(); // Parse the catch handler code.
5612 current_block_->statements->Add( 5610 current_block_->statements->Add(
5613 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); 5611 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label));
5614 SequenceNode* catch_handler = CloseBlock(); 5612 SequenceNode* catch_handler = CloseBlock();
5615 ExpectToken(Token::kRBRACE); 5613 ExpectToken(Token::kRBRACE);
5616 5614
5617 if (!exception_param.type->IsDynamicType()) { // Has a type specification. 5615 if (!exception_param.type->IsDynamicType()) { // Has a type specification.
5618 // Now form an 'if type check' as an exception type exists in 5616 // Now form an 'if type check' as an exception type exists in
5619 // the catch specifier. 5617 // the catch specifier.
5620 if (!exception_param.type->IsInstantiated() && 5618 if (!exception_param.type->IsInstantiated() &&
5621 (current_block_->scope->function_level() > 0)) { 5619 (current_block_->scope->function_level() > 0)) {
5622 // Make sure that the instantiator is captured. 5620 // Make sure that the instantiator is captured.
5623 CaptureInstantiator(); 5621 CaptureInstantiator();
5624 } 5622 }
5625 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); 5623 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type);
5626 AstNode* exception_var = new LoadLocalNode(catch_pos, *catch_excp_var); 5624 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var);
5627 if (!exception_type->type().IsInstantiated()) { 5625 if (!exception_type->type().IsInstantiated()) {
5628 EnsureExpressionTemp(); 5626 EnsureExpressionTemp();
5629 } 5627 }
5630 AstNode* type_cond_expr = new ComparisonNode( 5628 AstNode* type_cond_expr = new ComparisonNode(
5631 catch_pos, Token::kIS, exception_var, exception_type); 5629 catch_pos, Token::kIS, exception_var, exception_type);
5632 current_block_->statements->Add( 5630 current_block_->statements->Add(
5633 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); 5631 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL));
5634 } else { 5632 } else {
5635 // No exception type exists in the catch specifier so execute the 5633 // No exception type exists in the catch specifier so execute the
5636 // catch handler code unconditionally. 5634 // catch handler code unconditionally.
(...skipping 15 matching lines...) Expand all
5652 ConsumeToken(); // Consume the 'finally'. 5650 ConsumeToken(); // Consume the 'finally'.
5653 const intptr_t finally_pos = TokenPos(); 5651 const intptr_t finally_pos = TokenPos();
5654 // Add the finally block to the exit points recorded so far. 5652 // Add the finally block to the exit points recorded so far.
5655 intptr_t node_index = 0; 5653 intptr_t node_index = 0;
5656 AstNode* node_to_inline = 5654 AstNode* node_to_inline =
5657 inner_try_block->GetNodeToInlineFinally(node_index); 5655 inner_try_block->GetNodeToInlineFinally(node_index);
5658 while (node_to_inline != NULL) { 5656 while (node_to_inline != NULL) {
5659 finally_block = ParseFinallyBlock(); 5657 finally_block = ParseFinallyBlock();
5660 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, 5658 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos,
5661 finally_block, 5659 finally_block,
5662 *context_var); 5660 context_var);
5663 AddFinallyBlockToNode(node_to_inline, node); 5661 AddFinallyBlockToNode(node_to_inline, node);
5664 node_index += 1; 5662 node_index += 1;
5665 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 5663 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
5666 tokens_iterator_.SetCurrentPosition(finally_pos); 5664 tokens_iterator_.SetCurrentPosition(finally_pos);
5667 } 5665 }
5668 if (!generic_catch_seen) { 5666 if (!generic_catch_seen) {
5669 // No generic catch handler exists so execute this finally block 5667 // No generic catch handler exists so execute this finally block
5670 // before rethrowing the exception. 5668 // before rethrowing the exception.
5671 finally_block = ParseFinallyBlock(); 5669 finally_block = ParseFinallyBlock();
5672 catch_handler_list->Add(finally_block); 5670 catch_handler_list->Add(finally_block);
5673 tokens_iterator_.SetCurrentPosition(finally_pos); 5671 tokens_iterator_.SetCurrentPosition(finally_pos);
5674 } 5672 }
5675 finally_block = ParseFinallyBlock(); 5673 finally_block = ParseFinallyBlock();
5676 } else { 5674 } else {
5677 if (!catch_seen) { 5675 if (!catch_seen) {
5678 ErrorMsg("'catch' or 'finally' expected"); 5676 ErrorMsg("'catch' or 'finally' expected");
5679 } 5677 }
5680 } 5678 }
5681 5679
5682 if (!generic_catch_seen) { 5680 if (!generic_catch_seen) {
5683 // No generic catch handler exists so rethrow the exception so that 5681 // No generic catch handler exists so rethrow the exception so that
5684 // the next catch handler can deal with it. 5682 // the next catch handler can deal with it.
5685 catch_handler_list->Add( 5683 catch_handler_list->Add(
5686 new ThrowNode(handler_pos, 5684 new ThrowNode(handler_pos,
5687 new LoadLocalNode(handler_pos, *catch_excp_var), 5685 new LoadLocalNode(handler_pos, catch_excp_var),
5688 new LoadLocalNode(handler_pos, *catch_trace_var))); 5686 new LoadLocalNode(handler_pos, catch_trace_var)));
5689 } 5687 }
5690 CatchClauseNode* catch_block = new CatchClauseNode(handler_pos, 5688 CatchClauseNode* catch_block = new CatchClauseNode(handler_pos,
5691 catch_handler_list, 5689 catch_handler_list,
5692 *context_var, 5690 context_var,
5693 *catch_excp_var, 5691 catch_excp_var,
5694 *catch_trace_var); 5692 catch_trace_var);
5695 5693
5696 // Now create the try/catch ast node and return it. If there is a label 5694 // Now create the try/catch ast node and return it. If there is a label
5697 // on the try/catch, close the block that's embedding the try statement 5695 // on the try/catch, close the block that's embedding the try statement
5698 // and attach the label to it. 5696 // and attach the label to it.
5699 AstNode* try_catch_node = 5697 AstNode* try_catch_node =
5700 new TryCatchNode(try_pos, try_block, end_catch_label, 5698 new TryCatchNode(try_pos, try_block, end_catch_label,
5701 *context_var, catch_block, finally_block); 5699 context_var, catch_block, finally_block);
5702 5700
5703 if (try_label != NULL) { 5701 if (try_label != NULL) {
5704 current_block_->statements->Add(try_catch_node); 5702 current_block_->statements->Add(try_catch_node);
5705 SequenceNode* sequence = CloseBlock(); 5703 SequenceNode* sequence = CloseBlock();
5706 sequence->set_label(try_label); 5704 sequence->set_label(try_label);
5707 try_catch_node = sequence; 5705 try_catch_node = sequence;
5708 } 5706 }
5709 return try_catch_node; 5707 return try_catch_node;
5710 } 5708 }
5711 5709
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
5878 ASSERT(label->owner() != NULL); 5876 ASSERT(label->owner() != NULL);
5879 LocalScope* scope = label->owner()->parent(); 5877 LocalScope* scope = label->owner()->parent();
5880 ASSERT(scope != NULL); 5878 ASSERT(scope != NULL);
5881 LocalVariable* excp_var = scope->LocalLookupVariable( 5879 LocalVariable* excp_var = scope->LocalLookupVariable(
5882 String::ZoneHandle(Symbols::ExceptionVar())); 5880 String::ZoneHandle(Symbols::ExceptionVar()));
5883 ASSERT(excp_var != NULL); 5881 ASSERT(excp_var != NULL);
5884 LocalVariable* trace_var = scope->LocalLookupVariable( 5882 LocalVariable* trace_var = scope->LocalLookupVariable(
5885 String::ZoneHandle(Symbols::StacktraceVar())); 5883 String::ZoneHandle(Symbols::StacktraceVar()));
5886 ASSERT(trace_var != NULL); 5884 ASSERT(trace_var != NULL);
5887 statement = new ThrowNode(statement_pos, 5885 statement = new ThrowNode(statement_pos,
5888 new LoadLocalNode(statement_pos, *excp_var), 5886 new LoadLocalNode(statement_pos, excp_var),
5889 new LoadLocalNode(statement_pos, *trace_var)); 5887 new LoadLocalNode(statement_pos, trace_var));
5890 } 5888 }
5891 } else { 5889 } else {
5892 statement = ParseExpr(kAllowConst, kConsumeCascades); 5890 statement = ParseExpr(kAllowConst, kConsumeCascades);
5893 ExpectSemicolon(); 5891 ExpectSemicolon();
5894 } 5892 }
5895 return statement; 5893 return statement;
5896 } 5894 }
5897 5895
5898 5896
5899 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, 5897 RawError* Parser::FormatErrorWithAppend(const Error& prev_error,
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
6271 ConsumeToken(); 6269 ConsumeToken();
6272 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 6270 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
6273 list->Add(expr); 6271 list->Add(expr);
6274 } 6272 }
6275 expressions = list; 6273 expressions = list;
6276 } 6274 }
6277 return expressions; 6275 return expressions;
6278 } 6276 }
6279 6277
6280 6278
6281 const LocalVariable& Parser::GetIncrementTempLocal() { 6279 const LocalVariable* Parser::GetIncrementTempLocal() {
6282 if (expression_temp_ == NULL) { 6280 if (expression_temp_ == NULL) {
6283 expression_temp_ = ParsedFunction::CreateExpressionTempVar( 6281 expression_temp_ = ParsedFunction::CreateExpressionTempVar(
6284 current_function().token_pos()); 6282 current_function().token_pos());
6283 ASSERT(expression_temp_ != NULL);
6285 } 6284 }
6286 return *expression_temp_; 6285 return expression_temp_;
6287 } 6286 }
6288 6287
6289 6288
6290 void Parser::EnsureExpressionTemp() { 6289 void Parser::EnsureExpressionTemp() {
6291 // Temporary used later by the flow_graph_builder. 6290 // Temporary used later by the flow_graph_builder.
6292 GetIncrementTempLocal(); 6291 GetIncrementTempLocal();
6293 } 6292 }
6294 6293
6295 6294
6296 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, 6295 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
6395 AstNode* node = *expr; 6394 AstNode* node = *expr;
6396 if (node->IsLoadIndexedNode()) { 6395 if (node->IsLoadIndexedNode()) {
6397 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); 6396 LoadIndexedNode* left_node = node->AsLoadIndexedNode();
6398 LoadIndexedNode* right_node = left_node; 6397 LoadIndexedNode* right_node = left_node;
6399 intptr_t token_pos = node->token_pos(); 6398 intptr_t token_pos = node->token_pos();
6400 node = NULL; // Do not use it. 6399 node = NULL; // Do not use it.
6401 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { 6400 if (!IsSimpleLocalOrLiteralNode(left_node->array())) {
6402 LocalVariable* temp = 6401 LocalVariable* temp =
6403 CreateTempConstVariable(token_pos, "lia"); 6402 CreateTempConstVariable(token_pos, "lia");
6404 StoreLocalNode* save = 6403 StoreLocalNode* save =
6405 new StoreLocalNode(token_pos, *temp, left_node->array()); 6404 new StoreLocalNode(token_pos, temp, left_node->array());
6406 left_node = 6405 left_node =
6407 new LoadIndexedNode(token_pos, save, left_node->index_expr()); 6406 new LoadIndexedNode(token_pos, save, left_node->index_expr());
6408 right_node = new LoadIndexedNode(token_pos, 6407 right_node = new LoadIndexedNode(token_pos,
6409 new LoadLocalNode(token_pos, *temp), 6408 new LoadLocalNode(token_pos, temp),
6410 right_node->index_expr()); 6409 right_node->index_expr());
6411 } 6410 }
6412 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { 6411 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) {
6413 LocalVariable* temp = 6412 LocalVariable* temp =
6414 CreateTempConstVariable(token_pos, "lix"); 6413 CreateTempConstVariable(token_pos, "lix");
6415 StoreLocalNode* save = 6414 StoreLocalNode* save =
6416 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); 6415 new StoreLocalNode(token_pos, temp, left_node->index_expr());
6417 left_node = new LoadIndexedNode(token_pos, 6416 left_node = new LoadIndexedNode(token_pos,
6418 left_node->array(), 6417 left_node->array(),
6419 save); 6418 save);
6420 right_node = new LoadIndexedNode(token_pos, 6419 right_node = new LoadIndexedNode(token_pos,
6421 right_node->array(), 6420 right_node->array(),
6422 new LoadLocalNode(token_pos, *temp)); 6421 new LoadLocalNode(token_pos, temp));
6423 } 6422 }
6424 *expr = right_node; 6423 *expr = right_node;
6425 return left_node; 6424 return left_node;
6426 } 6425 }
6427 if (node->IsInstanceGetterNode()) { 6426 if (node->IsInstanceGetterNode()) {
6428 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); 6427 InstanceGetterNode* left_node = node->AsInstanceGetterNode();
6429 InstanceGetterNode* right_node = left_node; 6428 InstanceGetterNode* right_node = left_node;
6430 intptr_t token_pos = node->token_pos(); 6429 intptr_t token_pos = node->token_pos();
6431 node = NULL; // Do not use it. 6430 node = NULL; // Do not use it.
6432 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { 6431 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) {
6433 LocalVariable* temp = 6432 LocalVariable* temp =
6434 CreateTempConstVariable(token_pos, "igr"); 6433 CreateTempConstVariable(token_pos, "igr");
6435 StoreLocalNode* save = 6434 StoreLocalNode* save =
6436 new StoreLocalNode(token_pos, *temp, left_node->receiver()); 6435 new StoreLocalNode(token_pos, temp, left_node->receiver());
6437 left_node = new InstanceGetterNode(token_pos, 6436 left_node = new InstanceGetterNode(token_pos,
6438 save, 6437 save,
6439 left_node->field_name()); 6438 left_node->field_name());
6440 right_node = new InstanceGetterNode(token_pos, 6439 right_node = new InstanceGetterNode(token_pos,
6441 new LoadLocalNode(token_pos, *temp), 6440 new LoadLocalNode(token_pos, temp),
6442 right_node->field_name()); 6441 right_node->field_name());
6443 } 6442 }
6444 *expr = right_node; 6443 *expr = right_node;
6445 return left_node; 6444 return left_node;
6446 } 6445 }
6447 return *expr; 6446 return *expr;
6448 } 6447 }
6449 6448
6450 6449
6451 // Ensure that the expression temp is allocated for nodes that may need it. 6450 // Ensure that the expression temp is allocated for nodes that may need it.
6452 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { 6451 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) {
6453 AstNode* result = original->MakeAssignmentNode(rhs); 6452 AstNode* result = original->MakeAssignmentNode(rhs);
6454 if ((result != NULL) && 6453 if ((result != NULL) &&
6455 (result->IsStoreIndexedNode() || 6454 (result->IsStoreIndexedNode() ||
6456 result->IsInstanceSetterNode() || 6455 result->IsInstanceSetterNode() ||
6457 result->IsStaticSetterNode())) { 6456 result->IsStaticSetterNode())) {
6458 EnsureExpressionTemp(); 6457 EnsureExpressionTemp();
6459 } 6458 }
6460 return result; 6459 return result;
6461 } 6460 }
6462 6461
6463 6462
6464 AstNode* Parser::ParseCascades(AstNode* expr) { 6463 AstNode* Parser::ParseCascades(AstNode* expr) {
6465 intptr_t cascade_pos = TokenPos(); 6464 intptr_t cascade_pos = TokenPos();
6466 LocalVariable* cascade_receiver_var = 6465 LocalVariable* cascade_receiver_var =
6467 CreateTempConstVariable(cascade_pos, "casc"); 6466 CreateTempConstVariable(cascade_pos, "casc");
6468 StoreLocalNode* save_cascade = 6467 StoreLocalNode* save_cascade =
6469 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); 6468 new StoreLocalNode(cascade_pos, cascade_receiver_var, expr);
6470 current_block_->statements->Add(save_cascade); 6469 current_block_->statements->Add(save_cascade);
6471 while (CurrentToken() == Token::kCASCADE) { 6470 while (CurrentToken() == Token::kCASCADE) {
6472 cascade_pos = TokenPos(); 6471 cascade_pos = TokenPos();
6473 LoadLocalNode* load_cascade_receiver = 6472 LoadLocalNode* load_cascade_receiver =
6474 new LoadLocalNode(cascade_pos, *cascade_receiver_var); 6473 new LoadLocalNode(cascade_pos, cascade_receiver_var);
6475 if (Token::IsIdentifier(LookaheadToken(1))) { 6474 if (Token::IsIdentifier(LookaheadToken(1))) {
6476 // Replace .. with . for ParseSelectors(). 6475 // Replace .. with . for ParseSelectors().
6477 token_kind_ = Token::kPERIOD; 6476 token_kind_ = Token::kPERIOD;
6478 } else if (LookaheadToken(1) == Token::kLBRACK) { 6477 } else if (LookaheadToken(1) == Token::kLBRACK) {
6479 ConsumeToken(); 6478 ConsumeToken();
6480 } else { 6479 } else {
6481 ErrorMsg("identifier or [ expected after .."); 6480 ErrorMsg("identifier or [ expected after ..");
6482 } 6481 }
6483 expr = ParseSelectors(load_cascade_receiver, true); 6482 expr = ParseSelectors(load_cascade_receiver, true);
6484 6483
(...skipping 16 matching lines...) Expand all
6501 if (assign_expr == NULL) { 6500 if (assign_expr == NULL) {
6502 ErrorMsg(assignment_pos, 6501 ErrorMsg(assignment_pos,
6503 "left hand side of '%s' is not assignable", 6502 "left hand side of '%s' is not assignable",
6504 Token::Str(assignment_op)); 6503 Token::Str(assignment_op));
6505 } 6504 }
6506 expr = assign_expr; 6505 expr = assign_expr;
6507 } 6506 }
6508 current_block_->statements->Add(expr); 6507 current_block_->statements->Add(expr);
6509 } 6508 }
6510 // Result of the cascade is the receiver. 6509 // Result of the cascade is the receiver.
6511 return new LoadLocalNode(cascade_pos, *cascade_receiver_var); 6510 return new LoadLocalNode(cascade_pos, cascade_receiver_var);
6512 } 6511 }
6513 6512
6514 6513
6515 AstNode* Parser::ParseExpr(bool require_compiletime_const, 6514 AstNode* Parser::ParseExpr(bool require_compiletime_const,
6516 bool consume_cascades) { 6515 bool consume_cascades) {
6517 TRACE_PARSER("ParseExpr"); 6516 TRACE_PARSER("ParseExpr");
6518 const intptr_t expr_pos = TokenPos(); 6517 const intptr_t expr_pos = TokenPos();
6519 AstNode* expr = ParseConditionalExpr(); 6518 AstNode* expr = ParseConditionalExpr();
6520 if (!Token::IsAssignmentOperator(CurrentToken())) { 6519 if (!Token::IsAssignmentOperator(CurrentToken())) {
6521 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { 6520 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) {
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
7059 postfix_expr = ParseSelectors(postfix_expr, false); 7058 postfix_expr = ParseSelectors(postfix_expr, false);
7060 if (IsIncrementOperator(CurrentToken())) { 7059 if (IsIncrementOperator(CurrentToken())) {
7061 TRACE_PARSER("IncrementOperator"); 7060 TRACE_PARSER("IncrementOperator");
7062 Token::Kind incr_op = CurrentToken(); 7061 Token::Kind incr_op = CurrentToken();
7063 if (!IsAssignableExpr(postfix_expr)) { 7062 if (!IsAssignableExpr(postfix_expr)) {
7064 ErrorMsg("expression is not assignable"); 7063 ErrorMsg("expression is not assignable");
7065 } 7064 }
7066 ConsumeToken(); 7065 ConsumeToken();
7067 // Not prefix. 7066 // Not prefix.
7068 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr); 7067 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr);
7069 const LocalVariable& temp = GetIncrementTempLocal(); 7068 const LocalVariable* temp = GetIncrementTempLocal();
7070 AstNode* save = 7069 AstNode* save =
7071 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); 7070 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr);
7072 Token::Kind binary_op = 7071 Token::Kind binary_op =
7073 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 7072 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
7074 BinaryOpNode* add = new BinaryOpNode( 7073 BinaryOpNode* add = new BinaryOpNode(
7075 postfix_expr_pos, 7074 postfix_expr_pos,
7076 binary_op, 7075 binary_op,
7077 save, 7076 save,
7078 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); 7077 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1))));
7079 AstNode* store = CreateAssignmentNode(left_expr, add); 7078 AstNode* store = CreateAssignmentNode(left_expr, add);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
7373 // If node is non NULL return an AST node corresponding to the identifier. 7372 // If node is non NULL return an AST node corresponding to the identifier.
7374 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 7373 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
7375 const String &ident, 7374 const String &ident,
7376 AstNode** node) { 7375 AstNode** node) {
7377 TRACE_PARSER("ResolveIdentInLocalScope"); 7376 TRACE_PARSER("ResolveIdentInLocalScope");
7378 Isolate* isolate = Isolate::Current(); 7377 Isolate* isolate = Isolate::Current();
7379 // First try to find the identifier in the nested local scopes. 7378 // First try to find the identifier in the nested local scopes.
7380 LocalVariable* local = LookupLocalScope(ident); 7379 LocalVariable* local = LookupLocalScope(ident);
7381 if (local != NULL) { 7380 if (local != NULL) {
7382 if (node != NULL) { 7381 if (node != NULL) {
7383 *node = new LoadLocalNode(ident_pos, *local); 7382 *node = new LoadLocalNode(ident_pos, local);
7384 } 7383 }
7385 return true; 7384 return true;
7386 } 7385 }
7387 7386
7388 // Try to find the identifier in the class scope of the current class. 7387 // Try to find the identifier in the class scope of the current class.
7389 Class& cls = Class::Handle(isolate, current_class().raw()); 7388 Class& cls = Class::Handle(isolate, current_class().raw());
7390 Function& func = Function::Handle(isolate, Function::null()); 7389 Function& func = Function::Handle(isolate, Function::null());
7391 Field& field = Field::Handle(isolate, Field::null()); 7390 Field& field = Field::Handle(isolate, Field::null());
7392 7391
7393 // First check if a field exists. 7392 // First check if a field exists.
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
7877 ArgumentListNode* arguments) { 7876 ArgumentListNode* arguments) {
7878 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { 7877 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) {
7879 EnsureExpressionTemp(); 7878 EnsureExpressionTemp();
7880 } 7879 }
7881 LocalVariable* allocated = 7880 LocalVariable* allocated =
7882 CreateTempConstVariable(token_pos, "alloc"); 7881 CreateTempConstVariable(token_pos, "alloc");
7883 return new ConstructorCallNode(token_pos, 7882 return new ConstructorCallNode(token_pos,
7884 type_arguments, 7883 type_arguments,
7885 constructor, 7884 constructor,
7886 arguments, 7885 arguments,
7887 *allocated); 7886 allocated);
7888 } 7887 }
7889 7888
7890 7889
7891 static void AddKeyValuePair(ArrayNode* pairs, 7890 static void AddKeyValuePair(ArrayNode* pairs,
7892 bool is_const, 7891 bool is_const,
7893 AstNode* key, 7892 AstNode* key,
7894 AstNode* value) { 7893 AstNode* value) {
7895 if (is_const) { 7894 if (is_const) {
7896 ASSERT(key->IsLiteralNode()); 7895 ASSERT(key->IsLiteralNode());
7897 ASSERT(key->AsLiteralNode()->literal().IsString()); 7896 ASSERT(key->AsLiteralNode()->literal().IsString());
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
8577 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), 8576 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix),
8578 qual_ident); 8577 qual_ident);
8579 } 8578 }
8580 ASSERT(primary != NULL); 8579 ASSERT(primary != NULL);
8581 } else if (CurrentToken() == Token::kTHIS) { 8580 } else if (CurrentToken() == Token::kTHIS) {
8582 const String& this_name = String::Handle(Symbols::This()); 8581 const String& this_name = String::Handle(Symbols::This());
8583 LocalVariable* local = LookupLocalScope(this_name); 8582 LocalVariable* local = LookupLocalScope(this_name);
8584 if (local == NULL) { 8583 if (local == NULL) {
8585 ErrorMsg("receiver 'this' is not in scope"); 8584 ErrorMsg("receiver 'this' is not in scope");
8586 } 8585 }
8587 primary = new LoadLocalNode(TokenPos(), *local); 8586 primary = new LoadLocalNode(TokenPos(), local);
8588 ConsumeToken(); 8587 ConsumeToken();
8589 } else if (CurrentToken() == Token::kINTEGER) { 8588 } else if (CurrentToken() == Token::kINTEGER) {
8590 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); 8589 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral());
8591 primary = new LiteralNode(TokenPos(), literal); 8590 primary = new LiteralNode(TokenPos(), literal);
8592 ConsumeToken(); 8591 ConsumeToken();
8593 } else if (CurrentToken() == Token::kTRUE) { 8592 } else if (CurrentToken() == Token::kTRUE) {
8594 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::True())); 8593 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::True()));
8595 ConsumeToken(); 8594 ConsumeToken();
8596 } else if (CurrentToken() == Token::kFALSE) { 8595 } else if (CurrentToken() == Token::kFALSE) {
8597 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False())); 8596 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False()));
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
8944 void Parser::SkipQualIdent() { 8943 void Parser::SkipQualIdent() {
8945 ASSERT(IsIdentifier()); 8944 ASSERT(IsIdentifier());
8946 ConsumeToken(); 8945 ConsumeToken();
8947 if (CurrentToken() == Token::kPERIOD) { 8946 if (CurrentToken() == Token::kPERIOD) {
8948 ConsumeToken(); // Consume the kPERIOD token. 8947 ConsumeToken(); // Consume the kPERIOD token.
8949 ExpectIdentifier("identifier expected after '.'"); 8948 ExpectIdentifier("identifier expected after '.'");
8950 } 8949 }
8951 } 8950 }
8952 8951
8953 } // namespace dart 8952 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/scopes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698