| 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);
|
|
|