OLD | NEW |
---|---|
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 Loading... | |
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); |
hausner
2014/08/20 21:42:53
This does not compile, right? Should be a capital
Michael Lippautz (Google)
2014/08/21 16:39:14
Fixed in the comment.
| |
96 // :result_param.then(:async_op); | |
97 // return; // (is_regular_return() == false) | |
96 // } | 98 // } |
97 // :await_temp_var_(X+1) = :result_param; | 99 // :await_temp_var_(X+1) = :result_param; |
98 | 100 |
99 LocalVariable* async_op = preamble_->scope()->LookupVariable( | 101 LocalVariable* async_op = preamble_->scope()->LookupVariable( |
100 Symbols::AsyncOperation(), false); | 102 Symbols::AsyncOperation(), false); |
101 ASSERT(async_op != NULL); | 103 ASSERT(async_op != NULL); |
102 LocalVariable* result_param = preamble_->scope()->LookupVariable( | 104 LocalVariable* result_param = preamble_->scope()->LookupVariable( |
103 Symbols::AsyncOperationParam(), false); | 105 Symbols::AsyncOperationParam(), false); |
104 ASSERT(result_param != NULL); | 106 ASSERT(result_param != NULL); |
105 | 107 |
106 node->expr()->Visit(this); | 108 node->expr()->Visit(this); |
107 preamble_->Add(new(I) StoreLocalNode(Scanner::kNoSourcePos, | 109 preamble_->Add(new(I) StoreLocalNode( |
108 result_param, | 110 Scanner::kNoSourcePos, result_param, result_)); |
109 result_)); | |
110 LoadLocalNode* load_result_param = new(I) LoadLocalNode( | 111 LoadLocalNode* load_result_param = new(I) LoadLocalNode( |
111 Scanner::kNoSourcePos, result_param); | 112 Scanner::kNoSourcePos, result_param); |
112 SequenceNode* is_future_branch = new(I) SequenceNode( | 113 SequenceNode* is_future_branch = new(I) SequenceNode( |
113 Scanner::kNoSourcePos, preamble_->scope()); | 114 Scanner::kNoSourcePos, preamble_->scope()); |
115 AwaitMarkerNode* await_marker = | |
116 new(I) AwaitMarkerNode(AwaitMarkerNode::kNewContinuationState); | |
117 await_marker->set_scope(preamble_->scope()); | |
118 is_future_branch->Add(await_marker); | |
114 ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos); | 119 ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos); |
115 args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op)); | 120 args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op)); |
116 // TODO(mlippautz): Once continuations are supported, just call .then(). | 121 is_future_branch->Add(new(I) InstanceCallNode( |
117 // is_future_branch->Add(new(I) InstanceCallNode( | 122 Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args)); |
118 // Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args)); | 123 ReturnNode* continuation_return = new(I) ReturnNode(Scanner::kNoSourcePos); |
119 // | 124 continuation_return->set_type(ReturnNode::kContinuation); |
120 // For now, throw an exception. | 125 is_future_branch->Add(continuation_return); |
121 const String& exception = String::ZoneHandle( | 126 |
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( | 127 const Class& cls = Class::ZoneHandle( |
130 I, library_.LookupClass(Symbols::Future())); | 128 I, library_.LookupClass(Symbols::Future())); |
131 const AbstractType& future_type = AbstractType::ZoneHandle(I, | 129 const AbstractType& future_type = AbstractType::ZoneHandle(I, |
132 cls.RareType()); | 130 cls.RareType()); |
133 ASSERT(!future_type.IsNull()); | 131 ASSERT(!future_type.IsNull()); |
134 TypeNode* future_type_node = new(I) TypeNode( | 132 preamble_->Add(new(I) IfNode( |
135 Scanner::kNoSourcePos, future_type); | |
136 IfNode* is_future_if = new(I) IfNode( | |
137 Scanner::kNoSourcePos, | 133 Scanner::kNoSourcePos, |
138 new(I) ComparisonNode(Scanner::kNoSourcePos, | 134 new(I) ComparisonNode(Scanner::kNoSourcePos, |
139 Token::kIS, | 135 Token::kIS, |
140 load_result_param, | 136 load_result_param, |
141 future_type_node), | 137 new(I) TypeNode(Scanner::kNoSourcePos, |
138 future_type)), | |
142 is_future_branch, | 139 is_future_branch, |
143 NULL); | 140 NULL)); |
144 preamble_->Add(is_future_if); | 141 preamble_->Add(new(I) AwaitMarkerNode( |
145 | 142 AwaitMarkerNode::kTargetForContinuation)); |
146 // TODO(mlippautz): Join for await needs to happen here. | |
147 | 143 |
148 LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode( | 144 LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode( |
149 Scanner::kNoSourcePos, result_param)); | 145 Scanner::kNoSourcePos, result_param)); |
150 result_ = new(I) LoadLocalNode(Scanner::kNoSourcePos, result); | 146 result_ = new(I) LoadLocalNode(Scanner::kNoSourcePos, result); |
151 } | 147 } |
152 | 148 |
153 | 149 |
154 // Transforms boolean expressions into a sequence of evaluatons that only lazily | 150 // Transforms boolean expressions into a sequence of evaluatons that only lazily |
155 // evaluate subexpressions. | 151 // evaluate subexpressions. |
156 // | 152 // |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { | 495 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { |
500 // TODO(mlippautz): Check if relevant. | 496 // TODO(mlippautz): Check if relevant. |
501 AstNode* new_exception = Transform(node->exception()); | 497 AstNode* new_exception = Transform(node->exception()); |
502 AstNode* new_stacktrace = Transform(node->stacktrace()); | 498 AstNode* new_stacktrace = Transform(node->stacktrace()); |
503 result_ = new(I) ThrowNode(node->token_pos(), | 499 result_ = new(I) ThrowNode(node->token_pos(), |
504 new_exception, | 500 new_exception, |
505 new_stacktrace); | 501 new_stacktrace); |
506 } | 502 } |
507 | 503 |
508 } // namespace dart | 504 } // namespace dart |
OLD | NEW |