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

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
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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 const bool kTestOnly = true; 716 const bool kTestOnly = true;
717 if (parser.current_function().IsInFactoryScope()) { 717 if (parser.current_function().IsInFactoryScope()) {
718 instantiator = parser.LookupTypeArgumentsParameter(node_sequence->scope(), 718 instantiator = parser.LookupTypeArgumentsParameter(node_sequence->scope(),
719 kTestOnly); 719 kTestOnly);
720 } else { 720 } else {
721 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly); 721 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly);
722 } 722 }
723 if (!parser.current_function().IsLocalFunction() || 723 if (!parser.current_function().IsLocalFunction() ||
724 ((instantiator != NULL) && instantiator->is_captured())) { 724 ((instantiator != NULL) && instantiator->is_captured())) {
725 parsed_function->set_instantiator( 725 parsed_function->set_instantiator(
726 new LoadLocalNode(node_sequence->token_pos(), *instantiator)); 726 new LoadLocalNode(node_sequence->token_pos(), instantiator));
727 } 727 }
728 } 728 }
729 729
730 parsed_function->set_default_parameter_values(default_parameter_values); 730 parsed_function->set_default_parameter_values(default_parameter_values);
731 isolate->set_ast_node_id(prev_ast_node_id); 731 isolate->set_ast_node_id(prev_ast_node_id);
732 } 732 }
733 733
734 734
735 // TODO(regis): Implement support for non-const final static fields (currently 735 // TODO(regis): Implement support for non-const final static fields (currently
736 // supported "final" fields are actually const fields). 736 // supported "final" fields are actually const fields).
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 ASSERT(func.num_fixed_parameters() == 1); // receiver. 859 ASSERT(func.num_fixed_parameters() == 1); // receiver.
860 ASSERT(func.num_optional_parameters() == 0); 860 ASSERT(func.num_optional_parameters() == 0);
861 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 861 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
862 862
863 // Build local scope for function and populate with the formal parameters. 863 // Build local scope for function and populate with the formal parameters.
864 OpenFunctionBlock(func); 864 OpenFunctionBlock(func);
865 AddFormalParamsToScope(&params, current_block_->scope); 865 AddFormalParamsToScope(&params, current_block_->scope);
866 866
867 // Receiver is local 0. 867 // Receiver is local 0.
868 LocalVariable* receiver = current_block_->scope->VariableAt(0); 868 LocalVariable* receiver = current_block_->scope->VariableAt(0);
869 LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), *receiver); 869 LoadLocalNode* load_receiver = new LoadLocalNode(TokenPos(), receiver);
870 // TokenPos() returns the function's token position which points to the 870 // TokenPos() returns the function's token position which points to the
871 // name of the field; 871 // name of the field;
872 ASSERT(IsIdentifier()); 872 ASSERT(IsIdentifier());
873 const String& field_name = *CurrentLiteral(); 873 const String& field_name = *CurrentLiteral();
874 const Class& field_class = Class::Handle(func.owner()); 874 const Class& field_class = Class::Handle(func.owner());
875 const Field& field = 875 const Field& field =
876 Field::ZoneHandle(field_class.LookupInstanceField(field_name)); 876 Field::ZoneHandle(field_class.LookupInstanceField(field_name));
877 877
878 LoadInstanceFieldNode* load_field = 878 LoadInstanceFieldNode* load_field =
879 new LoadInstanceFieldNode(TokenPos(), load_receiver, field); 879 new LoadInstanceFieldNode(TokenPos(), load_receiver, field);
(...skipping 27 matching lines...) Expand all
907 &field_type); 907 &field_type);
908 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. 908 ASSERT(func.num_fixed_parameters() == 2); // receiver, value.
909 ASSERT(func.num_optional_parameters() == 0); 909 ASSERT(func.num_optional_parameters() == 0);
910 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType()); 910 ASSERT(AbstractType::Handle(func.result_type()).IsVoidType());
911 911
912 // Build local scope for function and populate with the formal parameters. 912 // Build local scope for function and populate with the formal parameters.
913 OpenFunctionBlock(func); 913 OpenFunctionBlock(func);
914 AddFormalParamsToScope(&params, current_block_->scope); 914 AddFormalParamsToScope(&params, current_block_->scope);
915 915
916 LoadLocalNode* receiver = 916 LoadLocalNode* receiver =
917 new LoadLocalNode(TokenPos(), *current_block_->scope->VariableAt(0)); 917 new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(0));
918 LoadLocalNode* value = 918 LoadLocalNode* value =
919 new LoadLocalNode(TokenPos(), *current_block_->scope->VariableAt(1)); 919 new LoadLocalNode(TokenPos(), current_block_->scope->VariableAt(1));
920 920
921 StoreInstanceFieldNode* store_field = 921 StoreInstanceFieldNode* store_field =
922 new StoreInstanceFieldNode(TokenPos(), receiver, field, value); 922 new StoreInstanceFieldNode(TokenPos(), receiver, field, value);
923 923
924 current_block_->statements->Add(store_field); 924 current_block_->statements->Add(store_field);
925 current_block_->statements->Add(new ReturnNode(TokenPos())); 925 current_block_->statements->Add(new ReturnNode(TokenPos()));
926 return CloseBlock(); 926 return CloseBlock();
927 } 927 }
928 928
929 929
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 ExpectToken(Token::kRBRACK); 1334 ExpectToken(Token::kRBRACK);
1335 1335
1336 if (Token::IsAssignmentOperator(CurrentToken()) && 1336 if (Token::IsAssignmentOperator(CurrentToken()) &&
1337 (CurrentToken() != Token::kASSIGN)) { 1337 (CurrentToken() != Token::kASSIGN)) {
1338 // Compound assignment. Ensure side effects in index expression 1338 // Compound assignment. Ensure side effects in index expression
1339 // only execute once. If the index is not a local variable or an 1339 // only execute once. If the index is not a local variable or an
1340 // literal, evaluate and save in a temporary local. 1340 // literal, evaluate and save in a temporary local.
1341 if (!IsSimpleLocalOrLiteralNode(index_expr)) { 1341 if (!IsSimpleLocalOrLiteralNode(index_expr)) {
1342 LocalVariable* temp = 1342 LocalVariable* temp =
1343 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); 1343 CreateTempConstVariable(operator_pos, index_expr->id(), "lix");
1344 AstNode* save = 1344 AstNode* save = new StoreLocalNode(operator_pos, temp, index_expr);
1345 new StoreLocalNode(operator_pos, *temp, index_expr);
1346 current_block_->statements->Add(save); 1345 current_block_->statements->Add(save);
1347 index_expr = new LoadLocalNode(operator_pos, *temp); 1346 index_expr = new LoadLocalNode(operator_pos, temp);
1348 } 1347 }
1349 } 1348 }
1350 1349
1351 // Resolve the [] operator function in the superclass. 1350 // Resolve the [] operator function in the superclass.
1352 const String& index_operator_name = 1351 const String& index_operator_name =
1353 String::ZoneHandle(Symbols::IndexToken()); 1352 String::ZoneHandle(Symbols::IndexToken());
1354 bool is_no_such_method = false; 1353 bool is_no_such_method = false;
1355 const Function& index_operator = Function::ZoneHandle( 1354 const Function& index_operator = Function::ZoneHandle(
1356 GetSuperFunction(operator_pos, 1355 GetSuperFunction(operator_pos,
1357 index_operator_name, 1356 index_operator_name,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 // we're not compiling class Object), or if the super class is an 1519 // we're not compiling class Object), or if the super class is an
1521 // artificially generated "wrapper class" that has no constructor. 1520 // artificially generated "wrapper class" that has no constructor.
1522 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) { 1521 if (super_class.IsNull() || (super_class.num_native_fields() > 0)) {
1523 return; 1522 return;
1524 } 1523 }
1525 String& ctor_name = String::Handle(super_class.Name()); 1524 String& ctor_name = String::Handle(super_class.Name());
1526 String& ctor_suffix = String::Handle(Symbols::Dot()); 1525 String& ctor_suffix = String::Handle(Symbols::Dot());
1527 ctor_name = String::Concat(ctor_name, ctor_suffix); 1526 ctor_name = String::Concat(ctor_name, ctor_suffix);
1528 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1527 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1529 // Implicit 'this' parameter is the first argument. 1528 // Implicit 'this' parameter is the first argument.
1530 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); 1529 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
1531 arguments->Add(implicit_argument); 1530 arguments->Add(implicit_argument);
1532 // Implicit construction phase parameter is second argument. 1531 // Implicit construction phase parameter is second argument.
1533 AstNode* phase_parameter = 1532 AstNode* phase_parameter =
1534 new LiteralNode(supercall_pos, 1533 new LiteralNode(supercall_pos,
1535 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 1534 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
1536 arguments->Add(phase_parameter); 1535 arguments->Add(phase_parameter);
1537 const Function& super_ctor = Function::ZoneHandle( 1536 const Function& super_ctor = Function::ZoneHandle(
1538 super_class.LookupConstructor(ctor_name)); 1537 super_class.LookupConstructor(ctor_name));
1539 if (super_ctor.IsNull()) { 1538 if (super_ctor.IsNull()) {
1540 ErrorMsg(supercall_pos, 1539 ErrorMsg(supercall_pos,
(...skipping 30 matching lines...) Expand all
1571 ctor_suffix = String::Concat( 1570 ctor_suffix = String::Concat(
1572 ctor_suffix, *ExpectIdentifier("constructor name expected")); 1571 ctor_suffix, *ExpectIdentifier("constructor name expected"));
1573 } 1572 }
1574 ctor_name = String::Concat(ctor_name, ctor_suffix); 1573 ctor_name = String::Concat(ctor_name, ctor_suffix);
1575 if (CurrentToken() != Token::kLPAREN) { 1574 if (CurrentToken() != Token::kLPAREN) {
1576 ErrorMsg("parameter list expected"); 1575 ErrorMsg("parameter list expected");
1577 } 1576 }
1578 1577
1579 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); 1578 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
1580 // 'this' parameter is the first argument to super class constructor. 1579 // 'this' parameter is the first argument to super class constructor.
1581 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, *receiver); 1580 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver);
1582 arguments->Add(implicit_argument); 1581 arguments->Add(implicit_argument);
1583 // Second implicit parameter is the construction phase. We optimistically 1582 // Second implicit parameter is the construction phase. We optimistically
1584 // assume that we can execute both the super initializer and the super 1583 // assume that we can execute both the super initializer and the super
1585 // constructor body. We may later change this to only execute the 1584 // constructor body. We may later change this to only execute the
1586 // super initializer. 1585 // super initializer.
1587 AstNode* phase_parameter = 1586 AstNode* phase_parameter =
1588 new LiteralNode(supercall_pos, 1587 new LiteralNode(supercall_pos,
1589 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 1588 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)));
1590 arguments->Add(phase_parameter); 1589 arguments->Add(phase_parameter);
1591 // 'this' parameter must not be accessible to the other super call arguments. 1590 // 'this' parameter must not be accessible to the other super call arguments.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 receiver->set_invisible(true); 1631 receiver->set_invisible(true);
1633 AstNode* init_expr = ParseConditionalExpr(); 1632 AstNode* init_expr = ParseConditionalExpr();
1634 receiver->set_invisible(false); 1633 receiver->set_invisible(false);
1635 SetAllowFunctionLiterals(saved_mode); 1634 SetAllowFunctionLiterals(saved_mode);
1636 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); 1635 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1637 if (field.IsNull()) { 1636 if (field.IsNull()) {
1638 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", 1637 ErrorMsg(field_pos, "unresolved reference to instance field '%s'",
1639 field_name.ToCString()); 1638 field_name.ToCString());
1640 } 1639 }
1641 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); 1640 CheckDuplicateFieldInit(field_pos, initialized_fields, &field);
1642 AstNode* instance = new LoadLocalNode(field_pos, *receiver); 1641 AstNode* instance = new LoadLocalNode(field_pos, receiver);
1643 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); 1642 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr);
1644 } 1643 }
1645 1644
1646 1645
1647 void Parser::CheckConstFieldsInitialized(const Class& cls) { 1646 void Parser::CheckConstFieldsInitialized(const Class& cls) {
1648 const Array& fields = Array::Handle(cls.fields()); 1647 const Array& fields = Array::Handle(cls.fields());
1649 Field& field = Field::Handle(); 1648 Field& field = Field::Handle();
1650 SequenceNode* initializers = current_block_->statements; 1649 SequenceNode* initializers = current_block_->statements;
1651 for (int field_num = 0; field_num < fields.Length(); field_num++) { 1650 for (int field_num = 0; field_num < fields.Length(); field_num++) {
1652 field ^= fields.At(field_num); 1651 field ^= fields.At(field_num);
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 ctor_suffix = String::Concat( 1786 ctor_suffix = String::Concat(
1788 ctor_suffix, *ExpectIdentifier("constructor name expected")); 1787 ctor_suffix, *ExpectIdentifier("constructor name expected"));
1789 } 1788 }
1790 ctor_name = String::Concat(ctor_name, ctor_suffix); 1789 ctor_name = String::Concat(ctor_name, ctor_suffix);
1791 if (CurrentToken() != Token::kLPAREN) { 1790 if (CurrentToken() != Token::kLPAREN) {
1792 ErrorMsg("parameter list expected"); 1791 ErrorMsg("parameter list expected");
1793 } 1792 }
1794 1793
1795 ArgumentListNode* arguments = new ArgumentListNode(call_pos); 1794 ArgumentListNode* arguments = new ArgumentListNode(call_pos);
1796 // 'this' parameter is the first argument to constructor. 1795 // 'this' parameter is the first argument to constructor.
1797 AstNode* implicit_argument = new LoadLocalNode(call_pos, *receiver); 1796 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver);
1798 arguments->Add(implicit_argument); 1797 arguments->Add(implicit_argument);
1799 // Construction phase parameter is second argument. 1798 // Construction phase parameter is second argument.
1800 LocalVariable* phase_param = LookupPhaseParameter(); 1799 LocalVariable* phase_param = LookupPhaseParameter();
1801 ASSERT(phase_param != NULL); 1800 ASSERT(phase_param != NULL);
1802 AstNode* phase_argument = new LoadLocalNode(call_pos, *phase_param); 1801 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param);
1803 arguments->Add(phase_argument); 1802 arguments->Add(phase_argument);
1804 ParseActualParameters(arguments, kAllowConst); 1803 ParseActualParameters(arguments, kAllowConst);
1805 1804
1806 // Resolve the constructor. 1805 // Resolve the constructor.
1807 const Function& redirect_ctor = Function::ZoneHandle( 1806 const Function& redirect_ctor = Function::ZoneHandle(
1808 cls.LookupConstructor(ctor_name)); 1807 cls.LookupConstructor(ctor_name));
1809 if (redirect_ctor.IsNull()) { 1808 if (redirect_ctor.IsNull()) {
1810 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString()); 1809 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString());
1811 } 1810 }
1812 String& error_message = String::Handle(); 1811 String& error_message = String::Handle();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 LocalVariable* phase_parameter = new LocalVariable( 1846 LocalVariable* phase_parameter = new LocalVariable(
1848 ctor_pos, 1847 ctor_pos,
1849 String::ZoneHandle(Symbols::PhaseParameter()), 1848 String::ZoneHandle(Symbols::PhaseParameter()),
1850 Type::ZoneHandle(Type::IntInterface())); 1849 Type::ZoneHandle(Type::IntInterface()));
1851 current_block_->scope->AddVariable(phase_parameter); 1850 current_block_->scope->AddVariable(phase_parameter);
1852 1851
1853 // Now that the "this" parameter is in scope, we can generate the code 1852 // Now that the "this" parameter is in scope, we can generate the code
1854 // to strore the initializer expressions in the respective instance fields. 1853 // to strore the initializer expressions in the respective instance fields.
1855 for (int i = 0; i < initializers.length(); i++) { 1854 for (int i = 0; i < initializers.length(); i++) {
1856 const Field* field = initializers[i].inst_field; 1855 const Field* field = initializers[i].inst_field;
1857 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); 1856 AstNode* instance = new LoadLocalNode(field->token_pos(), receiver);
1858 AstNode* field_init = 1857 AstNode* field_init =
1859 new StoreInstanceFieldNode(field->token_pos(), 1858 new StoreInstanceFieldNode(field->token_pos(),
1860 instance, 1859 instance,
1861 *field, 1860 *field,
1862 initializers[i].expr); 1861 initializers[i].expr);
1863 current_block_->statements->Add(field_init); 1862 current_block_->statements->Add(field_init);
1864 } 1863 }
1865 1864
1866 GenerateSuperConstructorCall(cls, receiver); 1865 GenerateSuperConstructorCall(cls, receiver);
1867 CheckConstFieldsInitialized(cls); 1866 CheckConstFieldsInitialized(cls);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 AddFormalParamsToScope(&params, current_block_->scope); 1934 AddFormalParamsToScope(&params, current_block_->scope);
1936 LocalVariable* receiver = current_block_->scope->VariableAt(0); 1935 LocalVariable* receiver = current_block_->scope->VariableAt(0);
1937 1936
1938 // Now that the "this" parameter is in scope, we can generate the code 1937 // Now that the "this" parameter is in scope, we can generate the code
1939 // to store the initializer expressions in the respective instance fields. 1938 // to store the initializer expressions in the respective instance fields.
1940 // We do this before the field parameters and the initializers from the 1939 // We do this before the field parameters and the initializers from the
1941 // constructor's initializer list get compiled. 1940 // constructor's initializer list get compiled.
1942 OpenBlock(); 1941 OpenBlock();
1943 for (int i = 0; i < initializers.length(); i++) { 1942 for (int i = 0; i < initializers.length(); i++) {
1944 const Field* field = initializers[i].inst_field; 1943 const Field* field = initializers[i].inst_field;
1945 AstNode* instance = new LoadLocalNode(field->token_pos(), *receiver); 1944 AstNode* instance = new LoadLocalNode(field->token_pos(), receiver);
1946 AstNode* field_init = 1945 AstNode* field_init =
1947 new StoreInstanceFieldNode(field->token_pos(), 1946 new StoreInstanceFieldNode(field->token_pos(),
1948 instance, 1947 instance,
1949 *field, 1948 *field,
1950 initializers[i].expr); 1949 initializers[i].expr);
1951 current_block_->statements->Add(field_init); 1950 current_block_->statements->Add(field_init);
1952 } 1951 }
1953 1952
1954 // Turn formal field parameters into field initializers or report error 1953 // Turn formal field parameters into field initializers or report error
1955 // if the function is not a constructor. 1954 // if the function is not a constructor.
1956 if (params.has_field_initializer) { 1955 if (params.has_field_initializer) {
1957 for (int i = 0; i < params.parameters->length(); i++) { 1956 for (int i = 0; i < params.parameters->length(); i++) {
1958 ParamDesc& param = (*params.parameters)[i]; 1957 ParamDesc& param = (*params.parameters)[i];
1959 if (param.is_field_initializer) { 1958 if (param.is_field_initializer) {
1960 const String& field_name = *param.name; 1959 const String& field_name = *param.name;
1961 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); 1960 Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
1962 if (field.IsNull()) { 1961 if (field.IsNull()) {
1963 ErrorMsg(param.name_pos, 1962 ErrorMsg(param.name_pos,
1964 "unresolved reference to instance field '%s'", 1963 "unresolved reference to instance field '%s'",
1965 field_name.ToCString()); 1964 field_name.ToCString());
1966 } 1965 }
1967 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); 1966 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field);
1968 AstNode* instance = new LoadLocalNode(param.name_pos, *receiver); 1967 AstNode* instance = new LoadLocalNode(param.name_pos, receiver);
1969 LocalVariable* p = 1968 LocalVariable* p =
1970 current_block_->scope->LookupVariable(*param.name, false); 1969 current_block_->scope->LookupVariable(*param.name, false);
1971 ASSERT(p != NULL); 1970 ASSERT(p != NULL);
1972 // Initializing formals cannot be used in the explicit initializer 1971 // Initializing formals cannot be used in the explicit initializer
1973 // list, nor can they be used in the constructor body. 1972 // list, nor can they be used in the constructor body.
1974 // Thus, make the parameter invisible. 1973 // Thus, make the parameter invisible.
1975 p->set_invisible(true); 1974 p->set_invisible(true);
1976 AstNode* value = new LoadLocalNode(param.name_pos, *p); 1975 AstNode* value = new LoadLocalNode(param.name_pos, p);
1977 AstNode* initializer = new StoreInstanceFieldNode( 1976 AstNode* initializer = new StoreInstanceFieldNode(
1978 param.name_pos, instance, field, value); 1977 param.name_pos, instance, field, value);
1979 current_block_->statements->Add(initializer); 1978 current_block_->statements->Add(initializer);
1980 } 1979 }
1981 } 1980 }
1982 } 1981 }
1983 1982
1984 // Now parse the explicit initializer list or constructor redirection. 1983 // Now parse the explicit initializer list or constructor redirection.
1985 ParseInitializers(cls, receiver, &initialized_fields); 1984 ParseInitializers(cls, receiver, &initialized_fields);
1986 1985
1987 SequenceNode* init_statements = CloseBlock(); 1986 SequenceNode* init_statements = CloseBlock();
1988 if (init_statements->length() > 0) { 1987 if (init_statements->length() > 0) {
1989 // Generate guard around the initializer code. 1988 // Generate guard around the initializer code.
1990 LocalVariable* phase_param = LookupPhaseParameter(); 1989 LocalVariable* phase_param = LookupPhaseParameter();
1991 AstNode* phase_value = new LoadLocalNode(TokenPos(), *phase_param); 1990 AstNode* phase_value = new LoadLocalNode(TokenPos(), phase_param);
1992 AstNode* phase_check = new BinaryOpNode( 1991 AstNode* phase_check = new BinaryOpNode(
1993 TokenPos(), Token::kBIT_AND, phase_value, 1992 TokenPos(), Token::kBIT_AND, phase_value,
1994 new LiteralNode(TokenPos(), 1993 new LiteralNode(TokenPos(),
1995 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); 1994 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
1996 AstNode* comparison = 1995 AstNode* comparison =
1997 new ComparisonNode(TokenPos(), Token::kNE_STRICT, 1996 new ComparisonNode(TokenPos(), Token::kNE_STRICT,
1998 phase_check, 1997 phase_check,
1999 new LiteralNode(TokenPos(), 1998 new LiteralNode(TokenPos(),
2000 Smi::ZoneHandle(Smi::New(0)))); 1999 Smi::ZoneHandle(Smi::New(0))));
2001 AstNode* guarded_init_statements = 2000 AstNode* guarded_init_statements =
(...skipping 29 matching lines...) Expand all
2031 // expressions are not evaluated twice. 2030 // expressions are not evaluated twice.
2032 ArgumentListNode* ctor_args = super_call->arguments(); 2031 ArgumentListNode* ctor_args = super_call->arguments();
2033 // The super initializer call has at least 2 arguments: the 2032 // The super initializer call has at least 2 arguments: the
2034 // implicit receiver, and the hidden construction phase. 2033 // implicit receiver, and the hidden construction phase.
2035 ASSERT(ctor_args->length() >= 2); 2034 ASSERT(ctor_args->length() >= 2);
2036 for (int i = 2; i < ctor_args->length(); i++) { 2035 for (int i = 2; i < ctor_args->length(); i++) {
2037 AstNode* arg = ctor_args->NodeAt(i); 2036 AstNode* arg = ctor_args->NodeAt(i);
2038 if (!IsSimpleLocalOrLiteralNode(arg)) { 2037 if (!IsSimpleLocalOrLiteralNode(arg)) {
2039 LocalVariable* temp = 2038 LocalVariable* temp =
2040 CreateTempConstVariable(arg->token_pos(), arg->id(), "sca"); 2039 CreateTempConstVariable(arg->token_pos(), arg->id(), "sca");
2041 AstNode* save_temp = 2040 AstNode* save_temp = new StoreLocalNode(arg->token_pos(), temp, arg);
2042 new StoreLocalNode(arg->token_pos(), *temp, arg);
2043 ctor_args->SetNodeAt(i, save_temp); 2041 ctor_args->SetNodeAt(i, save_temp);
2044 } 2042 }
2045 } 2043 }
2046 } 2044 }
2047 OpenBlock(); // Block to collect constructor body nodes. 2045 OpenBlock(); // Block to collect constructor body nodes.
2048 2046
2049 // Insert the implicit super call to the super constructor body. 2047 // Insert the implicit super call to the super constructor body.
2050 if (super_call != NULL) { 2048 if (super_call != NULL) {
2051 ArgumentListNode* initializer_args = super_call->arguments(); 2049 ArgumentListNode* initializer_args = super_call->arguments();
2052 const Function& super_ctor = super_call->function(); 2050 const Function& super_ctor = super_call->function();
2053 // Patch the initializer call so it only executes the super initializer. 2051 // Patch the initializer call so it only executes the super initializer.
2054 initializer_args->SetNodeAt(1, 2052 initializer_args->SetNodeAt(1,
2055 new LiteralNode(TokenPos(), 2053 new LiteralNode(TokenPos(),
2056 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit)))); 2054 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseInit))));
2057 2055
2058 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos()); 2056 ArgumentListNode* super_call_args = new ArgumentListNode(TokenPos());
2059 // First argument is the receiver. 2057 // First argument is the receiver.
2060 super_call_args->Add(new LoadLocalNode(TokenPos(), *receiver)); 2058 super_call_args->Add(new LoadLocalNode(TokenPos(), receiver));
2061 // Second argument is the construction phase argument. 2059 // Second argument is the construction phase argument.
2062 AstNode* phase_parameter = 2060 AstNode* phase_parameter =
2063 new LiteralNode(TokenPos(), 2061 new LiteralNode(TokenPos(),
2064 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))); 2062 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)));
2065 super_call_args->Add(phase_parameter); 2063 super_call_args->Add(phase_parameter);
2066 super_call_args->set_names(initializer_args->names()); 2064 super_call_args->set_names(initializer_args->names());
2067 for (int i = 2; i < initializer_args->length(); i++) { 2065 for (int i = 2; i < initializer_args->length(); i++) {
2068 AstNode* arg = initializer_args->NodeAt(i); 2066 AstNode* arg = initializer_args->NodeAt(i);
2069 if (arg->IsLiteralNode()) { 2067 if (arg->IsLiteralNode()) {
2070 LiteralNode* lit = arg->AsLiteralNode(); 2068 LiteralNode* lit = arg->AsLiteralNode();
2071 super_call_args->Add(new LiteralNode(TokenPos(), lit->literal())); 2069 super_call_args->Add(new LiteralNode(TokenPos(), lit->literal()));
2072 } else { 2070 } else {
2073 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); 2071 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode());
2074 if (arg->IsLoadLocalNode()) { 2072 if (arg->IsLoadLocalNode()) {
2075 const LocalVariable& temp = arg->AsLoadLocalNode()->local(); 2073 const LocalVariable* temp = arg->AsLoadLocalNode()->local();
2076 super_call_args->Add(new LoadLocalNode(TokenPos(), temp)); 2074 super_call_args->Add(new LoadLocalNode(TokenPos(), temp));
2077 } else if (arg->IsStoreLocalNode()) { 2075 } else if (arg->IsStoreLocalNode()) {
2078 const LocalVariable& temp = arg->AsStoreLocalNode()->local(); 2076 const LocalVariable* temp = arg->AsStoreLocalNode()->local();
2079 super_call_args->Add(new LoadLocalNode(TokenPos(), temp)); 2077 super_call_args->Add(new LoadLocalNode(TokenPos(), temp));
2080 } 2078 }
2081 } 2079 }
2082 } 2080 }
2083 ASSERT(super_ctor.AreValidArguments(super_call_args->length(), 2081 ASSERT(super_ctor.AreValidArguments(super_call_args->length(),
2084 super_call_args->names(), 2082 super_call_args->names(),
2085 NULL)); 2083 NULL));
2086 current_block_->statements->Add( 2084 current_block_->statements->Add(
2087 new StaticCallNode(TokenPos(), super_ctor, super_call_args)); 2085 new StaticCallNode(TokenPos(), super_ctor, super_call_args));
2088 } 2086 }
(...skipping 10 matching lines...) Expand all
2099 // Some constructors have no function body. 2097 // Some constructors have no function body.
2100 ConsumeToken(); 2098 ConsumeToken();
2101 } else { 2099 } else {
2102 UnexpectedToken(); 2100 UnexpectedToken();
2103 } 2101 }
2104 2102
2105 SequenceNode* ctor_block = CloseBlock(); 2103 SequenceNode* ctor_block = CloseBlock();
2106 if (ctor_block->length() > 0) { 2104 if (ctor_block->length() > 0) {
2107 // Generate guard around the constructor body code. 2105 // Generate guard around the constructor body code.
2108 LocalVariable* phase_param = LookupPhaseParameter(); 2106 LocalVariable* phase_param = LookupPhaseParameter();
2109 AstNode* phase_value = new LoadLocalNode(TokenPos(), *phase_param); 2107 AstNode* phase_value = new LoadLocalNode(TokenPos(), phase_param);
2110 AstNode* phase_check = 2108 AstNode* phase_check =
2111 new BinaryOpNode(TokenPos(), Token::kBIT_AND, 2109 new BinaryOpNode(TokenPos(), Token::kBIT_AND,
2112 phase_value, 2110 phase_value,
2113 new LiteralNode(TokenPos(), 2111 new LiteralNode(TokenPos(),
2114 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody)))); 2112 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseBody))));
2115 AstNode* comparison = 2113 AstNode* comparison =
2116 new ComparisonNode(TokenPos(), Token::kNE_STRICT, 2114 new ComparisonNode(TokenPos(), Token::kNE_STRICT,
2117 phase_check, 2115 phase_check,
2118 new LiteralNode(TokenPos(), 2116 new LiteralNode(TokenPos(),
2119 Smi::ZoneHandle(Smi::New(0)))); 2117 Smi::ZoneHandle(Smi::New(0))));
(...skipping 2099 matching lines...) Expand 10 before | Expand all | Expand 10 after
4219 4217
4220 4218
4221 AstNode* Parser::LoadReceiver(intptr_t token_pos) { 4219 AstNode* Parser::LoadReceiver(intptr_t token_pos) {
4222 // A nested function may access 'this', referring to the receiver of the 4220 // A nested function may access 'this', referring to the receiver of the
4223 // outermost enclosing function. 4221 // outermost enclosing function.
4224 const bool kTestOnly = false; 4222 const bool kTestOnly = false;
4225 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); 4223 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly);
4226 if (receiver == NULL) { 4224 if (receiver == NULL) {
4227 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); 4225 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'");
4228 } 4226 }
4229 return new LoadLocalNode(TokenPos(), *receiver); 4227 return new LoadLocalNode(TokenPos(), receiver);
4230 } 4228 }
4231 4229
4232 4230
4233 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) { 4231 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) {
4234 // A nested function may access ':type_arguments' to use as instantiator, 4232 // A nested function may access ':type_arguments' to use as instantiator,
4235 // referring to the implicit first parameter of the outermost enclosing 4233 // referring to the implicit first parameter of the outermost enclosing
4236 // factory function. 4234 // factory function.
4237 const bool kTestOnly = false; 4235 const bool kTestOnly = false;
4238 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope, 4236 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope,
4239 kTestOnly); 4237 kTestOnly);
4240 ASSERT(param != NULL); 4238 ASSERT(param != NULL);
4241 return new LoadLocalNode(TokenPos(), *param); 4239 return new LoadLocalNode(TokenPos(), param);
4242 } 4240 }
4243 4241
4244 4242
4245 AstNode* Parser::CallGetter(intptr_t token_pos, 4243 AstNode* Parser::CallGetter(intptr_t token_pos,
4246 AstNode* object, 4244 AstNode* object,
4247 const String& name) { 4245 const String& name) {
4248 return new InstanceGetterNode(TokenPos(), object, name); 4246 return new InstanceGetterNode(TokenPos(), object, name);
4249 } 4247 }
4250 4248
4251 4249
4252 // Returns ast nodes of the variable initialization. 4250 // Returns ast nodes of the variable initialization.
4253 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, 4251 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type,
4254 bool is_final, 4252 bool is_final,
4255 bool is_const) { 4253 bool is_const) {
4256 TRACE_PARSER("ParseVariableDeclaration"); 4254 TRACE_PARSER("ParseVariableDeclaration");
4257 ASSERT(IsIdentifier()); 4255 ASSERT(IsIdentifier());
4258 const intptr_t ident_pos = TokenPos(); 4256 const intptr_t ident_pos = TokenPos();
4259 LocalVariable* variable = 4257 LocalVariable* variable =
4260 new LocalVariable(ident_pos, *CurrentLiteral(), type); 4258 new LocalVariable(ident_pos, *CurrentLiteral(), type);
4261 ASSERT(current_block_ != NULL); 4259 ASSERT(current_block_ != NULL);
4262 ASSERT(current_block_->scope != NULL); 4260 ASSERT(current_block_->scope != NULL);
4263 ConsumeToken(); // Variable identifier. 4261 ConsumeToken(); // Variable identifier.
4264 AstNode* initialization = NULL; 4262 AstNode* initialization = NULL;
4265 if (CurrentToken() == Token::kASSIGN) { 4263 if (CurrentToken() == Token::kASSIGN) {
4266 // Variable initialization. 4264 // Variable initialization.
4267 const intptr_t assign_pos = TokenPos(); 4265 const intptr_t assign_pos = TokenPos();
4268 ConsumeToken(); 4266 ConsumeToken();
4269 AstNode* expr = ParseExpr(is_const, kConsumeCascades); 4267 AstNode* expr = ParseExpr(is_const, kConsumeCascades);
4270 initialization = new StoreLocalNode(assign_pos, *variable, expr); 4268 initialization = new StoreLocalNode(assign_pos, variable, expr);
4271 } else if (is_final || is_const) { 4269 } else if (is_final || is_const) {
4272 ErrorMsg(ident_pos, 4270 ErrorMsg(ident_pos,
4273 "missing initialization of 'final' or 'const' variable"); 4271 "missing initialization of 'final' or 'const' variable");
4274 } else { 4272 } else {
4275 // Initialize variable with null. 4273 // Initialize variable with null.
4276 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); 4274 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle());
4277 initialization = new StoreLocalNode(ident_pos, *variable, null_expr); 4275 initialization = new StoreLocalNode(ident_pos, variable, null_expr);
4278 } 4276 }
4279 // Add variable to scope after parsing the initalizer expression. 4277 // Add variable to scope after parsing the initalizer expression.
4280 // The expression must not be able to refer to the variable. 4278 // The expression must not be able to refer to the variable.
4281 if (!current_block_->scope->AddVariable(variable)) { 4279 if (!current_block_->scope->AddVariable(variable)) {
4282 ErrorMsg(ident_pos, "identifier '%s' already defined", 4280 ErrorMsg(ident_pos, "identifier '%s' already defined",
4283 variable->name().ToCString()); 4281 variable->name().ToCString());
4284 } 4282 }
4285 if (is_final || is_const) { 4283 if (is_final || is_const) {
4286 variable->set_is_final(); 4284 variable->set_is_final();
4287 } 4285 }
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4543 // This pruning is done by omitting to hook the local scope in its parent 4541 // This pruning is done by omitting to hook the local scope in its parent
4544 // scope in the constructor of LocalScope. 4542 // scope in the constructor of LocalScope.
4545 AstNode* closure = 4543 AstNode* closure =
4546 new ClosureNode(ident_pos, function, NULL, statements->scope()); 4544 new ClosureNode(ident_pos, function, NULL, statements->scope());
4547 4545
4548 if (function_variable == NULL) { 4546 if (function_variable == NULL) {
4549 ASSERT(is_literal); 4547 ASSERT(is_literal);
4550 return closure; 4548 return closure;
4551 } else { 4549 } else {
4552 AstNode* initialization = 4550 AstNode* initialization =
4553 new StoreLocalNode(ident_pos, *function_variable, closure); 4551 new StoreLocalNode(ident_pos, function_variable, closure);
4554 return initialization; 4552 return initialization;
4555 } 4553 }
4556 } 4554 }
4557 4555
4558 4556
4559 // Returns true if the current and next tokens can be parsed as type 4557 // Returns true if the current and next tokens can be parsed as type
4560 // parameters. Current token position is not saved and restored. 4558 // parameters. Current token position is not saved and restored.
4561 bool Parser::TryParseTypeParameter() { 4559 bool Parser::TryParseTypeParameter() {
4562 if (CurrentToken() == Token::kLT) { 4560 if (CurrentToken() == Token::kLT) {
4563 // We are possibly looking at type parameters. Find closing ">". 4561 // We are possibly looking at type parameters. Find closing ">".
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
4926 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL); 4924 SequenceNode* case_expressions = new SequenceNode(case_pos, NULL);
4927 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { 4925 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) {
4928 if (CurrentToken() == Token::kCASE) { 4926 if (CurrentToken() == Token::kCASE) {
4929 if (default_seen) { 4927 if (default_seen) {
4930 ErrorMsg("default clause must be last case"); 4928 ErrorMsg("default clause must be last case");
4931 } 4929 }
4932 ConsumeToken(); // Keyword case. 4930 ConsumeToken(); // Keyword case.
4933 const intptr_t expr_pos = TokenPos(); 4931 const intptr_t expr_pos = TokenPos();
4934 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 4932 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
4935 AstNode* switch_expr_load = new LoadLocalNode(case_pos, 4933 AstNode* switch_expr_load = new LoadLocalNode(case_pos,
4936 *switch_expr_value); 4934 switch_expr_value);
4937 AstNode* case_comparison = new ComparisonNode(expr_pos, 4935 AstNode* case_comparison = new ComparisonNode(expr_pos,
4938 Token::kEQ, 4936 Token::kEQ,
4939 expr, 4937 expr,
4940 switch_expr_load); 4938 switch_expr_load);
4941 case_expressions->Add(case_comparison); 4939 case_expressions->Add(case_comparison);
4942 } else { 4940 } else {
4943 if (default_seen) { 4941 if (default_seen) {
4944 ErrorMsg("only one default clause is allowed"); 4942 ErrorMsg("only one default clause is allowed");
4945 } 4943 }
4946 ConsumeToken(); // Keyword default. 4944 ConsumeToken(); // Keyword default.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
5017 OpenBlock(); 5015 OpenBlock();
5018 current_block_->scope->AddLabel(label); 5016 current_block_->scope->AddLabel(label);
5019 5017
5020 // Store switch expression in temporary local variable. 5018 // Store switch expression in temporary local variable.
5021 LocalVariable* temp_variable = 5019 LocalVariable* temp_variable =
5022 new LocalVariable(expr_pos, 5020 new LocalVariable(expr_pos,
5023 String::ZoneHandle(Symbols::New(":switch_expr")), 5021 String::ZoneHandle(Symbols::New(":switch_expr")),
5024 Type::ZoneHandle(Type::DynamicType())); 5022 Type::ZoneHandle(Type::DynamicType()));
5025 current_block_->scope->AddVariable(temp_variable); 5023 current_block_->scope->AddVariable(temp_variable);
5026 AstNode* save_switch_expr = 5024 AstNode* save_switch_expr =
5027 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); 5025 new StoreLocalNode(expr_pos, temp_variable, switch_expr);
5028 current_block_->statements->Add(save_switch_expr); 5026 current_block_->statements->Add(save_switch_expr);
5029 5027
5030 // Parse case clauses 5028 // Parse case clauses
5031 bool default_seen = false; 5029 bool default_seen = false;
5032 while (true) { 5030 while (true) {
5033 // Check for statement label 5031 // Check for statement label
5034 SourceLabel* case_label = NULL; 5032 SourceLabel* case_label = NULL;
5035 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { 5033 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) {
5036 // Case statements start with a label. 5034 // Case statements start with a label.
5037 String* label_name = CurrentLiteral(); 5035 String* label_name = CurrentLiteral();
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
5162 new LocalVariable(collection_pos, iterator_name, iterator_type); 5160 new LocalVariable(collection_pos, iterator_name, iterator_type);
5163 current_block_->scope->AddVariable(iterator_var); 5161 current_block_->scope->AddVariable(iterator_var);
5164 5162
5165 // Generate initialization of iterator variable. 5163 // Generate initialization of iterator variable.
5166 const String& iterator_method_name = 5164 const String& iterator_method_name =
5167 String::ZoneHandle(Symbols::GetIterator()); 5165 String::ZoneHandle(Symbols::GetIterator());
5168 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); 5166 ArgumentListNode* no_args = new ArgumentListNode(collection_pos);
5169 AstNode* get_iterator = new InstanceCallNode( 5167 AstNode* get_iterator = new InstanceCallNode(
5170 collection_pos, collection_expr, iterator_method_name, no_args); 5168 collection_pos, collection_expr, iterator_method_name, no_args);
5171 AstNode* iterator_init = 5169 AstNode* iterator_init =
5172 new StoreLocalNode(collection_pos, *iterator_var, get_iterator); 5170 new StoreLocalNode(collection_pos, iterator_var, get_iterator);
5173 current_block_->statements->Add(iterator_init); 5171 current_block_->statements->Add(iterator_init);
5174 5172
5175 // Generate while loop condition. 5173 // Generate while loop condition.
5176 AstNode* iterator_has_next = new InstanceCallNode( 5174 AstNode* iterator_has_next = new InstanceCallNode(
5177 collection_pos, 5175 collection_pos,
5178 new LoadLocalNode(collection_pos, *iterator_var), 5176 new LoadLocalNode(collection_pos, iterator_var),
5179 String::ZoneHandle(Symbols::HasNext()), 5177 String::ZoneHandle(Symbols::HasNext()),
5180 no_args); 5178 no_args);
5181 5179
5182 // Parse the for loop body. Ideally, we would use ParseNestedStatement() 5180 // Parse the for loop body. Ideally, we would use ParseNestedStatement()
5183 // here, but that does not work well because we have to insert an implicit 5181 // here, but that does not work well because we have to insert an implicit
5184 // variable assignment and potentially a variable declaration in the 5182 // variable assignment and potentially a variable declaration in the
5185 // loop body. 5183 // loop body.
5186 OpenLoopBlock(); 5184 OpenLoopBlock();
5187 current_block_->scope->AddLabel(label); 5185 current_block_->scope->AddLabel(label);
5188 5186
5189 AstNode* iterator_next = new InstanceCallNode( 5187 AstNode* iterator_next = new InstanceCallNode(
5190 collection_pos, 5188 collection_pos,
5191 new LoadLocalNode(collection_pos, *iterator_var), 5189 new LoadLocalNode(collection_pos, iterator_var),
5192 String::ZoneHandle(Symbols::Next()), 5190 String::ZoneHandle(Symbols::Next()),
5193 no_args); 5191 no_args);
5194 5192
5195 // Generate assignment of next iterator value to loop variable. 5193 // Generate assignment of next iterator value to loop variable.
5196 AstNode* loop_var_assignment = NULL; 5194 AstNode* loop_var_assignment = NULL;
5197 if (loop_var != NULL) { 5195 if (loop_var != NULL) {
5198 // The for loop declares a new variable. Add it to the loop body scope. 5196 // The for loop declares a new variable. Add it to the loop body scope.
5199 current_block_->scope->AddVariable(loop_var); 5197 current_block_->scope->AddVariable(loop_var);
5200 loop_var_assignment = 5198 loop_var_assignment =
5201 new StoreLocalNode(loop_var_pos, *loop_var, iterator_next); 5199 new StoreLocalNode(loop_var_pos, loop_var, iterator_next);
5202 } else { 5200 } else {
5203 AstNode* loop_var_primary = 5201 AstNode* loop_var_primary =
5204 ResolveIdent(loop_var_pos, *loop_var_name, false); 5202 ResolveIdent(loop_var_pos, *loop_var_name, false);
5205 ASSERT(!loop_var_primary->IsPrimaryNode()); 5203 ASSERT(!loop_var_primary->IsPrimaryNode());
5206 loop_var_assignment = 5204 loop_var_assignment =
5207 CreateAssignmentNode(loop_var_primary, iterator_next); 5205 CreateAssignmentNode(loop_var_primary, iterator_next);
5208 if (loop_var_assignment == NULL) { 5206 if (loop_var_assignment == NULL) {
5209 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable", 5207 ErrorMsg(loop_var_pos, "variable or field '%s' is not assignable",
5210 loop_var_name->ToCString()); 5208 loop_var_name->ToCString());
5211 } 5209 }
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
5602 OpenBlock(); 5600 OpenBlock();
5603 5601
5604 // Generate code to load the exception object (:exception_var) into 5602 // Generate code to load the exception object (:exception_var) into
5605 // the exception variable specified in this block. 5603 // the exception variable specified in this block.
5606 ASSERT(exception_param.var != NULL); 5604 ASSERT(exception_param.var != NULL);
5607 LocalVariable* var = LookupLocalScope(*exception_param.var); 5605 LocalVariable* var = LookupLocalScope(*exception_param.var);
5608 ASSERT(var != NULL); 5606 ASSERT(var != NULL);
5609 ASSERT(catch_excp_var != NULL); 5607 ASSERT(catch_excp_var != NULL);
5610 current_block_->statements->Add( 5608 current_block_->statements->Add(
5611 new StoreLocalNode(catch_pos, 5609 new StoreLocalNode(catch_pos,
5612 *var, 5610 var,
5613 new LoadLocalNode(catch_pos, *catch_excp_var))); 5611 new LoadLocalNode(catch_pos, catch_excp_var)));
5614 if (stack_trace_param.var != NULL) { 5612 if (stack_trace_param.var != NULL) {
5615 // A stack trace variable is specified in this block, so generate code 5613 // A stack trace variable is specified in this block, so generate code
5616 // to load the stack trace object (:stacktrace_var) into the stack trace 5614 // to load the stack trace object (:stacktrace_var) into the stack trace
5617 // variable specified in this block. 5615 // variable specified in this block.
5618 LocalVariable* trace = LookupLocalScope(*stack_trace_param.var); 5616 LocalVariable* trace = LookupLocalScope(*stack_trace_param.var);
5619 ASSERT(catch_trace_var != NULL); 5617 ASSERT(catch_trace_var != NULL);
5620 current_block_->statements->Add( 5618 current_block_->statements->Add(
5621 new StoreLocalNode(catch_pos, 5619 new StoreLocalNode(catch_pos,
5622 *trace, 5620 trace,
5623 new LoadLocalNode(catch_pos, *catch_trace_var))); 5621 new LoadLocalNode(catch_pos, catch_trace_var)));
5624 } 5622 }
5625 5623
5626 ParseStatementSequence(); // Parse the catch handler code. 5624 ParseStatementSequence(); // Parse the catch handler code.
5627 current_block_->statements->Add( 5625 current_block_->statements->Add(
5628 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); 5626 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label));
5629 SequenceNode* catch_handler = CloseBlock(); 5627 SequenceNode* catch_handler = CloseBlock();
5630 ExpectToken(Token::kRBRACE); 5628 ExpectToken(Token::kRBRACE);
5631 5629
5632 if (!exception_param.type->IsDynamicType()) { // Has a type specification. 5630 if (!exception_param.type->IsDynamicType()) { // Has a type specification.
5633 // Now form an 'if type check' as an exception type exists in 5631 // Now form an 'if type check' as an exception type exists in
5634 // the catch specifier. 5632 // the catch specifier.
5635 if (!exception_param.type->IsInstantiated() && 5633 if (!exception_param.type->IsInstantiated() &&
5636 (current_block_->scope->function_level() > 0)) { 5634 (current_block_->scope->function_level() > 0)) {
5637 // Make sure that the instantiator is captured. 5635 // Make sure that the instantiator is captured.
5638 CaptureInstantiator(); 5636 CaptureInstantiator();
5639 } 5637 }
5640 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); 5638 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type);
5641 AstNode* exception_var = new LoadLocalNode(catch_pos, *catch_excp_var); 5639 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var);
5642 if (!exception_type->type().IsInstantiated()) { 5640 if (!exception_type->type().IsInstantiated()) {
5643 EnsureExpressionTemp(); 5641 EnsureExpressionTemp();
5644 } 5642 }
5645 AstNode* type_cond_expr = new ComparisonNode( 5643 AstNode* type_cond_expr = new ComparisonNode(
5646 catch_pos, Token::kIS, exception_var, exception_type); 5644 catch_pos, Token::kIS, exception_var, exception_type);
5647 current_block_->statements->Add( 5645 current_block_->statements->Add(
5648 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); 5646 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL));
5649 } else { 5647 } else {
5650 // No exception type exists in the catch specifier so execute the 5648 // No exception type exists in the catch specifier so execute the
5651 // catch handler code unconditionally. 5649 // catch handler code unconditionally.
(...skipping 15 matching lines...) Expand all
5667 ConsumeToken(); // Consume the 'finally'. 5665 ConsumeToken(); // Consume the 'finally'.
5668 const intptr_t finally_pos = TokenPos(); 5666 const intptr_t finally_pos = TokenPos();
5669 // Add the finally block to the exit points recorded so far. 5667 // Add the finally block to the exit points recorded so far.
5670 intptr_t node_index = 0; 5668 intptr_t node_index = 0;
5671 AstNode* node_to_inline = 5669 AstNode* node_to_inline =
5672 inner_try_block->GetNodeToInlineFinally(node_index); 5670 inner_try_block->GetNodeToInlineFinally(node_index);
5673 while (node_to_inline != NULL) { 5671 while (node_to_inline != NULL) {
5674 finally_block = ParseFinallyBlock(); 5672 finally_block = ParseFinallyBlock();
5675 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos, 5673 InlinedFinallyNode* node = new InlinedFinallyNode(finally_pos,
5676 finally_block, 5674 finally_block,
5677 *context_var); 5675 context_var);
5678 AddFinallyBlockToNode(node_to_inline, node); 5676 AddFinallyBlockToNode(node_to_inline, node);
5679 node_index += 1; 5677 node_index += 1;
5680 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); 5678 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index);
5681 tokens_iterator_.SetCurrentPosition(finally_pos); 5679 tokens_iterator_.SetCurrentPosition(finally_pos);
5682 } 5680 }
5683 if (!generic_catch_seen) { 5681 if (!generic_catch_seen) {
5684 // No generic catch handler exists so execute this finally block 5682 // No generic catch handler exists so execute this finally block
5685 // before rethrowing the exception. 5683 // before rethrowing the exception.
5686 finally_block = ParseFinallyBlock(); 5684 finally_block = ParseFinallyBlock();
5687 catch_handler_list->Add(finally_block); 5685 catch_handler_list->Add(finally_block);
5688 tokens_iterator_.SetCurrentPosition(finally_pos); 5686 tokens_iterator_.SetCurrentPosition(finally_pos);
5689 } 5687 }
5690 finally_block = ParseFinallyBlock(); 5688 finally_block = ParseFinallyBlock();
5691 } else { 5689 } else {
5692 if (!catch_seen) { 5690 if (!catch_seen) {
5693 ErrorMsg("'catch' or 'finally' expected"); 5691 ErrorMsg("'catch' or 'finally' expected");
5694 } 5692 }
5695 } 5693 }
5696 5694
5697 if (!generic_catch_seen) { 5695 if (!generic_catch_seen) {
5698 // No generic catch handler exists so rethrow the exception so that 5696 // No generic catch handler exists so rethrow the exception so that
5699 // the next catch handler can deal with it. 5697 // the next catch handler can deal with it.
5700 catch_handler_list->Add( 5698 catch_handler_list->Add(
5701 new ThrowNode(handler_pos, 5699 new ThrowNode(handler_pos,
5702 new LoadLocalNode(handler_pos, *catch_excp_var), 5700 new LoadLocalNode(handler_pos, catch_excp_var),
5703 new LoadLocalNode(handler_pos, *catch_trace_var))); 5701 new LoadLocalNode(handler_pos, catch_trace_var)));
5704 } 5702 }
5705 CatchClauseNode* catch_block = new CatchClauseNode(handler_pos, 5703 CatchClauseNode* catch_block = new CatchClauseNode(handler_pos,
5706 catch_handler_list, 5704 catch_handler_list,
5707 *context_var, 5705 context_var,
5708 *catch_excp_var, 5706 catch_excp_var,
5709 *catch_trace_var); 5707 catch_trace_var);
5710 5708
5711 // Now create the try/catch ast node and return it. If there is a label 5709 // Now create the try/catch ast node and return it. If there is a label
5712 // on the try/catch, close the block that's embedding the try statement 5710 // on the try/catch, close the block that's embedding the try statement
5713 // and attach the label to it. 5711 // and attach the label to it.
5714 AstNode* try_catch_node = 5712 AstNode* try_catch_node =
5715 new TryCatchNode(try_pos, try_block, end_catch_label, 5713 new TryCatchNode(try_pos, try_block, end_catch_label,
5716 *context_var, catch_block, finally_block); 5714 context_var, catch_block, finally_block);
5717 5715
5718 if (try_label != NULL) { 5716 if (try_label != NULL) {
5719 current_block_->statements->Add(try_catch_node); 5717 current_block_->statements->Add(try_catch_node);
5720 SequenceNode* sequence = CloseBlock(); 5718 SequenceNode* sequence = CloseBlock();
5721 sequence->set_label(try_label); 5719 sequence->set_label(try_label);
5722 try_catch_node = sequence; 5720 try_catch_node = sequence;
5723 } 5721 }
5724 return try_catch_node; 5722 return try_catch_node;
5725 } 5723 }
5726 5724
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
5893 ASSERT(label->owner() != NULL); 5891 ASSERT(label->owner() != NULL);
5894 LocalScope* scope = label->owner()->parent(); 5892 LocalScope* scope = label->owner()->parent();
5895 ASSERT(scope != NULL); 5893 ASSERT(scope != NULL);
5896 LocalVariable* excp_var = scope->LocalLookupVariable( 5894 LocalVariable* excp_var = scope->LocalLookupVariable(
5897 String::ZoneHandle(Symbols::ExceptionVar())); 5895 String::ZoneHandle(Symbols::ExceptionVar()));
5898 ASSERT(excp_var != NULL); 5896 ASSERT(excp_var != NULL);
5899 LocalVariable* trace_var = scope->LocalLookupVariable( 5897 LocalVariable* trace_var = scope->LocalLookupVariable(
5900 String::ZoneHandle(Symbols::StacktraceVar())); 5898 String::ZoneHandle(Symbols::StacktraceVar()));
5901 ASSERT(trace_var != NULL); 5899 ASSERT(trace_var != NULL);
5902 statement = new ThrowNode(statement_pos, 5900 statement = new ThrowNode(statement_pos,
5903 new LoadLocalNode(statement_pos, *excp_var), 5901 new LoadLocalNode(statement_pos, excp_var),
5904 new LoadLocalNode(statement_pos, *trace_var)); 5902 new LoadLocalNode(statement_pos, trace_var));
5905 } 5903 }
5906 } else { 5904 } else {
5907 statement = ParseExpr(kAllowConst, kConsumeCascades); 5905 statement = ParseExpr(kAllowConst, kConsumeCascades);
5908 ExpectSemicolon(); 5906 ExpectSemicolon();
5909 } 5907 }
5910 return statement; 5908 return statement;
5911 } 5909 }
5912 5910
5913 5911
5914 RawError* Parser::FormatErrorWithAppend(const Error& prev_error, 5912 RawError* Parser::FormatErrorWithAppend(const Error& prev_error,
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
6286 ConsumeToken(); 6284 ConsumeToken();
6287 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 6285 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
6288 list->Add(expr); 6286 list->Add(expr);
6289 } 6287 }
6290 expressions = list; 6288 expressions = list;
6291 } 6289 }
6292 return expressions; 6290 return expressions;
6293 } 6291 }
6294 6292
6295 6293
6296 const LocalVariable& Parser::GetIncrementTempLocal() { 6294 const LocalVariable* Parser::GetIncrementTempLocal() {
6297 if (expression_temp_ == NULL) { 6295 if (expression_temp_ == NULL) {
6298 expression_temp_ = ParsedFunction::CreateExpressionTempVar( 6296 expression_temp_ = ParsedFunction::CreateExpressionTempVar(
6299 current_function().token_pos()); 6297 current_function().token_pos());
6300 } 6298 }
6301 return *expression_temp_; 6299 return expression_temp_;
6302 } 6300 }
6303 6301
6304 6302
6305 void Parser::EnsureExpressionTemp() { 6303 void Parser::EnsureExpressionTemp() {
6306 // Temporary used later by the flow_graph_builder. 6304 // Temporary used later by the flow_graph_builder.
6307 GetIncrementTempLocal(); 6305 GetIncrementTempLocal();
6308 } 6306 }
6309 6307
6310 6308
6311 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, 6309 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
6412 if (node->IsLoadIndexedNode()) { 6410 if (node->IsLoadIndexedNode()) {
6413 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); 6411 LoadIndexedNode* left_node = node->AsLoadIndexedNode();
6414 LoadIndexedNode* right_node = left_node; 6412 LoadIndexedNode* right_node = left_node;
6415 intptr_t node_id = node->id(); 6413 intptr_t node_id = node->id();
6416 intptr_t token_pos = node->token_pos(); 6414 intptr_t token_pos = node->token_pos();
6417 node = NULL; // Do not use it. 6415 node = NULL; // Do not use it.
6418 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { 6416 if (!IsSimpleLocalOrLiteralNode(left_node->array())) {
6419 LocalVariable* temp = 6417 LocalVariable* temp =
6420 CreateTempConstVariable(token_pos, node_id, "lia"); 6418 CreateTempConstVariable(token_pos, node_id, "lia");
6421 StoreLocalNode* save = 6419 StoreLocalNode* save =
6422 new StoreLocalNode(token_pos, *temp, left_node->array()); 6420 new StoreLocalNode(token_pos, temp, left_node->array());
6423 left_node = 6421 left_node =
6424 new LoadIndexedNode(token_pos, save, left_node->index_expr()); 6422 new LoadIndexedNode(token_pos, save, left_node->index_expr());
6425 right_node = new LoadIndexedNode(token_pos, 6423 right_node = new LoadIndexedNode(token_pos,
6426 new LoadLocalNode(token_pos, *temp), 6424 new LoadLocalNode(token_pos, temp),
6427 right_node->index_expr()); 6425 right_node->index_expr());
6428 } 6426 }
6429 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { 6427 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) {
6430 LocalVariable* temp = 6428 LocalVariable* temp =
6431 CreateTempConstVariable(token_pos, node_id, "lix"); 6429 CreateTempConstVariable(token_pos, node_id, "lix");
6432 StoreLocalNode* save = 6430 StoreLocalNode* save =
6433 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); 6431 new StoreLocalNode(token_pos, temp, left_node->index_expr());
6434 left_node = new LoadIndexedNode(token_pos, 6432 left_node = new LoadIndexedNode(token_pos,
6435 left_node->array(), 6433 left_node->array(),
6436 save); 6434 save);
6437 right_node = new LoadIndexedNode(token_pos, 6435 right_node = new LoadIndexedNode(token_pos,
6438 right_node->array(), 6436 right_node->array(),
6439 new LoadLocalNode(token_pos, *temp)); 6437 new LoadLocalNode(token_pos, temp));
6440 } 6438 }
6441 *expr = right_node; 6439 *expr = right_node;
6442 return left_node; 6440 return left_node;
6443 } 6441 }
6444 if (node->IsInstanceGetterNode()) { 6442 if (node->IsInstanceGetterNode()) {
6445 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); 6443 InstanceGetterNode* left_node = node->AsInstanceGetterNode();
6446 InstanceGetterNode* right_node = left_node; 6444 InstanceGetterNode* right_node = left_node;
6447 intptr_t node_id = node->id(); 6445 intptr_t node_id = node->id();
6448 intptr_t token_pos = node->token_pos(); 6446 intptr_t token_pos = node->token_pos();
6449 node = NULL; // Do not use it. 6447 node = NULL; // Do not use it.
6450 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { 6448 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) {
6451 LocalVariable* temp = 6449 LocalVariable* temp =
6452 CreateTempConstVariable(token_pos, node_id, "igr"); 6450 CreateTempConstVariable(token_pos, node_id, "igr");
6453 StoreLocalNode* save = 6451 StoreLocalNode* save =
6454 new StoreLocalNode(token_pos, *temp, left_node->receiver()); 6452 new StoreLocalNode(token_pos, temp, left_node->receiver());
6455 left_node = new InstanceGetterNode(token_pos, 6453 left_node = new InstanceGetterNode(token_pos,
6456 save, 6454 save,
6457 left_node->field_name()); 6455 left_node->field_name());
6458 right_node = new InstanceGetterNode(token_pos, 6456 right_node = new InstanceGetterNode(token_pos,
6459 new LoadLocalNode(token_pos, *temp), 6457 new LoadLocalNode(token_pos, temp),
6460 right_node->field_name()); 6458 right_node->field_name());
6461 } 6459 }
6462 *expr = right_node; 6460 *expr = right_node;
6463 return left_node; 6461 return left_node;
6464 } 6462 }
6465 return *expr; 6463 return *expr;
6466 } 6464 }
6467 6465
6468 6466
6469 // Ensure that the expression temp is allocated for nodes that may need it. 6467 // Ensure that the expression temp is allocated for nodes that may need it.
6470 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) { 6468 AstNode* Parser::CreateAssignmentNode(AstNode* original, AstNode* rhs) {
6471 AstNode* result = original->MakeAssignmentNode(rhs); 6469 AstNode* result = original->MakeAssignmentNode(rhs);
6472 if ((result != NULL) && 6470 if ((result != NULL) &&
6473 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) { 6471 (result->IsStoreIndexedNode() || result->IsInstanceSetterNode())) {
6474 EnsureExpressionTemp(); 6472 EnsureExpressionTemp();
6475 } 6473 }
6476 return result; 6474 return result;
6477 } 6475 }
6478 6476
6479 6477
6480 AstNode* Parser::ParseCascades(AstNode* expr) { 6478 AstNode* Parser::ParseCascades(AstNode* expr) {
6481 intptr_t cascade_pos = TokenPos(); 6479 intptr_t cascade_pos = TokenPos();
6482 LocalVariable* cascade_receiver_var = 6480 LocalVariable* cascade_receiver_var =
6483 CreateTempConstVariable(cascade_pos, expr->id(), "casc"); 6481 CreateTempConstVariable(cascade_pos, expr->id(), "casc");
6484 StoreLocalNode* save_cascade = 6482 StoreLocalNode* save_cascade =
6485 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); 6483 new StoreLocalNode(cascade_pos, cascade_receiver_var, expr);
6486 current_block_->statements->Add(save_cascade); 6484 current_block_->statements->Add(save_cascade);
6487 while (CurrentToken() == Token::kCASCADE) { 6485 while (CurrentToken() == Token::kCASCADE) {
6488 cascade_pos = TokenPos(); 6486 cascade_pos = TokenPos();
6489 LoadLocalNode* load_cascade_receiver = 6487 LoadLocalNode* load_cascade_receiver =
6490 new LoadLocalNode(cascade_pos, *cascade_receiver_var); 6488 new LoadLocalNode(cascade_pos, cascade_receiver_var);
6491 if (Token::IsIdentifier(LookaheadToken(1))) { 6489 if (Token::IsIdentifier(LookaheadToken(1))) {
6492 // Replace .. with . for ParseSelectors(). 6490 // Replace .. with . for ParseSelectors().
6493 token_kind_ = Token::kPERIOD; 6491 token_kind_ = Token::kPERIOD;
6494 } else if (LookaheadToken(1) == Token::kLBRACK) { 6492 } else if (LookaheadToken(1) == Token::kLBRACK) {
6495 ConsumeToken(); 6493 ConsumeToken();
6496 } else { 6494 } else {
6497 ErrorMsg("identifier or [ expected after .."); 6495 ErrorMsg("identifier or [ expected after ..");
6498 } 6496 }
6499 expr = ParseSelectors(load_cascade_receiver, true); 6497 expr = ParseSelectors(load_cascade_receiver, true);
6500 6498
(...skipping 16 matching lines...) Expand all
6517 if (assign_expr == NULL) { 6515 if (assign_expr == NULL) {
6518 ErrorMsg(assignment_pos, 6516 ErrorMsg(assignment_pos,
6519 "left hand side of '%s' is not assignable", 6517 "left hand side of '%s' is not assignable",
6520 Token::Str(assignment_op)); 6518 Token::Str(assignment_op));
6521 } 6519 }
6522 expr = assign_expr; 6520 expr = assign_expr;
6523 } 6521 }
6524 current_block_->statements->Add(expr); 6522 current_block_->statements->Add(expr);
6525 } 6523 }
6526 // Result of the cascade is the receiver. 6524 // Result of the cascade is the receiver.
6527 return new LoadLocalNode(cascade_pos, *cascade_receiver_var); 6525 return new LoadLocalNode(cascade_pos, cascade_receiver_var);
6528 } 6526 }
6529 6527
6530 6528
6531 AstNode* Parser::ParseExpr(bool require_compiletime_const, 6529 AstNode* Parser::ParseExpr(bool require_compiletime_const,
6532 bool consume_cascades) { 6530 bool consume_cascades) {
6533 TRACE_PARSER("ParseExpr"); 6531 TRACE_PARSER("ParseExpr");
6534 const intptr_t expr_pos = TokenPos(); 6532 const intptr_t expr_pos = TokenPos();
6535 AstNode* expr = ParseConditionalExpr(); 6533 AstNode* expr = ParseConditionalExpr();
6536 if (!Token::IsAssignmentOperator(CurrentToken())) { 6534 if (!Token::IsAssignmentOperator(CurrentToken())) {
6537 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { 6535 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) {
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
7075 postfix_expr = ParseSelectors(postfix_expr, false); 7073 postfix_expr = ParseSelectors(postfix_expr, false);
7076 if (IsIncrementOperator(CurrentToken())) { 7074 if (IsIncrementOperator(CurrentToken())) {
7077 TRACE_PARSER("IncrementOperator"); 7075 TRACE_PARSER("IncrementOperator");
7078 Token::Kind incr_op = CurrentToken(); 7076 Token::Kind incr_op = CurrentToken();
7079 if (!IsAssignableExpr(postfix_expr)) { 7077 if (!IsAssignableExpr(postfix_expr)) {
7080 ErrorMsg("expression is not assignable"); 7078 ErrorMsg("expression is not assignable");
7081 } 7079 }
7082 ConsumeToken(); 7080 ConsumeToken();
7083 // Not prefix. 7081 // Not prefix.
7084 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr); 7082 AstNode* left_expr = PrepareCompoundAssignmentNodes(&postfix_expr);
7085 const LocalVariable& temp = GetIncrementTempLocal(); 7083 const LocalVariable* temp = GetIncrementTempLocal();
7086 AstNode* save = 7084 AstNode* save =
7087 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); 7085 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr);
7088 Token::Kind binary_op = 7086 Token::Kind binary_op =
7089 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; 7087 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB;
7090 BinaryOpNode* add = new BinaryOpNode( 7088 BinaryOpNode* add = new BinaryOpNode(
7091 postfix_expr_pos, 7089 postfix_expr_pos,
7092 binary_op, 7090 binary_op,
7093 save, 7091 save,
7094 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); 7092 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1))));
7095 AstNode* store = CreateAssignmentNode(left_expr, add); 7093 AstNode* store = CreateAssignmentNode(left_expr, add);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
7389 // If node is non NULL return an AST node corresponding to the identifier. 7387 // If node is non NULL return an AST node corresponding to the identifier.
7390 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 7388 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
7391 const String &ident, 7389 const String &ident,
7392 AstNode** node) { 7390 AstNode** node) {
7393 TRACE_PARSER("ResolveIdentInLocalScope"); 7391 TRACE_PARSER("ResolveIdentInLocalScope");
7394 Isolate* isolate = Isolate::Current(); 7392 Isolate* isolate = Isolate::Current();
7395 // First try to find the identifier in the nested local scopes. 7393 // First try to find the identifier in the nested local scopes.
7396 LocalVariable* local = LookupLocalScope(ident); 7394 LocalVariable* local = LookupLocalScope(ident);
7397 if (local != NULL) { 7395 if (local != NULL) {
7398 if (node != NULL) { 7396 if (node != NULL) {
7399 *node = new LoadLocalNode(ident_pos, *local); 7397 *node = new LoadLocalNode(ident_pos, local);
7400 } 7398 }
7401 return true; 7399 return true;
7402 } 7400 }
7403 7401
7404 // Try to find the identifier in the class scope of the current class. 7402 // Try to find the identifier in the class scope of the current class.
7405 Class& cls = Class::Handle(isolate, current_class().raw()); 7403 Class& cls = Class::Handle(isolate, current_class().raw());
7406 Function& func = Function::Handle(isolate, Function::null()); 7404 Function& func = Function::Handle(isolate, Function::null());
7407 Field& field = Field::Handle(isolate, Field::null()); 7405 Field& field = Field::Handle(isolate, Field::null());
7408 7406
7409 // First check if a field exists. 7407 // First check if a field exists.
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
7893 ArgumentListNode* arguments) { 7891 ArgumentListNode* arguments) {
7894 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { 7892 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) {
7895 EnsureExpressionTemp(); 7893 EnsureExpressionTemp();
7896 } 7894 }
7897 LocalVariable* allocated = 7895 LocalVariable* allocated =
7898 CreateTempConstVariable(token_pos, token_pos, "alloc"); 7896 CreateTempConstVariable(token_pos, token_pos, "alloc");
7899 return new ConstructorCallNode(token_pos, 7897 return new ConstructorCallNode(token_pos,
7900 type_arguments, 7898 type_arguments,
7901 constructor, 7899 constructor,
7902 arguments, 7900 arguments,
7903 *allocated); 7901 allocated);
7904 } 7902 }
7905 7903
7906 7904
7907 static void AddKeyValuePair(ArrayNode* pairs, 7905 static void AddKeyValuePair(ArrayNode* pairs,
7908 bool is_const, 7906 bool is_const,
7909 AstNode* key, 7907 AstNode* key,
7910 AstNode* value) { 7908 AstNode* value) {
7911 if (is_const) { 7909 if (is_const) {
7912 ASSERT(key->IsLiteralNode()); 7910 ASSERT(key->IsLiteralNode());
7913 ASSERT(key->AsLiteralNode()->literal().IsString()); 7911 ASSERT(key->AsLiteralNode()->literal().IsString());
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
8593 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), 8591 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix),
8594 qual_ident); 8592 qual_ident);
8595 } 8593 }
8596 ASSERT(primary != NULL); 8594 ASSERT(primary != NULL);
8597 } else if (CurrentToken() == Token::kTHIS) { 8595 } else if (CurrentToken() == Token::kTHIS) {
8598 const String& this_name = String::Handle(Symbols::This()); 8596 const String& this_name = String::Handle(Symbols::This());
8599 LocalVariable* local = LookupLocalScope(this_name); 8597 LocalVariable* local = LookupLocalScope(this_name);
8600 if (local == NULL) { 8598 if (local == NULL) {
8601 ErrorMsg("receiver 'this' is not in scope"); 8599 ErrorMsg("receiver 'this' is not in scope");
8602 } 8600 }
8603 primary = new LoadLocalNode(TokenPos(), *local); 8601 primary = new LoadLocalNode(TokenPos(), local);
8604 ConsumeToken(); 8602 ConsumeToken();
8605 } else if (CurrentToken() == Token::kINTEGER) { 8603 } else if (CurrentToken() == Token::kINTEGER) {
8606 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral()); 8604 const Integer& literal = Integer::ZoneHandle(CurrentIntegerLiteral());
8607 primary = new LiteralNode(TokenPos(), literal); 8605 primary = new LiteralNode(TokenPos(), literal);
8608 ConsumeToken(); 8606 ConsumeToken();
8609 } else if (CurrentToken() == Token::kTRUE) { 8607 } else if (CurrentToken() == Token::kTRUE) {
8610 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::True())); 8608 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::True()));
8611 ConsumeToken(); 8609 ConsumeToken();
8612 } else if (CurrentToken() == Token::kFALSE) { 8610 } else if (CurrentToken() == Token::kFALSE) {
8613 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False())); 8611 primary = new LiteralNode(TokenPos(), Bool::ZoneHandle(Bool::False()));
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
8960 void Parser::SkipQualIdent() { 8958 void Parser::SkipQualIdent() {
8961 ASSERT(IsIdentifier()); 8959 ASSERT(IsIdentifier());
8962 ConsumeToken(); 8960 ConsumeToken();
8963 if (CurrentToken() == Token::kPERIOD) { 8961 if (CurrentToken() == Token::kPERIOD) {
8964 ConsumeToken(); // Consume the kPERIOD token. 8962 ConsumeToken(); // Consume the kPERIOD token.
8965 ExpectIdentifier("identifier expected after '.'"); 8963 ExpectIdentifier("identifier expected after '.'");
8966 } 8964 }
8967 } 8965 }
8968 8966
8969 } // namespace dart 8967 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/parser.h ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698