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

Unified Diff: runtime/vm/ast_transformer.cc

Issue 634603002: Await always waits (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/ast_transformer.cc
===================================================================
--- runtime/vm/ast_transformer.cc (revision 41104)
+++ runtime/vm/ast_transformer.cc (working copy)
@@ -4,6 +4,7 @@
#include "vm/ast_transformer.h"
+#include "vm/object_store.h"
#include "vm/parser.h"
namespace dart {
@@ -43,12 +44,10 @@
#undef DEFINE_UNREACHABLE
AwaitTransformer::AwaitTransformer(SequenceNode* preamble,
- const Library& library,
ParsedFunction* const parsed_function,
LocalScope* function_top)
: preamble_(preamble),
temp_cnt_(0),
- library_(library),
parsed_function_(parsed_function),
function_top_(function_top),
isolate_(Isolate::Current()) {
@@ -114,13 +113,14 @@
//
// :await_temp_var_X = <expr>;
// :result_param = :await_temp_var_X;
- // if (:result_param is Future) {
- // AwaitMarker(kNewContinuationState);
- // :result_param = :result_param.then(:async_op);
- // _asyncCatchHelper(:result_param.catchError, :async_op);
- // return; // (return_type() == kContinuation)
+ // if (:result_param is !Future) {
+ // :result_param = Future.value(:result_param);
// }
- // AwaitMarker(kTargetForContinuation); // Join happens here.
+ // AwaitMarker(kNewContinuationState);
+ // :result_param = :result_param.then(:async_op);
+ // _asyncCatchHelper(:result_param.catchError, :async_op);
+ // return; // (return_type() == kContinuationTarget)
+ //
// :saved_try_ctx_var = :await_saved_try_ctx_var_y;
// :await_temp_var_(X+1) = :result_param;
@@ -131,30 +131,64 @@
LocalVariable* error_param = GetVariableInScope(
preamble_->scope(), Symbols::AsyncOperationErrorParam());
- node->expr()->Visit(this);
+ AstNode* transformed_expr = Transform(node->expr());
preamble_->Add(new(I) StoreLocalNode(
- Scanner::kNoSourcePos, result_param, result_));
+ Scanner::kNoSourcePos, result_param, transformed_expr));
+
LoadLocalNode* load_result_param = new(I) LoadLocalNode(
Scanner::kNoSourcePos, result_param);
- LocalScope* is_future_scope = ChainNewScope(preamble_->scope());
- SequenceNode* is_future_branch = new (I) SequenceNode(
- Scanner::kNoSourcePos, is_future_scope);
- AwaitMarkerNode* await_marker = new (I) AwaitMarkerNode(
- AwaitMarkerNode::kNewContinuationState);
- await_marker->set_scope(is_future_scope);
- GetVariableInScope(is_future_scope, Symbols::AwaitJumpVar());
- GetVariableInScope(is_future_scope, Symbols::AwaitContextVar());
- is_future_branch->Add(await_marker);
+
+ const Class& future_cls =
+ Class::ZoneHandle(I, I->object_store()->future_class());
+ ASSERT(!future_cls.IsNull());
+ const AbstractType& future_type =
+ AbstractType::ZoneHandle(I, future_cls.RareType());
+ ASSERT(!future_type.IsNull());
+
+ LocalScope* is_not_future_scope = ChainNewScope(preamble_->scope());
+ SequenceNode* is_not_future_branch =
+ new (I) SequenceNode(Scanner::kNoSourcePos, is_not_future_scope);
+
+ // if (:result_param is !Future) {
+ // :result_param = Future.value(:result_param);
+ // }
+ const Function& value_ctor = Function::ZoneHandle(
+ I, future_cls.LookupFunction(Symbols::FutureValue()));
+ ASSERT(!value_ctor.IsNull());
+ ArgumentListNode* ctor_args = new (I) ArgumentListNode(Scanner::kNoSourcePos);
+ ctor_args->Add(new (I) LoadLocalNode(Scanner::kNoSourcePos, result_param));
+ ConstructorCallNode* ctor_call =
+ new (I) ConstructorCallNode(Scanner::kNoSourcePos,
+ TypeArguments::ZoneHandle(I),
+ value_ctor,
+ ctor_args);
+ is_not_future_branch->Add(new (I) StoreLocalNode(
+ Scanner::kNoSourcePos, result_param, ctor_call));
+ AstNode* is_not_future_test = new (I) ComparisonNode(
+ Scanner::kNoSourcePos,
+ Token::kISNOT,
+ load_result_param,
+ new (I) TypeNode(Scanner::kNoSourcePos, future_type));
+ preamble_->Add(new(I) IfNode(Scanner::kNoSourcePos,
+ is_not_future_test,
+ is_not_future_branch,
+ NULL));
+
+ AwaitMarkerNode* await_marker = new (I) AwaitMarkerNode();
+ await_marker->set_scope(preamble_->scope());
+ GetVariableInScope(preamble_->scope(), Symbols::AwaitJumpVar());
+ GetVariableInScope(preamble_->scope(), Symbols::AwaitContextVar());
+ preamble_->Add(await_marker);
ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos);
+
args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op));
- is_future_branch->Add(new (I) StoreLocalNode(
+ preamble_->Add(new (I) StoreLocalNode(
Scanner::kNoSourcePos,
result_param,
- new(I) InstanceCallNode(
- Scanner::kNoSourcePos,
- load_result_param,
- Symbols::FutureThen(),
- args)));
+ new(I) InstanceCallNode(Scanner::kNoSourcePos,
+ load_result_param,
+ Symbols::FutureThen(),
+ args)));
const Library& core_lib = Library::Handle(Library::CoreLibrary());
const Function& async_catch_helper = Function::ZoneHandle(
I, core_lib.LookupFunctionAllowPrivate(Symbols::AsyncCatchHelper()));
@@ -168,30 +202,14 @@
catch_helper_args->Add(catch_error_getter);
catch_helper_args->Add(new (I) LoadLocalNode(
Scanner::kNoSourcePos, async_op));
- is_future_branch->Add(new (I) StaticCallNode(
+ preamble_->Add(new (I) StaticCallNode(
Scanner::kNoSourcePos,
async_catch_helper,
catch_helper_args));
ReturnNode* continuation_return = new(I) ReturnNode(Scanner::kNoSourcePos);
- continuation_return->set_return_type(ReturnNode::kContinuation);
- is_future_branch->Add(continuation_return);
+ continuation_return->set_return_type(ReturnNode::kContinuationTarget);
+ preamble_->Add(continuation_return);
- const Class& cls = Class::ZoneHandle(
- I, library_.LookupClass(Symbols::Future()));
- const AbstractType& future_type = AbstractType::ZoneHandle(I, cls.RareType());
- ASSERT(!future_type.IsNull());
- preamble_->Add(new(I) IfNode(
- Scanner::kNoSourcePos,
- new (I) ComparisonNode(
- Scanner::kNoSourcePos,
- Token::kIS,
- load_result_param,
- new (I) TypeNode(Scanner::kNoSourcePos, future_type)),
- is_future_branch,
- NULL));
- preamble_->Add(new (I) AwaitMarkerNode(
- AwaitMarkerNode::kTargetForContinuation));
-
// If this expression is part of a try block, also append the code for
// restoring the saved try context that lives on the stack.
const String& async_saved_try_ctx_name =
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/dart_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698