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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 4d0e741c47c372fae22fc0e384917383cc8aa14e..761ddfa668054401e861c4d51afc6ccd66e8c113 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -834,7 +834,10 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) {
if (!HasReturnNode(node_sequence)) {
// Add implicit return node.
- node_sequence->Add(new ReturnNode(func.end_token_pos()));
+ ReturnNode* implicit_return =
+ new(Isolate::Current()) ReturnNode(func.end_token_pos(),
+ node_sequence->scope());
+ node_sequence->Add(implicit_return);
}
if (parsed_function->has_expression_temp_var()) {
node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
@@ -1016,7 +1019,8 @@ SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) {
if (expr->EvalConstExpr() == NULL) {
ReportError(expr_pos, "initializer is not a valid compile-time constant");
}
- ReturnNode* return_node = new ReturnNode(ident_pos, expr);
+ ReturnNode* return_node =
+ new ReturnNode(ident_pos, expr, current_block_->scope);
current_block_->statements->Add(return_node);
} else {
// This getter may be called each time the static field is accessed.
@@ -1087,7 +1091,8 @@ SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) {
// Generate code returning the field value.
ReturnNode* return_node =
new ReturnNode(ident_pos,
- new LoadStaticFieldNode(ident_pos, field));
+ new LoadStaticFieldNode(ident_pos, field),
+ current_block_->scope);
current_block_->statements->Add(return_node);
}
return CloseBlock();
@@ -1234,7 +1239,7 @@ SequenceNode* Parser::ParseInstanceGetter(const Function& func) {
new LoadInstanceFieldNode(ident_pos, load_receiver, field);
ReturnNode* return_node =
- new ReturnNode(Scanner::kNoSourcePos, load_field);
+ new ReturnNode(Scanner::kNoSourcePos, load_field, current_block_->scope);
current_block_->statements->Add(return_node);
return CloseBlock();
}
@@ -1278,7 +1283,7 @@ SequenceNode* Parser::ParseInstanceSetter(const Function& func) {
StoreInstanceFieldNode* store_field =
new StoreInstanceFieldNode(ident_pos, receiver, field, value);
current_block_->statements->Add(store_field);
- current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
+ current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos, NULL));
return CloseBlock();
}
@@ -1308,7 +1313,8 @@ SequenceNode* Parser::ParseMethodExtractor(const Function& func) {
load_receiver,
NULL);
- ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure);
+ ReturnNode* return_node =
+ new ReturnNode(Scanner::kNoSourcePos, closure, current_block_->scope);
current_block_->statements->Add(return_node);
return CloseBlock();
}
@@ -1405,7 +1411,7 @@ SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func,
StaticCallNode* call =
new StaticCallNode(token_pos, no_such_method, arguments);
- ReturnNode* return_node = new ReturnNode(token_pos, call);
+ ReturnNode* return_node = new ReturnNode(token_pos, call, NULL);
current_block_->statements->Add(return_node);
return CloseBlock();
}
@@ -1465,7 +1471,7 @@ SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func,
result = BuildClosureCall(token_pos, getter_call, args);
}
- ReturnNode* return_node = new ReturnNode(token_pos, result);
+ ReturnNode* return_node = new ReturnNode(token_pos, result, NULL);
current_block_->statements->Add(return_node);
return CloseBlock();
}
@@ -2576,7 +2582,7 @@ SequenceNode* Parser::MakeImplicitConstructor(const Function& func) {
CheckFieldsInitialized(current_class());
// Empty constructor body.
- current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
+ current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos, NULL));
SequenceNode* statements = CloseBlock();
return statements;
}
@@ -2895,7 +2901,7 @@ SequenceNode* Parser::ParseConstructor(const Function& func,
new IfNode(Scanner::kNoSourcePos, comparison, ctor_block, NULL);
current_block_->statements->Add(guarded_block_statements);
}
- current_block_->statements->Add(new ReturnNode(func.end_token_pos()));
+ current_block_->statements->Add(new ReturnNode(func.end_token_pos(), NULL));
SequenceNode* statements = CloseBlock();
return statements;
}
@@ -3054,7 +3060,8 @@ SequenceNode* Parser::ParseFunc(const Function& func,
const intptr_t expr_pos = TokenPos();
AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
ASSERT(expr != NULL);
- current_block_->statements->Add(new ReturnNode(expr_pos, expr));
+ current_block_->statements->Add(
+ new ReturnNode(expr_pos, expr, current_block_->scope));
end_token_pos = TokenPos();
} else if (IsLiteral("native")) {
if (String::Handle(I, func.name()).Equals(
@@ -3118,7 +3125,8 @@ void Parser::AddEqualityNullCheck() {
LoadReceiver(Scanner::kNoSourcePos),
null_operand);
SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos, NULL);
- arg_is_null->Add(new ReturnNode(Scanner::kNoSourcePos, result));
+ arg_is_null->Add(
+ new ReturnNode(Scanner::kNoSourcePos, result, current_block_->scope));
IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos,
check_arg,
arg_is_null,
@@ -5651,47 +5659,16 @@ SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
new (I) LoadLocalNode(
Scanner::kNoSourcePos,
async_completer),
- Symbols::CompleterFuture()));
+ Symbols::CompleterFuture()),
+ current_block_->scope);
current_block_->statements->Add(return_node);
return CloseBlock();
}
void Parser::CloseAsyncClosure(SequenceNode* body) {
- ASSERT(body != NULL);
- // Replace an optional ReturnNode with the appropriate completer calls.
- intptr_t last_index = body->length() - 1;
- AstNode* last = NULL;
- if (last_index >= 0) {
- // Non-empty async closure.
- last = body->NodeAt(last_index);
- }
- ArgumentListNode* args = new (I) ArgumentListNode(Scanner::kNoSourcePos);
- LocalVariable* completer = body->scope()->LookupVariable(
- Symbols::AsyncCompleter(), false);
- ASSERT(completer != NULL);
- if (last != NULL && last->IsReturnNode()) {
- // Replace
- // return <expr>;
- // with
- // completer.complete(<expr>);
- args->Add(body->NodeAt(last_index)->AsReturnNode()->value());
- body->ReplaceNodeAt(last_index,
- new (I) InstanceCallNode(
- Scanner::kNoSourcePos,
- new (I) LoadLocalNode(Scanner::kNoSourcePos, completer),
- Symbols::CompleterComplete(),
- args));
- } else {
- // Add to AST:
- // completer.complete();
- body->Add(
- new (I) InstanceCallNode(
- Scanner::kNoSourcePos,
- new (I) LoadLocalNode(Scanner::kNoSourcePos, completer),
- Symbols::CompleterComplete(),
- args));
- }
+ // We need a temporary expression to store intermediate return values.
+ parsed_function()->EnsureExpressionTemp();
}
@@ -5800,13 +5777,15 @@ void Parser::ParseNativeFunctionBlock(const ParamList* params,
Dart_NativeEntryResolver resolver = library.native_entry_resolver();
bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver);
current_block_->statements->Add(new(I) ReturnNode(
- TokenPos(), new(I) NativeBodyNode(
+ TokenPos(),
+ new(I) NativeBodyNode(
TokenPos(),
Function::ZoneHandle(I, func.raw()),
native_name,
native_function,
current_block_->scope,
- is_bootstrap_native)));
+ is_bootstrap_native),
+ NULL));
}
@@ -7704,9 +7683,9 @@ AstNode* Parser::ParseStatement() {
"return of a value not allowed in constructors");
}
AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
- statement = new(I) ReturnNode(statement_pos, expr);
+ statement = new(I) ReturnNode(statement_pos, expr, current_block_->scope);
} else {
- statement = new(I) ReturnNode(statement_pos);
+ statement = new(I) ReturnNode(statement_pos, current_block_->scope);
}
AddNodeForFinallyInlining(statement);
ExpectSemicolon();
@@ -10974,7 +10953,7 @@ const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) {
return Instance::ZoneHandle(I, field.value());
} else {
ASSERT(expr->EvalConstExpr() != NULL);
- ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr);
+ ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr, NULL);
// Compile time constant expressions cannot reference anything from a
// local scope.
LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0);

Powered by Google App Engine
This is Rietveld 408576698