| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 StaticCallNode* init_call = | 1079 StaticCallNode* init_call = |
| 1080 new StaticCallNode(expr_pos, init_function, arguments); | 1080 new StaticCallNode(expr_pos, init_function, arguments); |
| 1081 initialize_field->Add(init_call); | 1081 initialize_field->Add(init_call); |
| 1082 | 1082 |
| 1083 AstNode* uninitialized_check = | 1083 AstNode* uninitialized_check = |
| 1084 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); | 1084 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); |
| 1085 current_block_->statements->Add(uninitialized_check); | 1085 current_block_->statements->Add(uninitialized_check); |
| 1086 | 1086 |
| 1087 // Generate code returning the field value. | 1087 // Generate code returning the field value. |
| 1088 ReturnNode* return_node = | 1088 ReturnNode* return_node = |
| 1089 new ReturnNode(ident_pos, | 1089 new ReturnNode(ident_pos, new LoadStaticFieldNode(ident_pos, field)); |
| 1090 new LoadStaticFieldNode(ident_pos, field)); | |
| 1091 current_block_->statements->Add(return_node); | 1090 current_block_->statements->Add(return_node); |
| 1092 } | 1091 } |
| 1093 return CloseBlock(); | 1092 return CloseBlock(); |
| 1094 } | 1093 } |
| 1095 | 1094 |
| 1096 | 1095 |
| 1097 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { | 1096 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { |
| 1098 TRACE_PARSER("ParseStaticInitializer"); | 1097 TRACE_PARSER("ParseStaticInitializer"); |
| 1099 ParamList params; | 1098 ParamList params; |
| 1100 ASSERT(func.num_fixed_parameters() == 0); // static. | 1099 ASSERT(func.num_fixed_parameters() == 0); // static. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1225 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1227 ASSERT(IsIdentifier()); | 1226 ASSERT(IsIdentifier()); |
| 1228 const String& field_name = *CurrentLiteral(); | 1227 const String& field_name = *CurrentLiteral(); |
| 1229 const Class& field_class = Class::Handle(I, func.Owner()); | 1228 const Class& field_class = Class::Handle(I, func.Owner()); |
| 1230 const Field& field = | 1229 const Field& field = |
| 1231 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); | 1230 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); |
| 1232 | 1231 |
| 1233 LoadInstanceFieldNode* load_field = | 1232 LoadInstanceFieldNode* load_field = |
| 1234 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1233 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1235 | 1234 |
| 1236 ReturnNode* return_node = | 1235 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field); |
| 1237 new ReturnNode(Scanner::kNoSourcePos, load_field); | |
| 1238 current_block_->statements->Add(return_node); | 1236 current_block_->statements->Add(return_node); |
| 1239 return CloseBlock(); | 1237 return CloseBlock(); |
| 1240 } | 1238 } |
| 1241 | 1239 |
| 1242 | 1240 |
| 1243 // Create AstNodes for an implicit instance setter method: | 1241 // Create AstNodes for an implicit instance setter method: |
| 1244 // LoadLocalNode 0 ('this') | 1242 // LoadLocalNode 0 ('this') |
| 1245 // LoadLocalNode 1 ('value') | 1243 // LoadLocalNode 1 ('value') |
| 1246 // SetInstanceField (field_name); | 1244 // SetInstanceField (field_name); |
| 1247 // ReturnNode (void); | 1245 // ReturnNode (void); |
| (...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3110 ComparisonNode* check_arg = | 3108 ComparisonNode* check_arg = |
| 3111 new ComparisonNode(Scanner::kNoSourcePos, | 3109 new ComparisonNode(Scanner::kNoSourcePos, |
| 3112 Token::kEQ_STRICT, | 3110 Token::kEQ_STRICT, |
| 3113 argument, | 3111 argument, |
| 3114 null_operand); | 3112 null_operand); |
| 3115 ComparisonNode* result = | 3113 ComparisonNode* result = |
| 3116 new ComparisonNode(Scanner::kNoSourcePos, | 3114 new ComparisonNode(Scanner::kNoSourcePos, |
| 3117 Token::kEQ_STRICT, | 3115 Token::kEQ_STRICT, |
| 3118 LoadReceiver(Scanner::kNoSourcePos), | 3116 LoadReceiver(Scanner::kNoSourcePos), |
| 3119 null_operand); | 3117 null_operand); |
| 3120 SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos, NULL); | 3118 SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos, |
| 3119 current_block_->scope); |
| 3121 arg_is_null->Add(new ReturnNode(Scanner::kNoSourcePos, result)); | 3120 arg_is_null->Add(new ReturnNode(Scanner::kNoSourcePos, result)); |
| 3122 IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos, | 3121 IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos, |
| 3123 check_arg, | 3122 check_arg, |
| 3124 arg_is_null, | 3123 arg_is_null, |
| 3125 NULL); | 3124 NULL); |
| 3126 current_block_->statements->Add(if_arg_null); | 3125 current_block_->statements->Add(if_arg_null); |
| 3127 } | 3126 } |
| 3128 | 3127 |
| 3129 | 3128 |
| 3130 void Parser::SkipIf(Token::Kind token) { | 3129 void Parser::SkipIf(Token::Kind token) { |
| (...skipping 2520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5651 new (I) LoadLocalNode( | 5650 new (I) LoadLocalNode( |
| 5652 Scanner::kNoSourcePos, | 5651 Scanner::kNoSourcePos, |
| 5653 async_completer), | 5652 async_completer), |
| 5654 Symbols::CompleterFuture())); | 5653 Symbols::CompleterFuture())); |
| 5655 current_block_->statements->Add(return_node); | 5654 current_block_->statements->Add(return_node); |
| 5656 return CloseBlock(); | 5655 return CloseBlock(); |
| 5657 } | 5656 } |
| 5658 | 5657 |
| 5659 | 5658 |
| 5660 void Parser::CloseAsyncClosure(SequenceNode* body) { | 5659 void Parser::CloseAsyncClosure(SequenceNode* body) { |
| 5661 ASSERT(body != NULL); | 5660 // We need a temporary expression to store intermediate return values. |
| 5662 // Replace an optional ReturnNode with the appropriate completer calls. | 5661 parsed_function()->EnsureExpressionTemp(); |
| 5663 intptr_t last_index = body->length() - 1; | |
| 5664 AstNode* last = NULL; | |
| 5665 if (last_index >= 0) { | |
| 5666 // Non-empty async closure. | |
| 5667 last = body->NodeAt(last_index); | |
| 5668 } | |
| 5669 ArgumentListNode* args = new (I) ArgumentListNode(Scanner::kNoSourcePos); | |
| 5670 LocalVariable* completer = body->scope()->LookupVariable( | |
| 5671 Symbols::AsyncCompleter(), false); | |
| 5672 ASSERT(completer != NULL); | |
| 5673 if (last != NULL && last->IsReturnNode()) { | |
| 5674 // Replace | |
| 5675 // return <expr>; | |
| 5676 // with | |
| 5677 // completer.complete(<expr>); | |
| 5678 args->Add(body->NodeAt(last_index)->AsReturnNode()->value()); | |
| 5679 body->ReplaceNodeAt(last_index, | |
| 5680 new (I) InstanceCallNode( | |
| 5681 Scanner::kNoSourcePos, | |
| 5682 new (I) LoadLocalNode(Scanner::kNoSourcePos, completer), | |
| 5683 Symbols::CompleterComplete(), | |
| 5684 args)); | |
| 5685 } else { | |
| 5686 // Add to AST: | |
| 5687 // completer.complete(); | |
| 5688 body->Add( | |
| 5689 new (I) InstanceCallNode( | |
| 5690 Scanner::kNoSourcePos, | |
| 5691 new (I) LoadLocalNode(Scanner::kNoSourcePos, completer), | |
| 5692 Symbols::CompleterComplete(), | |
| 5693 args)); | |
| 5694 } | |
| 5695 } | 5662 } |
| 5696 | 5663 |
| 5697 | 5664 |
| 5698 // Set up default values for all optional parameters to the function. | 5665 // Set up default values for all optional parameters to the function. |
| 5699 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5666 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 5700 Array* default_values) { | 5667 Array* default_values) { |
| 5701 if (params->num_optional_parameters > 0) { | 5668 if (params->num_optional_parameters > 0) { |
| 5702 // Build array of default parameter values. | 5669 // Build array of default parameter values. |
| 5703 ParamDesc* param = | 5670 ParamDesc* param = |
| 5704 params->parameters->data() + params->num_fixed_parameters; | 5671 params->parameters->data() + params->num_fixed_parameters; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5793 ReportError(native_pos, | 5760 ReportError(native_pos, |
| 5794 "native function '%s' (%" Pd " arguments) cannot be found", | 5761 "native function '%s' (%" Pd " arguments) cannot be found", |
| 5795 native_name.ToCString(), func.NumParameters()); | 5762 native_name.ToCString(), func.NumParameters()); |
| 5796 } | 5763 } |
| 5797 func.SetIsNativeAutoSetupScope(auto_setup_scope); | 5764 func.SetIsNativeAutoSetupScope(auto_setup_scope); |
| 5798 | 5765 |
| 5799 // Now add the NativeBodyNode and return statement. | 5766 // Now add the NativeBodyNode and return statement. |
| 5800 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); | 5767 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); |
| 5801 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); | 5768 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); |
| 5802 current_block_->statements->Add(new(I) ReturnNode( | 5769 current_block_->statements->Add(new(I) ReturnNode( |
| 5803 TokenPos(), new(I) NativeBodyNode( | 5770 TokenPos(), |
| 5771 new(I) NativeBodyNode( |
| 5804 TokenPos(), | 5772 TokenPos(), |
| 5805 Function::ZoneHandle(I, func.raw()), | 5773 Function::ZoneHandle(I, func.raw()), |
| 5806 native_name, | 5774 native_name, |
| 5807 native_function, | 5775 native_function, |
| 5808 current_block_->scope, | 5776 current_block_->scope, |
| 5809 is_bootstrap_native))); | 5777 is_bootstrap_native))); |
| 5810 } | 5778 } |
| 5811 | 5779 |
| 5812 | 5780 |
| 5813 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 5781 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| (...skipping 5511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11325 void Parser::SkipQualIdent() { | 11293 void Parser::SkipQualIdent() { |
| 11326 ASSERT(IsIdentifier()); | 11294 ASSERT(IsIdentifier()); |
| 11327 ConsumeToken(); | 11295 ConsumeToken(); |
| 11328 if (CurrentToken() == Token::kPERIOD) { | 11296 if (CurrentToken() == Token::kPERIOD) { |
| 11329 ConsumeToken(); // Consume the kPERIOD token. | 11297 ConsumeToken(); // Consume the kPERIOD token. |
| 11330 ExpectIdentifier("identifier expected after '.'"); | 11298 ExpectIdentifier("identifier expected after '.'"); |
| 11331 } | 11299 } |
| 11332 } | 11300 } |
| 11333 | 11301 |
| 11334 } // namespace dart | 11302 } // namespace dart |
| OLD | NEW |