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

Side by Side 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, 3 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
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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/ast_transformer.h" 5 #include "vm/ast_transformer.h"
6 6
7 #include "vm/parser.h" 7 #include "vm/parser.h"
8 8
9 namespace dart { 9 namespace dart {
10 10
11 // Quick access to the locally defined isolate() method. 11 // Quick access to the locally defined isolate() method.
12 #define I (isolate()) 12 #define I (isolate())
13 13
14 // Nodes that are unreachable from already parsed expressions. 14 // Nodes that are unreachable from already parsed expressions.
15 #define FOR_EACH_UNREACHABLE_NODE(V) \ 15 #define FOR_EACH_UNREACHABLE_NODE(V) \
16 V(AwaitMarker) \
16 V(Case) \ 17 V(Case) \
17 V(CatchClause) \ 18 V(CatchClause) \
18 V(CloneContext) \ 19 V(CloneContext) \
19 V(ClosureCall) \ 20 V(ClosureCall) \
20 V(DoWhile) \ 21 V(DoWhile) \
21 V(If) \ 22 V(If) \
22 V(InitStaticField) \ 23 V(InitStaticField) \
23 V(InlinedFinally) \ 24 V(InlinedFinally) \
24 V(For) \ 25 V(For) \
25 V(Jump) \ 26 V(Jump) \
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { 79 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) {
79 result_ = node; 80 result_ = node;
80 } 81 }
81 82
82 83
83 void AwaitTransformer::VisitTypeNode(TypeNode* node) { 84 void AwaitTransformer::VisitTypeNode(TypeNode* node) {
84 result_ = new(I) TypeNode(node->token_pos(), node->type()); 85 result_ = new(I) TypeNode(node->token_pos(), node->type());
85 } 86 }
86 87
87 88
88
89 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { 89 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
90 // Await transformation: 90 // Await transformation:
91 // 91 //
92 // :await_temp_var_X = <expr>; 92 // :await_temp_var_X = <expr>;
93 // :result_param = :await_temp_var_X; 93 // :result_param = :await_temp_var_X;
94 // if (:result_param is Future) { 94 // if (:result_param is Future) {
95 // // :result_param.then(:async_op); 95 // AwaitMarker(kNewContinuationState);
96 // :result_param.then(:async_op);
97 // return; // (return_type() == kContinuation)
96 // } 98 // }
99 // AwaitMarker(kTargetForContinuation); // Join happens here.
100 // :saved_try_ctx_var = :await_saved_try_ctx_var_y;
97 // :await_temp_var_(X+1) = :result_param; 101 // :await_temp_var_(X+1) = :result_param;
98 102
99 LocalVariable* async_op = preamble_->scope()->LookupVariable( 103 LocalVariable* async_op = preamble_->scope()->LookupVariable(
100 Symbols::AsyncOperation(), false); 104 Symbols::AsyncOperation(), false);
101 ASSERT(async_op != NULL); 105 ASSERT(async_op != NULL);
102 LocalVariable* result_param = preamble_->scope()->LookupVariable( 106 LocalVariable* result_param = preamble_->scope()->LookupVariable(
103 Symbols::AsyncOperationParam(), false); 107 Symbols::AsyncOperationParam(), false);
104 ASSERT(result_param != NULL); 108 ASSERT(result_param != NULL);
105 109
106 node->expr()->Visit(this); 110 node->expr()->Visit(this);
107 preamble_->Add(new(I) StoreLocalNode(Scanner::kNoSourcePos, 111 preamble_->Add(new(I) StoreLocalNode(
108 result_param, 112 Scanner::kNoSourcePos, result_param, result_));
109 result_));
110 LoadLocalNode* load_result_param = new(I) LoadLocalNode( 113 LoadLocalNode* load_result_param = new(I) LoadLocalNode(
111 Scanner::kNoSourcePos, result_param); 114 Scanner::kNoSourcePos, result_param);
112 SequenceNode* is_future_branch = new(I) SequenceNode( 115 SequenceNode* is_future_branch = new(I) SequenceNode(
113 Scanner::kNoSourcePos, preamble_->scope()); 116 Scanner::kNoSourcePos, preamble_->scope());
117 AwaitMarkerNode* await_marker =
118 new(I) AwaitMarkerNode(AwaitMarkerNode::kNewContinuationState);
119 await_marker->set_scope(preamble_->scope());
120 is_future_branch->Add(await_marker);
114 ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos); 121 ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos);
115 args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op)); 122 args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op));
116 // TODO(mlippautz): Once continuations are supported, just call .then(). 123 is_future_branch->Add(new(I) InstanceCallNode(
117 // is_future_branch->Add(new(I) InstanceCallNode( 124 Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args));
118 // Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args)); 125 ReturnNode* continuation_return = new(I) ReturnNode(Scanner::kNoSourcePos);
119 // 126 continuation_return->set_return_type(ReturnNode::kContinuation);
120 // For now, throw an exception. 127 is_future_branch->Add(continuation_return);
121 const String& exception = String::ZoneHandle( 128
122 I, String::New("awaitable futures not yet supported", Heap::kOld));
123 is_future_branch->Add(new(I) ThrowNode(
124 Scanner::kNoSourcePos,
125 new(I) LiteralNode(
126 Scanner::kNoSourcePos,
127 String::ZoneHandle(I, Symbols::New(exception))),
128 NULL));
129 const Class& cls = Class::ZoneHandle( 129 const Class& cls = Class::ZoneHandle(
130 I, library_.LookupClass(Symbols::Future())); 130 I, library_.LookupClass(Symbols::Future()));
131 const AbstractType& future_type = AbstractType::ZoneHandle(I, 131 const AbstractType& future_type = AbstractType::ZoneHandle(I, cls.RareType());
132 cls.RareType());
133 ASSERT(!future_type.IsNull()); 132 ASSERT(!future_type.IsNull());
134 TypeNode* future_type_node = new(I) TypeNode( 133 preamble_->Add(new(I) IfNode(
135 Scanner::kNoSourcePos, future_type);
136 IfNode* is_future_if = new(I) IfNode(
137 Scanner::kNoSourcePos, 134 Scanner::kNoSourcePos,
138 new(I) ComparisonNode(Scanner::kNoSourcePos, 135 new (I) ComparisonNode(
139 Token::kIS, 136 Scanner::kNoSourcePos,
140 load_result_param, 137 Token::kIS,
141 future_type_node), 138 load_result_param,
139 new (I) TypeNode(Scanner::kNoSourcePos, future_type)),
142 is_future_branch, 140 is_future_branch,
143 NULL); 141 NULL));
144 preamble_->Add(is_future_if); 142 preamble_->Add(new (I) AwaitMarkerNode(
145 143 AwaitMarkerNode::kTargetForContinuation));
146 // TODO(mlippautz): Join for await needs to happen here. 144 // If this expression is part of a try block, also append the code for
145 // restoring the saved try context that lives on the stack.
146 if (parsed_function_->saved_try_ctx() != NULL) {
147 preamble_->Add(new (I) StoreLocalNode(
148 Scanner::kNoSourcePos,
149 parsed_function_->saved_try_ctx(),
150 new (I) LoadLocalNode(
151 Scanner::kNoSourcePos, parsed_function_->async_saved_try_ctx())));
152 }
147 153
148 LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode( 154 LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode(
149 Scanner::kNoSourcePos, result_param)); 155 Scanner::kNoSourcePos, result_param));
150 result_ = new(I) LoadLocalNode(Scanner::kNoSourcePos, result); 156 result_ = new(I) LoadLocalNode(Scanner::kNoSourcePos, result);
151 } 157 }
152 158
153 159
154 // Transforms boolean expressions into a sequence of evaluatons that only lazily 160 // Transforms boolean expressions into a sequence of evaluatons that only lazily
155 // evaluate subexpressions. 161 // evaluate subexpressions.
156 // 162 //
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { 505 void AwaitTransformer::VisitThrowNode(ThrowNode* node) {
500 // TODO(mlippautz): Check if relevant. 506 // TODO(mlippautz): Check if relevant.
501 AstNode* new_exception = Transform(node->exception()); 507 AstNode* new_exception = Transform(node->exception());
502 AstNode* new_stacktrace = Transform(node->stacktrace()); 508 AstNode* new_stacktrace = Transform(node->stacktrace());
503 result_ = new(I) ThrowNode(node->token_pos(), 509 result_ = new(I) ThrowNode(node->token_pos(),
504 new_exception, 510 new_exception,
505 new_stacktrace); 511 new_stacktrace);
506 } 512 }
507 513
508 } // namespace dart 514 } // namespace dart
OLDNEW
« 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