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

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

Issue 460763002: Fix returning from async functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: add scope via sequencenode add method Created 6 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 "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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698