| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 : script_(script), | 232 : script_(script), |
| 233 tokens_(TokenStream::Handle(script.tokens())), | 233 tokens_(TokenStream::Handle(script.tokens())), |
| 234 token_index_(0), | 234 token_index_(0), |
| 235 current_block_(NULL), | 235 current_block_(NULL), |
| 236 is_top_level_(false), | 236 is_top_level_(false), |
| 237 current_member_(NULL), | 237 current_member_(NULL), |
| 238 allow_function_literals_(true), | 238 allow_function_literals_(true), |
| 239 current_function_(Function::Handle()), | 239 current_function_(Function::Handle()), |
| 240 current_class_(Class::Handle()), | 240 current_class_(Class::Handle()), |
| 241 library_(library), | 241 library_(library), |
| 242 try_blocks_list_(NULL) { | 242 try_blocks_list_(NULL), |
| 243 increment_temp_(NULL) { |
| 243 ASSERT(!tokens_.IsNull()); | 244 ASSERT(!tokens_.IsNull()); |
| 244 ASSERT(!library.IsNull()); | 245 ASSERT(!library.IsNull()); |
| 245 SetPosition(0); | 246 SetPosition(0); |
| 246 } | 247 } |
| 247 | 248 |
| 248 | 249 |
| 249 Parser::Parser(const Script& script, | 250 Parser::Parser(const Script& script, |
| 250 const Function& function, | 251 const Function& function, |
| 251 intptr_t token_index) | 252 intptr_t token_index) |
| 252 : script_(script), | 253 : script_(script), |
| 253 tokens_(TokenStream::Handle(script.tokens())), | 254 tokens_(TokenStream::Handle(script.tokens())), |
| 254 token_index_(0), | 255 token_index_(0), |
| 255 current_block_(NULL), | 256 current_block_(NULL), |
| 256 is_top_level_(false), | 257 is_top_level_(false), |
| 257 current_member_(NULL), | 258 current_member_(NULL), |
| 258 allow_function_literals_(true), | 259 allow_function_literals_(true), |
| 259 current_function_(function), | 260 current_function_(function), |
| 260 current_class_(Class::Handle(current_function_.owner())), | 261 current_class_(Class::Handle(current_function_.owner())), |
| 261 library_(Library::Handle(current_class_.library())), | 262 library_(Library::Handle(current_class_.library())), |
| 262 try_blocks_list_(NULL) { | 263 try_blocks_list_(NULL), |
| 264 increment_temp_(NULL) { |
| 263 ASSERT(!tokens_.IsNull()); | 265 ASSERT(!tokens_.IsNull()); |
| 264 ASSERT(!function.IsNull()); | 266 ASSERT(!function.IsNull()); |
| 265 SetPosition(token_index); | 267 SetPosition(token_index); |
| 266 } | 268 } |
| 267 | 269 |
| 268 | 270 |
| 269 bool Parser::SetAllowFunctionLiterals(bool value) { | 271 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 270 bool current_value = allow_function_literals_; | 272 bool current_value = allow_function_literals_; |
| 271 allow_function_literals_ = value; | 273 allow_function_literals_ = value; |
| 272 return current_value; | 274 return current_value; |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); | 642 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); |
| 641 } | 643 } |
| 642 } | 644 } |
| 643 | 645 |
| 644 | 646 |
| 645 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 647 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 646 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 648 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 647 Isolate* isolate = Isolate::Current(); | 649 Isolate* isolate = Isolate::Current(); |
| 648 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 650 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 649 // Compilation can be nested, preserve the ast node id. | 651 // Compilation can be nested, preserve the ast node id. |
| 650 const int prev_ast_node_id = isolate->ast_node_id(); | 652 const intptr_t prev_ast_node_id = isolate->ast_node_id(); |
| 651 isolate->set_ast_node_id(0); | 653 isolate->set_ast_node_id(0); |
| 652 ASSERT(parsed_function != NULL); | 654 ASSERT(parsed_function != NULL); |
| 653 const Function& func = parsed_function->function(); | 655 const Function& func = parsed_function->function(); |
| 654 const Class& cls = Class::Handle(isolate, func.owner()); | 656 const Class& cls = Class::Handle(isolate, func.owner()); |
| 655 const Script& script = Script::Handle(isolate, cls.script()); | 657 const Script& script = Script::Handle(isolate, cls.script()); |
| 656 Parser parser(script, func, func.token_index()); | 658 Parser parser(script, func, func.token_index()); |
| 657 SequenceNode* node_sequence = NULL; | 659 SequenceNode* node_sequence = NULL; |
| 658 Array& default_parameter_values = Array::Handle(isolate, Array::null()); | 660 Array& default_parameter_values = Array::Handle(isolate, Array::null()); |
| 659 switch (func.kind()) { | 661 switch (func.kind()) { |
| 660 case RawFunction::kFunction: | 662 case RawFunction::kFunction: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 676 node_sequence = parser.ParseStaticConstGetter(func); | 678 node_sequence = parser.ParseStaticConstGetter(func); |
| 677 break; | 679 break; |
| 678 default: | 680 default: |
| 679 UNREACHABLE(); | 681 UNREACHABLE(); |
| 680 } | 682 } |
| 681 | 683 |
| 682 if (!HasReturnNode(node_sequence)) { | 684 if (!HasReturnNode(node_sequence)) { |
| 683 // Add implicit return node. | 685 // Add implicit return node. |
| 684 node_sequence->Add(new ReturnNode(parser.token_index_)); | 686 node_sequence->Add(new ReturnNode(parser.token_index_)); |
| 685 } | 687 } |
| 688 if (parser.increment_temp_ != NULL) { |
| 689 node_sequence->scope()->AddVariable(parser.increment_temp_); |
| 690 } |
| 686 parsed_function->SetNodeSequence(node_sequence); | 691 parsed_function->SetNodeSequence(node_sequence); |
| 687 | 692 |
| 688 // The instantiator may be required at run time for generic type checks or | 693 // The instantiator may be required at run time for generic type checks or |
| 689 // allocation of generic types. | 694 // allocation of generic types. |
| 690 if (parser.IsInstantiatorRequired()) { | 695 if (parser.IsInstantiatorRequired()) { |
| 691 // In the case of a local function, only set the instantiator if the | 696 // In the case of a local function, only set the instantiator if the |
| 692 // receiver was captured. | 697 // receiver was captured. |
| 693 const bool kTestOnly = true; | 698 const bool kTestOnly = true; |
| 694 LocalVariable* receiver = | 699 LocalVariable* receiver = |
| 695 parser.LookupReceiver(node_sequence->scope(), | 700 parser.LookupReceiver(node_sequence->scope(), |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 | 1213 |
| 1209 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1214 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1210 // 'this' parameter is the first argument to super call. | 1215 // 'this' parameter is the first argument to super call. |
| 1211 AstNode* receiver = LoadReceiver(supercall_pos); | 1216 AstNode* receiver = LoadReceiver(supercall_pos); |
| 1212 arguments->Add(receiver); | 1217 arguments->Add(receiver); |
| 1213 ParseActualParameters(arguments, kAllowConst); | 1218 ParseActualParameters(arguments, kAllowConst); |
| 1214 return new StaticCallNode(supercall_pos, super_function, arguments); | 1219 return new StaticCallNode(supercall_pos, super_function, arguments); |
| 1215 } | 1220 } |
| 1216 | 1221 |
| 1217 | 1222 |
| 1223 // Simple test if a node is side effect free. |
| 1224 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
| 1225 if (node->IsLiteralNode()) { |
| 1226 return true; |
| 1227 } |
| 1228 if (node->IsLoadLocalNode() && !node->AsLoadLocalNode()->HasPseudo()) { |
| 1229 return true; |
| 1230 } |
| 1231 return false; |
| 1232 } |
| 1233 |
| 1234 |
| 1218 AstNode* Parser::ParseSuperOperator() { | 1235 AstNode* Parser::ParseSuperOperator() { |
| 1219 TRACE_PARSER("ParseSuperOperator"); | 1236 TRACE_PARSER("ParseSuperOperator"); |
| 1220 AstNode* super_op = NULL; | 1237 AstNode* super_op = NULL; |
| 1221 const intptr_t operator_pos = token_index_; | 1238 const intptr_t operator_pos = token_index_; |
| 1222 | 1239 |
| 1223 if (CurrentToken() == Token::kLBRACK) { | 1240 if (CurrentToken() == Token::kLBRACK) { |
| 1224 ConsumeToken(); | 1241 ConsumeToken(); |
| 1225 AstNode* index_expr = ParseExpr(kAllowConst); | 1242 AstNode* index_expr = ParseExpr(kAllowConst); |
| 1226 ExpectToken(Token::kRBRACK); | 1243 ExpectToken(Token::kRBRACK); |
| 1227 | 1244 |
| 1228 if (Token::IsAssignmentOperator(CurrentToken()) && | 1245 if (Token::IsAssignmentOperator(CurrentToken()) && |
| 1229 (CurrentToken() != Token::kASSIGN)) { | 1246 (CurrentToken() != Token::kASSIGN)) { |
| 1230 // Compound assignment. Ensure side effects in index expression | 1247 // Compound assignment. Ensure side effects in index expression |
| 1231 // only execute once. If the index is not a local variable or an | 1248 // only execute once. If the index is not a local variable or an |
| 1232 // literal, evaluate and save in a temporary local. | 1249 // literal, evaluate and save in a temporary local. |
| 1233 if (!index_expr->IsLoadLocalNode() && !index_expr->IsLiteralNode()) { | 1250 if (!IsSimpleLocalOrLiteralNode(index_expr)) { |
| 1234 LocalVariable* temp = | 1251 LocalVariable* temp = |
| 1235 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); | 1252 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); |
| 1236 AstNode* save = | 1253 AstNode* save = |
| 1237 new StoreLocalNode(operator_pos, *temp, index_expr); | 1254 new StoreLocalNode(operator_pos, *temp, index_expr); |
| 1238 current_block_->statements->Add(save); | 1255 current_block_->statements->Add(save); |
| 1239 index_expr = new LoadLocalNode(operator_pos, *temp); | 1256 index_expr = new LoadLocalNode(operator_pos, *temp); |
| 1240 } | 1257 } |
| 1241 } | 1258 } |
| 1242 | 1259 |
| 1243 // Resolve the [] operator function in the superclass. | 1260 // Resolve the [] operator function in the superclass. |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1846 // We need to patch the super _initializer_ call so that it | 1863 // We need to patch the super _initializer_ call so that it |
| 1847 // saves the evaluated actual arguments in temporary variables. | 1864 // saves the evaluated actual arguments in temporary variables. |
| 1848 // The temporary variables are necessary so that the argument | 1865 // The temporary variables are necessary so that the argument |
| 1849 // expressions are not evaluated twice. | 1866 // expressions are not evaluated twice. |
| 1850 ArgumentListNode* ctor_args = super_call->arguments(); | 1867 ArgumentListNode* ctor_args = super_call->arguments(); |
| 1851 // The super initializer call has at least 2 arguments: the | 1868 // The super initializer call has at least 2 arguments: the |
| 1852 // implicit receiver, and the hidden construction phase. | 1869 // implicit receiver, and the hidden construction phase. |
| 1853 ASSERT(ctor_args->length() >= 2); | 1870 ASSERT(ctor_args->length() >= 2); |
| 1854 for (int i = 2; i < ctor_args->length(); i++) { | 1871 for (int i = 2; i < ctor_args->length(); i++) { |
| 1855 AstNode* arg = ctor_args->NodeAt(i); | 1872 AstNode* arg = ctor_args->NodeAt(i); |
| 1856 if (!arg->IsLoadLocalNode() && !arg->IsLiteralNode()) { | 1873 if (!IsSimpleLocalOrLiteralNode(arg)) { |
| 1857 LocalVariable* temp = | 1874 LocalVariable* temp = |
| 1858 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); | 1875 CreateTempConstVariable(arg->token_index(), arg->id(), "sca"); |
| 1859 AstNode* save_temp = | 1876 AstNode* save_temp = |
| 1860 new StoreLocalNode(arg->token_index(), *temp, arg); | 1877 new StoreLocalNode(arg->token_index(), *temp, arg); |
| 1861 ctor_args->SetNodeAt(i, save_temp); | 1878 ctor_args->SetNodeAt(i, save_temp); |
| 1862 } | 1879 } |
| 1863 } | 1880 } |
| 1864 } | 1881 } |
| 1865 OpenBlock(); // Block to collect constructor body nodes. | 1882 OpenBlock(); // Block to collect constructor body nodes. |
| 1866 | 1883 |
| (...skipping 3986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5853 } | 5870 } |
| 5854 } | 5871 } |
| 5855 current_preced--; | 5872 current_preced--; |
| 5856 } | 5873 } |
| 5857 return left_operand; | 5874 return left_operand; |
| 5858 } | 5875 } |
| 5859 | 5876 |
| 5860 | 5877 |
| 5861 bool Parser::IsAssignableExpr(AstNode* expr) { | 5878 bool Parser::IsAssignableExpr(AstNode* expr) { |
| 5862 return expr->IsPrimaryNode() | 5879 return expr->IsPrimaryNode() |
| 5863 || expr->IsLoadLocalNode() | 5880 || (expr->IsLoadLocalNode() && !expr->AsLoadLocalNode()->HasPseudo()) |
| 5864 || expr->IsLoadStaticFieldNode() | 5881 || expr->IsLoadStaticFieldNode() |
| 5865 || expr->IsStaticGetterNode() | 5882 || expr->IsStaticGetterNode() |
| 5866 || expr->IsInstanceGetterNode() | 5883 || expr->IsInstanceGetterNode() |
| 5867 || expr->IsLoadIndexedNode(); | 5884 || expr->IsLoadIndexedNode(); |
| 5868 } | 5885 } |
| 5869 | 5886 |
| 5870 | 5887 |
| 5871 AstNode* Parser::ParseExprList() { | 5888 AstNode* Parser::ParseExprList() { |
| 5872 TRACE_PARSER("ParseExprList"); | 5889 TRACE_PARSER("ParseExprList"); |
| 5873 AstNode* expressions = ParseExpr(kAllowConst); | 5890 AstNode* expressions = ParseExpr(kAllowConst); |
| 5874 if (CurrentToken() == Token::kCOMMA) { | 5891 if (CurrentToken() == Token::kCOMMA) { |
| 5875 // Collect comma-separated expressions in a non scope owning sequence node. | 5892 // Collect comma-separated expressions in a non scope owning sequence node. |
| 5876 SequenceNode* list = new SequenceNode(token_index_, NULL); | 5893 SequenceNode* list = new SequenceNode(token_index_, NULL); |
| 5877 list->Add(expressions); | 5894 list->Add(expressions); |
| 5878 while (CurrentToken() == Token::kCOMMA) { | 5895 while (CurrentToken() == Token::kCOMMA) { |
| 5879 ConsumeToken(); | 5896 ConsumeToken(); |
| 5880 AstNode* expr = ParseExpr(kAllowConst); | 5897 AstNode* expr = ParseExpr(kAllowConst); |
| 5881 list->Add(expr); | 5898 list->Add(expr); |
| 5882 } | 5899 } |
| 5883 expressions = list; | 5900 expressions = list; |
| 5884 } | 5901 } |
| 5885 return expressions; | 5902 return expressions; |
| 5886 } | 5903 } |
| 5887 | 5904 |
| 5888 | 5905 |
| 5889 static bool IsLocalOrLiteralNode(AstNode* node) { | 5906 const LocalVariable& Parser::GetIncrementTempLocal() { |
| 5890 return node->IsLoadLocalNode() || node->IsLiteralNode(); | 5907 if (increment_temp_ == NULL) { |
| 5908 increment_temp_ = |
| 5909 new LocalVariable(current_function_.token_index(), |
| 5910 String::ZoneHandle(String::NewSymbol(":incrtemp")), |
| 5911 Type::ZoneHandle(Type::DynamicType())); |
| 5912 } |
| 5913 return *increment_temp_; |
| 5891 } | 5914 } |
| 5892 | 5915 |
| 5893 | |
| 5894 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, | 5916 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, |
| 5895 intptr_t token_id, | 5917 intptr_t token_id, |
| 5896 const char* s) { | 5918 const char* s) { |
| 5897 char name[64]; | 5919 char name[64]; |
| 5898 OS::SNPrint(name, 64, ":%s%d", s, token_id); | 5920 OS::SNPrint(name, 64, ":%s%d", s, token_id); |
| 5899 LocalVariable* temp = | 5921 LocalVariable* temp = |
| 5900 new LocalVariable(token_index, | 5922 new LocalVariable(token_index, |
| 5901 String::ZoneHandle(String::NewSymbol(name)), | 5923 String::ZoneHandle(String::NewSymbol(name)), |
| 5902 Type::ZoneHandle(Type::DynamicType())); | 5924 Type::ZoneHandle(Type::DynamicType())); |
| 5903 temp->set_is_final(); | 5925 temp->set_is_final(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5990 // left and right nodes. 'expr' becomes the right node, left node is returned as | 6012 // left and right nodes. 'expr' becomes the right node, left node is returned as |
| 5991 // result. | 6013 // result. |
| 5992 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 6014 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 5993 AstNode* node = *expr; | 6015 AstNode* node = *expr; |
| 5994 if (node->IsLoadIndexedNode()) { | 6016 if (node->IsLoadIndexedNode()) { |
| 5995 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); | 6017 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); |
| 5996 LoadIndexedNode* right_node = left_node; | 6018 LoadIndexedNode* right_node = left_node; |
| 5997 intptr_t node_id = node->id(); | 6019 intptr_t node_id = node->id(); |
| 5998 intptr_t token_index = node->token_index(); | 6020 intptr_t token_index = node->token_index(); |
| 5999 node = NULL; // Do not use it. | 6021 node = NULL; // Do not use it. |
| 6000 if (!IsLocalOrLiteralNode(left_node->array())) { | 6022 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { |
| 6001 LocalVariable* temp = | 6023 LocalVariable* temp = |
| 6002 CreateTempConstVariable(token_index, node_id, "lia"); | 6024 CreateTempConstVariable(token_index, node_id, "lia"); |
| 6003 StoreLocalNode* save = | 6025 StoreLocalNode* save = |
| 6004 new StoreLocalNode(token_index, *temp, left_node->array()); | 6026 new StoreLocalNode(token_index, *temp, left_node->array()); |
| 6005 left_node = | 6027 left_node = |
| 6006 new LoadIndexedNode(token_index, save, left_node->index_expr()); | 6028 new LoadIndexedNode(token_index, save, left_node->index_expr()); |
| 6007 right_node = new LoadIndexedNode(token_index, | 6029 right_node = new LoadIndexedNode(token_index, |
| 6008 new LoadLocalNode(token_index, *temp), | 6030 new LoadLocalNode(token_index, *temp), |
| 6009 right_node->index_expr()); | 6031 right_node->index_expr()); |
| 6010 } | 6032 } |
| 6011 if (!IsLocalOrLiteralNode(left_node->index_expr())) { | 6033 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { |
| 6012 LocalVariable* temp = | 6034 LocalVariable* temp = |
| 6013 CreateTempConstVariable(token_index, node_id, "lix"); | 6035 CreateTempConstVariable(token_index, node_id, "lix"); |
| 6014 StoreLocalNode* save = | 6036 StoreLocalNode* save = |
| 6015 new StoreLocalNode(token_index, *temp, left_node->index_expr()); | 6037 new StoreLocalNode(token_index, *temp, left_node->index_expr()); |
| 6016 left_node = new LoadIndexedNode(token_index, | 6038 left_node = new LoadIndexedNode(token_index, |
| 6017 left_node->array(), | 6039 left_node->array(), |
| 6018 save); | 6040 save); |
| 6019 right_node = new LoadIndexedNode(token_index, | 6041 right_node = new LoadIndexedNode(token_index, |
| 6020 right_node->array(), | 6042 right_node->array(), |
| 6021 new LoadLocalNode(token_index, *temp)); | 6043 new LoadLocalNode(token_index, *temp)); |
| 6022 } | 6044 } |
| 6023 *expr = right_node; | 6045 *expr = right_node; |
| 6024 return left_node; | 6046 return left_node; |
| 6025 } | 6047 } |
| 6026 if (node->IsInstanceGetterNode()) { | 6048 if (node->IsInstanceGetterNode()) { |
| 6027 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); | 6049 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); |
| 6028 InstanceGetterNode* right_node = left_node; | 6050 InstanceGetterNode* right_node = left_node; |
| 6029 intptr_t node_id = node->id(); | 6051 intptr_t node_id = node->id(); |
| 6030 intptr_t token_index = node->token_index(); | 6052 intptr_t token_index = node->token_index(); |
| 6031 node = NULL; // Do not use it. | 6053 node = NULL; // Do not use it. |
| 6032 if (!IsLocalOrLiteralNode(left_node->receiver())) { | 6054 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { |
| 6033 LocalVariable* temp = | 6055 LocalVariable* temp = |
| 6034 CreateTempConstVariable(token_index, node_id, "igr"); | 6056 CreateTempConstVariable(token_index, node_id, "igr"); |
| 6035 StoreLocalNode* save = | 6057 StoreLocalNode* save = |
| 6036 new StoreLocalNode(token_index, *temp, left_node->receiver()); | 6058 new StoreLocalNode(token_index, *temp, left_node->receiver()); |
| 6037 left_node = new InstanceGetterNode(token_index, | 6059 left_node = new InstanceGetterNode(token_index, |
| 6038 save, | 6060 save, |
| 6039 left_node->field_name()); | 6061 left_node->field_name()); |
| 6040 right_node = new InstanceGetterNode(token_index, | 6062 right_node = new InstanceGetterNode(token_index, |
| 6041 new LoadLocalNode(token_index, *temp), | 6063 new LoadLocalNode(token_index, *temp), |
| 6042 right_node->field_name()); | 6064 right_node->field_name()); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6619 } | 6641 } |
| 6620 if (IsIncrementOperator(CurrentToken())) { | 6642 if (IsIncrementOperator(CurrentToken())) { |
| 6621 TRACE_PARSER("IncrementOperator"); | 6643 TRACE_PARSER("IncrementOperator"); |
| 6622 Token::Kind incr_op = CurrentToken(); | 6644 Token::Kind incr_op = CurrentToken(); |
| 6623 if (!IsAssignableExpr(postfix_expr)) { | 6645 if (!IsAssignableExpr(postfix_expr)) { |
| 6624 ErrorMsg("expression is not assignable"); | 6646 ErrorMsg("expression is not assignable"); |
| 6625 } | 6647 } |
| 6626 ConsumeToken(); | 6648 ConsumeToken(); |
| 6627 // Not prefix. | 6649 // Not prefix. |
| 6628 if (postfix_expr->IsLoadStaticFieldNode() || | 6650 if (postfix_expr->IsLoadStaticFieldNode() || |
| 6629 postfix_expr->IsStaticGetterNode()) { | 6651 postfix_expr->IsStaticGetterNode() || |
| 6630 LocalVariable* temp = CreateTempConstVariable( | 6652 postfix_expr->IsLoadLocalNode()) { |
| 6631 postfix_expr_pos, postfix_expr->id(), "incoplix"); | 6653 const LocalVariable& temp = GetIncrementTempLocal(); |
| 6632 AstNode* save = | 6654 AstNode* save = |
| 6633 new StoreLocalNode(postfix_expr_pos, *temp, postfix_expr); | 6655 new StoreLocalNode(postfix_expr_pos, temp, postfix_expr); |
| 6634 Token::Kind binary_op = | 6656 Token::Kind binary_op = |
| 6635 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 6657 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 6636 BinaryOpNode* add = new BinaryOpNode( | 6658 BinaryOpNode* add = new BinaryOpNode( |
| 6637 postfix_expr_pos, | 6659 postfix_expr_pos, |
| 6638 binary_op, | 6660 binary_op, |
| 6639 save, | 6661 save, |
| 6640 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); | 6662 new LiteralNode(postfix_expr_pos, Smi::ZoneHandle(Smi::New(1)))); |
| 6641 AstNode* store = postfix_expr->MakeAssignmentNode(add); | 6663 AstNode* store = postfix_expr->MakeAssignmentNode(add); |
| 6642 LoadLocalNode* load_res = | 6664 LoadLocalNode* load_res = |
| 6643 new LoadLocalNode(postfix_expr_pos, *temp, store); | 6665 new LoadLocalNode(postfix_expr_pos, temp, store); |
| 6644 return load_res; | 6666 return load_res; |
| 6645 } else { | 6667 } else { |
| 6646 AstNode* incr_op_node = | 6668 AstNode* incr_op_node = |
| 6647 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); | 6669 postfix_expr->MakeIncrOpNode(postfix_expr_pos, incr_op, false); |
| 6648 if (incr_op_node == NULL) { | 6670 if (incr_op_node == NULL) { |
| 6649 Unimplemented("incr op not implemented"); | 6671 Unimplemented("incr op not implemented"); |
| 6650 } | 6672 } |
| 6651 postfix_expr = incr_op_node; | 6673 postfix_expr = incr_op_node; |
| 6652 } | 6674 } |
| 6653 } | 6675 } |
| (...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8426 void Parser::SkipQualIdent() { | 8448 void Parser::SkipQualIdent() { |
| 8427 ASSERT(IsIdentifier()); | 8449 ASSERT(IsIdentifier()); |
| 8428 ConsumeToken(); | 8450 ConsumeToken(); |
| 8429 if (CurrentToken() == Token::kPERIOD) { | 8451 if (CurrentToken() == Token::kPERIOD) { |
| 8430 ConsumeToken(); // Consume the kPERIOD token. | 8452 ConsumeToken(); // Consume the kPERIOD token. |
| 8431 ExpectIdentifier("identifier expected after '.'"); | 8453 ExpectIdentifier("identifier expected after '.'"); |
| 8432 } | 8454 } |
| 8433 } | 8455 } |
| 8434 | 8456 |
| 8435 } // namespace dart | 8457 } // namespace dart |
| OLD | NEW |