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

Unified Diff: runtime/vm/ast_transformer.cc

Issue 484933003: Await it! (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebase 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
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/ast_transformer.cc
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index e4637e5427829ebe023c438fb493c7879df0881d..6ef865f0e246a4e88846d46a2240b562078efbf2 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -13,6 +13,7 @@ namespace dart {
// Nodes that are unreachable from already parsed expressions.
#define FOR_EACH_UNREACHABLE_NODE(V) \
+ V(AwaitMarker) \
V(Case) \
V(CatchClause) \
V(CloneContext) \
@@ -85,15 +86,18 @@ void AwaitTransformer::VisitTypeNode(TypeNode* node) {
}
-
void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
// Await transformation:
//
// :await_temp_var_X = <expr>;
// :result_param = :await_temp_var_X;
// if (:result_param is Future) {
- // // :result_param.then(:async_op);
+ // AwaitMarker(kNewContinuationState);
+ // :result_param.then(:async_op);
+ // return; // (return_type() == kContinuation)
// }
+ // AwaitMarker(kTargetForContinuation); // Join happens here.
+ // :saved_try_ctx_var = :await_saved_try_ctx_var_y;
// :await_temp_var_(X+1) = :result_param;
LocalVariable* async_op = preamble_->scope()->LookupVariable(
@@ -104,46 +108,48 @@ void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
ASSERT(result_param != NULL);
node->expr()->Visit(this);
- preamble_->Add(new(I) StoreLocalNode(Scanner::kNoSourcePos,
- result_param,
- result_));
+ preamble_->Add(new(I) StoreLocalNode(
+ Scanner::kNoSourcePos, result_param, result_));
LoadLocalNode* load_result_param = new(I) LoadLocalNode(
Scanner::kNoSourcePos, result_param);
SequenceNode* is_future_branch = new(I) SequenceNode(
Scanner::kNoSourcePos, preamble_->scope());
+ AwaitMarkerNode* await_marker =
+ new(I) AwaitMarkerNode(AwaitMarkerNode::kNewContinuationState);
+ await_marker->set_scope(preamble_->scope());
+ is_future_branch->Add(await_marker);
ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos);
args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op));
- // TODO(mlippautz): Once continuations are supported, just call .then().
- // is_future_branch->Add(new(I) InstanceCallNode(
- // Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args));
- //
- // For now, throw an exception.
- const String& exception = String::ZoneHandle(
- I, String::New("awaitable futures not yet supported", Heap::kOld));
- is_future_branch->Add(new(I) ThrowNode(
- Scanner::kNoSourcePos,
- new(I) LiteralNode(
- Scanner::kNoSourcePos,
- String::ZoneHandle(I, Symbols::New(exception))),
- NULL));
+ is_future_branch->Add(new(I) InstanceCallNode(
+ Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args));
+ ReturnNode* continuation_return = new(I) ReturnNode(Scanner::kNoSourcePos);
+ continuation_return->set_return_type(ReturnNode::kContinuation);
+ is_future_branch->Add(continuation_return);
+
const Class& cls = Class::ZoneHandle(
I, library_.LookupClass(Symbols::Future()));
- const AbstractType& future_type = AbstractType::ZoneHandle(I,
- cls.RareType());
+ const AbstractType& future_type = AbstractType::ZoneHandle(I, cls.RareType());
ASSERT(!future_type.IsNull());
- TypeNode* future_type_node = new(I) TypeNode(
- Scanner::kNoSourcePos, future_type);
- IfNode* is_future_if = new(I) IfNode(
+ preamble_->Add(new(I) IfNode(
Scanner::kNoSourcePos,
- new(I) ComparisonNode(Scanner::kNoSourcePos,
- Token::kIS,
- load_result_param,
- future_type_node),
+ new (I) ComparisonNode(
+ Scanner::kNoSourcePos,
+ Token::kIS,
+ load_result_param,
+ new (I) TypeNode(Scanner::kNoSourcePos, future_type)),
is_future_branch,
- NULL);
- preamble_->Add(is_future_if);
-
- // TODO(mlippautz): Join for await needs to happen here.
+ 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.
+ if (parsed_function_->saved_try_ctx() != NULL) {
+ preamble_->Add(new (I) StoreLocalNode(
+ Scanner::kNoSourcePos,
+ parsed_function_->saved_try_ctx(),
+ new (I) LoadLocalNode(
+ Scanner::kNoSourcePos, parsed_function_->async_saved_try_ctx())));
+ }
LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode(
Scanner::kNoSourcePos, result_param));
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698