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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 return new LocalVariable(token_pos, | 106 return new LocalVariable(token_pos, |
107 String::ZoneHandle(Symbols::ExprTemp()), | 107 String::ZoneHandle(Symbols::ExprTemp()), |
108 Type::ZoneHandle(Type::DynamicType())); | 108 Type::ZoneHandle(Type::DynamicType())); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 112 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
113 ASSERT(node_sequence_ == NULL); | 113 ASSERT(node_sequence_ == NULL); |
114 ASSERT(node_sequence != NULL); | 114 ASSERT(node_sequence != NULL); |
115 node_sequence_ = node_sequence; | 115 node_sequence_ = node_sequence; |
116 const int num_fixed_params = function().num_fixed_parameters(); | |
117 const int num_opt_params = function().num_optional_parameters(); | |
118 // Allocated ids for parameters. | |
119 intptr_t parameter_id = AstNode::kNoId; | |
120 for (intptr_t i = 0; i < num_fixed_params + num_opt_params; i++) { | |
121 parameter_id = AstNode::GetNextId(); | |
122 if (i == 0) { | |
123 node_sequence_->set_first_parameter_id(parameter_id); | |
124 } | |
125 } | |
126 node_sequence_->set_last_parameter_id(parameter_id); | |
127 } | 116 } |
128 | 117 |
129 | 118 |
130 void ParsedFunction::AllocateVariables() { | 119 void ParsedFunction::AllocateVariables() { |
131 LocalScope* scope = node_sequence()->scope(); | 120 LocalScope* scope = node_sequence()->scope(); |
132 const int fixed_parameter_count = function().num_fixed_parameters(); | 121 const int fixed_parameter_count = function().num_fixed_parameters(); |
133 const int optional_parameter_count = function().num_optional_parameters(); | 122 const int optional_parameter_count = function().num_optional_parameters(); |
134 const int parameter_count = fixed_parameter_count + optional_parameter_count; | 123 const int parameter_count = fixed_parameter_count + optional_parameter_count; |
135 const bool is_native_instance_closure = | 124 const bool is_native_instance_closure = |
136 function().is_native() && function().IsImplicitInstanceClosureFunction(); | 125 function().is_native() && function().IsImplicitInstanceClosureFunction(); |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 } else { | 644 } else { |
656 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); | 645 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); |
657 } | 646 } |
658 } | 647 } |
659 | 648 |
660 | 649 |
661 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 650 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
662 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 651 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
663 Isolate* isolate = Isolate::Current(); | 652 Isolate* isolate = Isolate::Current(); |
664 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 653 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
665 // Compilation can be nested, preserve the ast node id. | |
666 const intptr_t prev_ast_node_id = isolate->ast_node_id(); | |
667 isolate->set_ast_node_id(0); | |
668 ASSERT(parsed_function != NULL); | 654 ASSERT(parsed_function != NULL); |
669 const Function& func = parsed_function->function(); | 655 const Function& func = parsed_function->function(); |
670 const Class& cls = Class::Handle(isolate, func.owner()); | 656 const Class& cls = Class::Handle(isolate, func.owner()); |
671 const Script& script = Script::Handle(isolate, cls.script()); | 657 const Script& script = Script::Handle(isolate, cls.script()); |
672 Parser parser(script, func, func.token_pos()); | 658 Parser parser(script, func, func.token_pos()); |
673 SequenceNode* node_sequence = NULL; | 659 SequenceNode* node_sequence = NULL; |
674 Array& default_parameter_values = Array::Handle(isolate, Array::null()); | 660 Array& default_parameter_values = Array::Handle(isolate, Array::null()); |
675 switch (func.kind()) { | 661 switch (func.kind()) { |
676 case RawFunction::kRegularFunction: | 662 case RawFunction::kRegularFunction: |
677 case RawFunction::kClosureFunction: | 663 case RawFunction::kClosureFunction: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly); | 707 instantiator = parser.LookupReceiver(node_sequence->scope(), kTestOnly); |
722 } | 708 } |
723 if (!parser.current_function().IsLocalFunction() || | 709 if (!parser.current_function().IsLocalFunction() || |
724 ((instantiator != NULL) && instantiator->is_captured())) { | 710 ((instantiator != NULL) && instantiator->is_captured())) { |
725 parsed_function->set_instantiator( | 711 parsed_function->set_instantiator( |
726 new LoadLocalNode(node_sequence->token_pos(), *instantiator)); | 712 new LoadLocalNode(node_sequence->token_pos(), *instantiator)); |
727 } | 713 } |
728 } | 714 } |
729 | 715 |
730 parsed_function->set_default_parameter_values(default_parameter_values); | 716 parsed_function->set_default_parameter_values(default_parameter_values); |
731 isolate->set_ast_node_id(prev_ast_node_id); | |
732 } | 717 } |
733 | 718 |
734 | 719 |
735 // TODO(regis): Implement support for non-const final static fields (currently | 720 // TODO(regis): Implement support for non-const final static fields (currently |
736 // supported "final" fields are actually const fields). | 721 // supported "final" fields are actually const fields). |
737 // TODO(regis): Since a const variable is implicitly final, | 722 // TODO(regis): Since a const variable is implicitly final, |
738 // rename ParseStaticConstGetter to ParseStaticFinalGetter and | 723 // rename ParseStaticConstGetter to ParseStaticFinalGetter and |
739 // rename kConstImplicitGetter to kImplicitFinalGetter. | 724 // rename kConstImplicitGetter to kImplicitFinalGetter. |
740 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { | 725 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { |
741 TRACE_PARSER("ParseStaticConstGetter"); | 726 TRACE_PARSER("ParseStaticConstGetter"); |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 1318 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
1334 ExpectToken(Token::kRBRACK); | 1319 ExpectToken(Token::kRBRACK); |
1335 | 1320 |
1336 if (Token::IsAssignmentOperator(CurrentToken()) && | 1321 if (Token::IsAssignmentOperator(CurrentToken()) && |
1337 (CurrentToken() != Token::kASSIGN)) { | 1322 (CurrentToken() != Token::kASSIGN)) { |
1338 // Compound assignment. Ensure side effects in index expression | 1323 // Compound assignment. Ensure side effects in index expression |
1339 // only execute once. If the index is not a local variable or an | 1324 // only execute once. If the index is not a local variable or an |
1340 // literal, evaluate and save in a temporary local. | 1325 // literal, evaluate and save in a temporary local. |
1341 if (!IsSimpleLocalOrLiteralNode(index_expr)) { | 1326 if (!IsSimpleLocalOrLiteralNode(index_expr)) { |
1342 LocalVariable* temp = | 1327 LocalVariable* temp = |
1343 CreateTempConstVariable(operator_pos, index_expr->id(), "lix"); | 1328 CreateTempConstVariable(operator_pos, "lix"); |
1344 AstNode* save = | 1329 AstNode* save = |
1345 new StoreLocalNode(operator_pos, *temp, index_expr); | 1330 new StoreLocalNode(operator_pos, *temp, index_expr); |
1346 current_block_->statements->Add(save); | 1331 current_block_->statements->Add(save); |
1347 index_expr = new LoadLocalNode(operator_pos, *temp); | 1332 index_expr = new LoadLocalNode(operator_pos, *temp); |
1348 } | 1333 } |
1349 } | 1334 } |
1350 | 1335 |
1351 // Resolve the [] operator function in the superclass. | 1336 // Resolve the [] operator function in the superclass. |
1352 const String& index_operator_name = | 1337 const String& index_operator_name = |
1353 String::ZoneHandle(Symbols::IndexToken()); | 1338 String::ZoneHandle(Symbols::IndexToken()); |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2030 // The temporary variables are necessary so that the argument | 2015 // The temporary variables are necessary so that the argument |
2031 // expressions are not evaluated twice. | 2016 // expressions are not evaluated twice. |
2032 ArgumentListNode* ctor_args = super_call->arguments(); | 2017 ArgumentListNode* ctor_args = super_call->arguments(); |
2033 // The super initializer call has at least 2 arguments: the | 2018 // The super initializer call has at least 2 arguments: the |
2034 // implicit receiver, and the hidden construction phase. | 2019 // implicit receiver, and the hidden construction phase. |
2035 ASSERT(ctor_args->length() >= 2); | 2020 ASSERT(ctor_args->length() >= 2); |
2036 for (int i = 2; i < ctor_args->length(); i++) { | 2021 for (int i = 2; i < ctor_args->length(); i++) { |
2037 AstNode* arg = ctor_args->NodeAt(i); | 2022 AstNode* arg = ctor_args->NodeAt(i); |
2038 if (!IsSimpleLocalOrLiteralNode(arg)) { | 2023 if (!IsSimpleLocalOrLiteralNode(arg)) { |
2039 LocalVariable* temp = | 2024 LocalVariable* temp = |
2040 CreateTempConstVariable(arg->token_pos(), arg->id(), "sca"); | 2025 CreateTempConstVariable(arg->token_pos(), "sca"); |
2041 AstNode* save_temp = | 2026 AstNode* save_temp = |
2042 new StoreLocalNode(arg->token_pos(), *temp, arg); | 2027 new StoreLocalNode(arg->token_pos(), *temp, arg); |
2043 ctor_args->SetNodeAt(i, save_temp); | 2028 ctor_args->SetNodeAt(i, save_temp); |
2044 } | 2029 } |
2045 } | 2030 } |
2046 } | 2031 } |
2047 OpenBlock(); // Block to collect constructor body nodes. | 2032 OpenBlock(); // Block to collect constructor body nodes. |
2048 | 2033 |
2049 // Insert the implicit super call to the super constructor body. | 2034 // Insert the implicit super call to the super constructor body. |
2050 if (super_call != NULL) { | 2035 if (super_call != NULL) { |
(...skipping 4251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6302 } | 6287 } |
6303 | 6288 |
6304 | 6289 |
6305 void Parser::EnsureExpressionTemp() { | 6290 void Parser::EnsureExpressionTemp() { |
6306 // Temporary used later by the flow_graph_builder. | 6291 // Temporary used later by the flow_graph_builder. |
6307 GetIncrementTempLocal(); | 6292 GetIncrementTempLocal(); |
6308 } | 6293 } |
6309 | 6294 |
6310 | 6295 |
6311 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 6296 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
6312 intptr_t token_id, | |
6313 const char* s) { | 6297 const char* s) { |
6314 char name[64]; | 6298 char name[64]; |
6315 OS::SNPrint(name, 64, ":%s%d", s, token_id); | 6299 OS::SNPrint(name, 64, ":%s%d", s, token_pos); |
6316 LocalVariable* temp = | 6300 LocalVariable* temp = |
6317 new LocalVariable(token_pos, | 6301 new LocalVariable(token_pos, |
6318 String::ZoneHandle(Symbols::New(name)), | 6302 String::ZoneHandle(Symbols::New(name)), |
6319 Type::ZoneHandle(Type::DynamicType())); | 6303 Type::ZoneHandle(Type::DynamicType())); |
6320 temp->set_is_final(); | 6304 temp->set_is_final(); |
6321 current_block_->scope->AddVariable(temp); | 6305 current_block_->scope->AddVariable(temp); |
6322 return temp; | 6306 return temp; |
6323 } | 6307 } |
6324 | 6308 |
6325 | 6309 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6405 // to control inputs with potential side effects, the store part stores any | 6389 // to control inputs with potential side effects, the store part stores any |
6406 // side effect creating inputs into locals. The load part reads then from | 6390 // side effect creating inputs into locals. The load part reads then from |
6407 // those locals. If expr may have side effects, it will be split into two new | 6391 // those locals. If expr may have side effects, it will be split into two new |
6408 // left and right nodes. 'expr' becomes the right node, left node is returned as | 6392 // left and right nodes. 'expr' becomes the right node, left node is returned as |
6409 // result. | 6393 // result. |
6410 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 6394 AstNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
6411 AstNode* node = *expr; | 6395 AstNode* node = *expr; |
6412 if (node->IsLoadIndexedNode()) { | 6396 if (node->IsLoadIndexedNode()) { |
6413 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); | 6397 LoadIndexedNode* left_node = node->AsLoadIndexedNode(); |
6414 LoadIndexedNode* right_node = left_node; | 6398 LoadIndexedNode* right_node = left_node; |
6415 intptr_t node_id = node->id(); | |
6416 intptr_t token_pos = node->token_pos(); | 6399 intptr_t token_pos = node->token_pos(); |
6417 node = NULL; // Do not use it. | 6400 node = NULL; // Do not use it. |
6418 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { | 6401 if (!IsSimpleLocalOrLiteralNode(left_node->array())) { |
6419 LocalVariable* temp = | 6402 LocalVariable* temp = |
6420 CreateTempConstVariable(token_pos, node_id, "lia"); | 6403 CreateTempConstVariable(token_pos, "lia"); |
6421 StoreLocalNode* save = | 6404 StoreLocalNode* save = |
6422 new StoreLocalNode(token_pos, *temp, left_node->array()); | 6405 new StoreLocalNode(token_pos, *temp, left_node->array()); |
6423 left_node = | 6406 left_node = |
6424 new LoadIndexedNode(token_pos, save, left_node->index_expr()); | 6407 new LoadIndexedNode(token_pos, save, left_node->index_expr()); |
6425 right_node = new LoadIndexedNode(token_pos, | 6408 right_node = new LoadIndexedNode(token_pos, |
6426 new LoadLocalNode(token_pos, *temp), | 6409 new LoadLocalNode(token_pos, *temp), |
6427 right_node->index_expr()); | 6410 right_node->index_expr()); |
6428 } | 6411 } |
6429 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { | 6412 if (!IsSimpleLocalOrLiteralNode(left_node->index_expr())) { |
6430 LocalVariable* temp = | 6413 LocalVariable* temp = |
6431 CreateTempConstVariable(token_pos, node_id, "lix"); | 6414 CreateTempConstVariable(token_pos, "lix"); |
6432 StoreLocalNode* save = | 6415 StoreLocalNode* save = |
6433 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); | 6416 new StoreLocalNode(token_pos, *temp, left_node->index_expr()); |
6434 left_node = new LoadIndexedNode(token_pos, | 6417 left_node = new LoadIndexedNode(token_pos, |
6435 left_node->array(), | 6418 left_node->array(), |
6436 save); | 6419 save); |
6437 right_node = new LoadIndexedNode(token_pos, | 6420 right_node = new LoadIndexedNode(token_pos, |
6438 right_node->array(), | 6421 right_node->array(), |
6439 new LoadLocalNode(token_pos, *temp)); | 6422 new LoadLocalNode(token_pos, *temp)); |
6440 } | 6423 } |
6441 *expr = right_node; | 6424 *expr = right_node; |
6442 return left_node; | 6425 return left_node; |
6443 } | 6426 } |
6444 if (node->IsInstanceGetterNode()) { | 6427 if (node->IsInstanceGetterNode()) { |
6445 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); | 6428 InstanceGetterNode* left_node = node->AsInstanceGetterNode(); |
6446 InstanceGetterNode* right_node = left_node; | 6429 InstanceGetterNode* right_node = left_node; |
6447 intptr_t node_id = node->id(); | |
6448 intptr_t token_pos = node->token_pos(); | 6430 intptr_t token_pos = node->token_pos(); |
6449 node = NULL; // Do not use it. | 6431 node = NULL; // Do not use it. |
6450 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { | 6432 if (!IsSimpleLocalOrLiteralNode(left_node->receiver())) { |
6451 LocalVariable* temp = | 6433 LocalVariable* temp = |
6452 CreateTempConstVariable(token_pos, node_id, "igr"); | 6434 CreateTempConstVariable(token_pos, "igr"); |
6453 StoreLocalNode* save = | 6435 StoreLocalNode* save = |
6454 new StoreLocalNode(token_pos, *temp, left_node->receiver()); | 6436 new StoreLocalNode(token_pos, *temp, left_node->receiver()); |
6455 left_node = new InstanceGetterNode(token_pos, | 6437 left_node = new InstanceGetterNode(token_pos, |
6456 save, | 6438 save, |
6457 left_node->field_name()); | 6439 left_node->field_name()); |
6458 right_node = new InstanceGetterNode(token_pos, | 6440 right_node = new InstanceGetterNode(token_pos, |
6459 new LoadLocalNode(token_pos, *temp), | 6441 new LoadLocalNode(token_pos, *temp), |
6460 right_node->field_name()); | 6442 right_node->field_name()); |
6461 } | 6443 } |
6462 *expr = right_node; | 6444 *expr = right_node; |
(...skipping 12 matching lines...) Expand all Loading... |
6475 result->IsStaticSetterNode())) { | 6457 result->IsStaticSetterNode())) { |
6476 EnsureExpressionTemp(); | 6458 EnsureExpressionTemp(); |
6477 } | 6459 } |
6478 return result; | 6460 return result; |
6479 } | 6461 } |
6480 | 6462 |
6481 | 6463 |
6482 AstNode* Parser::ParseCascades(AstNode* expr) { | 6464 AstNode* Parser::ParseCascades(AstNode* expr) { |
6483 intptr_t cascade_pos = TokenPos(); | 6465 intptr_t cascade_pos = TokenPos(); |
6484 LocalVariable* cascade_receiver_var = | 6466 LocalVariable* cascade_receiver_var = |
6485 CreateTempConstVariable(cascade_pos, expr->id(), "casc"); | 6467 CreateTempConstVariable(cascade_pos, "casc"); |
6486 StoreLocalNode* save_cascade = | 6468 StoreLocalNode* save_cascade = |
6487 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); | 6469 new StoreLocalNode(cascade_pos, *cascade_receiver_var, expr); |
6488 current_block_->statements->Add(save_cascade); | 6470 current_block_->statements->Add(save_cascade); |
6489 while (CurrentToken() == Token::kCASCADE) { | 6471 while (CurrentToken() == Token::kCASCADE) { |
6490 cascade_pos = TokenPos(); | 6472 cascade_pos = TokenPos(); |
6491 LoadLocalNode* load_cascade_receiver = | 6473 LoadLocalNode* load_cascade_receiver = |
6492 new LoadLocalNode(cascade_pos, *cascade_receiver_var); | 6474 new LoadLocalNode(cascade_pos, *cascade_receiver_var); |
6493 if (Token::IsIdentifier(LookaheadToken(1))) { | 6475 if (Token::IsIdentifier(LookaheadToken(1))) { |
6494 // Replace .. with . for ParseSelectors(). | 6476 // Replace .. with . for ParseSelectors(). |
6495 token_kind_ = Token::kPERIOD; | 6477 token_kind_ = Token::kPERIOD; |
(...skipping 1394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7890 | 7872 |
7891 ConstructorCallNode* Parser::CreateConstructorCallNode( | 7873 ConstructorCallNode* Parser::CreateConstructorCallNode( |
7892 intptr_t token_pos, | 7874 intptr_t token_pos, |
7893 const AbstractTypeArguments& type_arguments, | 7875 const AbstractTypeArguments& type_arguments, |
7894 const Function& constructor, | 7876 const Function& constructor, |
7895 ArgumentListNode* arguments) { | 7877 ArgumentListNode* arguments) { |
7896 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 7878 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
7897 EnsureExpressionTemp(); | 7879 EnsureExpressionTemp(); |
7898 } | 7880 } |
7899 LocalVariable* allocated = | 7881 LocalVariable* allocated = |
7900 CreateTempConstVariable(token_pos, token_pos, "alloc"); | 7882 CreateTempConstVariable(token_pos, "alloc"); |
7901 return new ConstructorCallNode(token_pos, | 7883 return new ConstructorCallNode(token_pos, |
7902 type_arguments, | 7884 type_arguments, |
7903 constructor, | 7885 constructor, |
7904 arguments, | 7886 arguments, |
7905 *allocated); | 7887 *allocated); |
7906 } | 7888 } |
7907 | 7889 |
7908 | 7890 |
7909 static void AddKeyValuePair(ArrayNode* pairs, | 7891 static void AddKeyValuePair(ArrayNode* pairs, |
7910 bool is_const, | 7892 bool is_const, |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8962 void Parser::SkipQualIdent() { | 8944 void Parser::SkipQualIdent() { |
8963 ASSERT(IsIdentifier()); | 8945 ASSERT(IsIdentifier()); |
8964 ConsumeToken(); | 8946 ConsumeToken(); |
8965 if (CurrentToken() == Token::kPERIOD) { | 8947 if (CurrentToken() == Token::kPERIOD) { |
8966 ConsumeToken(); // Consume the kPERIOD token. | 8948 ConsumeToken(); // Consume the kPERIOD token. |
8967 ExpectIdentifier("identifier expected after '.'"); | 8949 ExpectIdentifier("identifier expected after '.'"); |
8968 } | 8950 } |
8969 } | 8951 } |
8970 | 8952 |
8971 } // namespace dart | 8953 } // namespace dart |
OLD | NEW |