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

Side by Side Diff: runtime/vm/ast_transformer.cc

Issue 1589643002: Source positions for constructors and lots of async machinery (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/class_finalizer_test.cc » ('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/object_store.h" 7 #include "vm/object_store.h"
8 #include "vm/parser.h" 8 #include "vm/parser.h"
9 #include "vm/thread.h" 9 #include "vm/thread.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 // Quick access to the current zone. 13 // Quick access to the current zone.
14 #define Z (thread()->zone()) 14 #define Z (thread()->zone())
15 15
16 // Quick synthetic token position.
17 #define ST(token_pos) Token::ToSynthetic(token_pos)
18
16 // Nodes that are unreachable from already parsed expressions. 19 // Nodes that are unreachable from already parsed expressions.
17 #define FOR_EACH_UNREACHABLE_NODE(V) \ 20 #define FOR_EACH_UNREACHABLE_NODE(V) \
18 V(AwaitMarker) \ 21 V(AwaitMarker) \
19 V(Case) \ 22 V(Case) \
20 V(CatchClause) \ 23 V(CatchClause) \
21 V(CloneContext) \ 24 V(CloneContext) \
22 V(ClosureCall) \ 25 V(ClosureCall) \
23 V(DoWhile) \ 26 V(DoWhile) \
24 V(If) \ 27 V(If) \
25 V(InitStaticField) \ 28 V(InitStaticField) \
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 LocalVariable* AwaitTransformer::EnsureCurrentTempVar() { 67 LocalVariable* AwaitTransformer::EnsureCurrentTempVar() {
65 String& symbol = 68 String& symbol =
66 String::ZoneHandle(Z, Symbols::NewFormatted("%d", temp_cnt_)); 69 String::ZoneHandle(Z, Symbols::NewFormatted("%d", temp_cnt_));
67 symbol = Symbols::FromConcat(Symbols::AwaitTempVarPrefix(), symbol); 70 symbol = Symbols::FromConcat(Symbols::AwaitTempVarPrefix(), symbol);
68 ASSERT(!symbol.IsNull()); 71 ASSERT(!symbol.IsNull());
69 // Look up the variable in the scope used for async temp variables. 72 // Look up the variable in the scope used for async temp variables.
70 LocalVariable* await_tmp = async_temp_scope_->LocalLookupVariable(symbol); 73 LocalVariable* await_tmp = async_temp_scope_->LocalLookupVariable(symbol);
71 if (await_tmp == NULL) { 74 if (await_tmp == NULL) {
72 // We need a new temp variable; add it to the function's top scope. 75 // We need a new temp variable; add it to the function's top scope.
73 await_tmp = new (Z) LocalVariable( 76 await_tmp = new (Z) LocalVariable(
74 Scanner::kNoSourcePos, symbol, Object::dynamic_type()); 77 Token::kNoSourcePos, symbol, Object::dynamic_type());
75 async_temp_scope_->AddVariable(await_tmp); 78 async_temp_scope_->AddVariable(await_tmp);
76 // After adding it to the top scope, we can look it up from the preamble. 79 // After adding it to the top scope, we can look it up from the preamble.
77 // The following call includes an ASSERT check. 80 // The following call includes an ASSERT check.
78 await_tmp = GetVariableInScope(preamble_->scope(), symbol); 81 await_tmp = GetVariableInScope(preamble_->scope(), symbol);
79 } 82 }
80 return await_tmp; 83 return await_tmp;
81 } 84 }
82 85
83 86
84 LocalVariable* AwaitTransformer::GetVariableInScope(LocalScope* scope, 87 LocalVariable* AwaitTransformer::GetVariableInScope(LocalScope* scope,
85 const String& symbol) { 88 const String& symbol) {
86 LocalVariable* var = scope->LookupVariable(symbol, false); 89 LocalVariable* var = scope->LookupVariable(symbol, false);
87 ASSERT(var != NULL); 90 ASSERT(var != NULL);
88 return var; 91 return var;
89 } 92 }
90 93
91 94
92 LocalVariable* AwaitTransformer::AddToPreambleNewTempVar(AstNode* node) { 95 LocalVariable* AwaitTransformer::AddToPreambleNewTempVar(AstNode* node,
96 intptr_t token_pos) {
93 LocalVariable* tmp_var = EnsureCurrentTempVar(); 97 LocalVariable* tmp_var = EnsureCurrentTempVar();
94 preamble_->Add(new(Z) StoreLocalNode(Scanner::kNoSourcePos, tmp_var, node)); 98 ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos));
99 preamble_->Add(new(Z) StoreLocalNode(token_pos, tmp_var, node));
95 NextTempVar(); 100 NextTempVar();
96 return tmp_var; 101 return tmp_var;
97 } 102 }
98 103
99 104
100 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { 105 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) {
101 result_ = node; 106 result_ = node;
102 } 107 }
103 108
104 109
105 void AwaitTransformer::VisitTypeNode(TypeNode* node) { 110 void AwaitTransformer::VisitTypeNode(TypeNode* node) {
106 result_ = new(Z) TypeNode(node->token_pos(), node->type()); 111 result_ = new(Z) TypeNode(node->token_pos(), node->type());
107 } 112 }
108 113
109 114
110 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { 115 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) {
111 // Await transformation: 116 // Await transformation:
112 // 117 //
113 // :await_temp_var_X = <expr>; 118 // :await_temp_var_X = <expr>;
114 // AwaitMarker(kNewContinuationState); 119 // AwaitMarker(kNewContinuationState);
115 // :result_param = _awaitHelper( 120 // :result_param = _awaitHelper(
116 // :await_temp_var_X, :async_then_callback, :async_catch_error_callback); 121 // :await_temp_var_X, :async_then_callback, :async_catch_error_callback);
117 // return; // (return_type() == kContinuationTarget) 122 // return; // (return_type() == kContinuationTarget)
118 // 123 //
119 // :saved_try_ctx_var = :await_saved_try_ctx_var_y; 124 // :saved_try_ctx_var = :await_saved_try_ctx_var_y;
120 // :await_temp_var_(X+1) = :result_param; 125 // :await_temp_var_(X+1) = :result_param;
121 126
122 const intptr_t token_pos = node->token_pos(); 127 const intptr_t token_pos = ST(node->token_pos());
123 LocalVariable* async_op = GetVariableInScope( 128 LocalVariable* async_op = GetVariableInScope(
124 preamble_->scope(), Symbols::AsyncOperation()); 129 preamble_->scope(), Symbols::AsyncOperation());
125 LocalVariable* async_then_callback = GetVariableInScope( 130 LocalVariable* async_then_callback = GetVariableInScope(
126 preamble_->scope(), Symbols::AsyncThenCallback()); 131 preamble_->scope(), Symbols::AsyncThenCallback());
127 LocalVariable* async_catch_error_callback = GetVariableInScope( 132 LocalVariable* async_catch_error_callback = GetVariableInScope(
128 preamble_->scope(), Symbols::AsyncCatchErrorCallback()); 133 preamble_->scope(), Symbols::AsyncCatchErrorCallback());
129 LocalVariable* result_param = GetVariableInScope( 134 LocalVariable* result_param = GetVariableInScope(
130 preamble_->scope(), Symbols::AsyncOperationParam()); 135 preamble_->scope(), Symbols::AsyncOperationParam());
131 LocalVariable* error_param = GetVariableInScope( 136 LocalVariable* error_param = GetVariableInScope(
132 preamble_->scope(), Symbols::AsyncOperationErrorParam()); 137 preamble_->scope(), Symbols::AsyncOperationErrorParam());
133 LocalVariable* stack_trace_param = GetVariableInScope( 138 LocalVariable* stack_trace_param = GetVariableInScope(
134 preamble_->scope(), Symbols::AsyncOperationStackTraceParam()); 139 preamble_->scope(), Symbols::AsyncOperationStackTraceParam());
135 140
136 AstNode* transformed_expr = Transform(node->expr()); 141 AstNode* transformed_expr = Transform(node->expr());
137 LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr); 142 LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr,
143 ST(node->token_pos()));
138 144
139 AwaitMarkerNode* await_marker = 145 AwaitMarkerNode* await_marker =
140 new (Z) AwaitMarkerNode(async_temp_scope_, node->scope(), token_pos); 146 new (Z) AwaitMarkerNode(async_temp_scope_, node->scope(), token_pos);
141 preamble_->Add(await_marker); 147 preamble_->Add(await_marker);
142 148
143 // :result_param = _awaitHelper( 149 // :result_param = _awaitHelper(
144 // :await_temp, :async_then_callback, :async_catch_error_callback) 150 // :await_temp, :async_then_callback, :async_catch_error_callback)
145 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); 151 const Library& async_lib = Library::Handle(Library::AsyncLibrary());
146 const Function& async_await_helper = Function::ZoneHandle( 152 const Function& async_await_helper = Function::ZoneHandle(
147 Z, async_lib.LookupFunctionAllowPrivate(Symbols::AsyncAwaitHelper())); 153 Z, async_lib.LookupFunctionAllowPrivate(Symbols::AsyncAwaitHelper()));
148 ASSERT(!async_await_helper.IsNull()); 154 ASSERT(!async_await_helper.IsNull());
149 ArgumentListNode* async_await_helper_args = new (Z) ArgumentListNode( 155 ArgumentListNode* async_await_helper_args =
150 Scanner::kNoSourcePos); 156 new (Z) ArgumentListNode(token_pos);
151 async_await_helper_args->Add( 157 async_await_helper_args->Add(
152 new(Z) LoadLocalNode(Scanner::kNoSourcePos, await_temp)); 158 new(Z) LoadLocalNode(token_pos, await_temp));
153 async_await_helper_args->Add( 159 async_await_helper_args->Add(
154 new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_then_callback)); 160 new(Z) LoadLocalNode(token_pos, async_then_callback));
155 async_await_helper_args->Add( 161 async_await_helper_args->Add(
156 new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_catch_error_callback)); 162 new(Z) LoadLocalNode(token_pos, async_catch_error_callback));
157 StaticCallNode* await_helper_call = new (Z) StaticCallNode( 163 StaticCallNode* await_helper_call = new (Z) StaticCallNode(
158 node->token_pos(), 164 node->token_pos(),
159 async_await_helper, 165 async_await_helper,
160 async_await_helper_args); 166 async_await_helper_args);
161 167
162 preamble_->Add(new(Z) StoreLocalNode( 168 preamble_->Add(new(Z) StoreLocalNode(
163 Scanner::kNoSourcePos, result_param, await_helper_call)); 169 token_pos, result_param, await_helper_call));
164 170
165 ReturnNode* continuation_return = new(Z) ReturnNode(Scanner::kNoSourcePos); 171 ReturnNode* continuation_return = new(Z) ReturnNode(token_pos);
166 continuation_return->set_return_type(ReturnNode::kContinuationTarget); 172 continuation_return->set_return_type(ReturnNode::kContinuationTarget);
167 preamble_->Add(continuation_return); 173 preamble_->Add(continuation_return);
168 174
169 // If this expression is part of a try block, also append the code for 175 // If this expression is part of a try block, also append the code for
170 // restoring the saved try context that lives on the stack and possibly the 176 // restoring the saved try context that lives on the stack and possibly the
171 // saved try context of the outer try block. 177 // saved try context of the outer try block.
172 if (node->saved_try_ctx() != NULL) { 178 if (node->saved_try_ctx() != NULL) {
173 preamble_->Add(new (Z) StoreLocalNode( 179 preamble_->Add(new (Z) StoreLocalNode(
174 Scanner::kNoSourcePos, 180 token_pos,
175 node->saved_try_ctx(), 181 node->saved_try_ctx(),
176 new (Z) LoadLocalNode(Scanner::kNoSourcePos, 182 new (Z) LoadLocalNode(token_pos,
177 node->async_saved_try_ctx()))); 183 node->async_saved_try_ctx())));
178 if (node->outer_saved_try_ctx() != NULL) { 184 if (node->outer_saved_try_ctx() != NULL) {
179 preamble_->Add(new (Z) StoreLocalNode( 185 preamble_->Add(new (Z) StoreLocalNode(
180 Scanner::kNoSourcePos, 186 token_pos,
181 node->outer_saved_try_ctx(), 187 node->outer_saved_try_ctx(),
182 new (Z) LoadLocalNode(Scanner::kNoSourcePos, 188 new (Z) LoadLocalNode(token_pos,
183 node->outer_async_saved_try_ctx()))); 189 node->outer_async_saved_try_ctx())));
184 } 190 }
185 } else { 191 } else {
186 ASSERT(node->outer_saved_try_ctx() == NULL); 192 ASSERT(node->outer_saved_try_ctx() == NULL);
187 } 193 }
188 194
189 // Load the async_op variable. It is unused, but the observatory uses it 195 // Load the async_op variable. It is unused, but the observatory uses it
190 // to determine if a breakpoint is inside an asynchronous function. 196 // to determine if a breakpoint is inside an asynchronous function.
191 LoadLocalNode* load_async_op = new (Z) LoadLocalNode( 197 LoadLocalNode* load_async_op = new (Z) LoadLocalNode(token_pos, async_op);
192 Scanner::kNoSourcePos, async_op);
193 preamble_->Add(load_async_op); 198 preamble_->Add(load_async_op);
194 199
195 LoadLocalNode* load_error_param = new (Z) LoadLocalNode( 200 LoadLocalNode* load_error_param = new (Z) LoadLocalNode(
196 Scanner::kNoSourcePos, error_param); 201 token_pos, error_param);
197 LoadLocalNode* load_stack_trace_param = new (Z) LoadLocalNode( 202 LoadLocalNode* load_stack_trace_param = new (Z) LoadLocalNode(
198 Scanner::kNoSourcePos, stack_trace_param); 203 token_pos, stack_trace_param);
199 SequenceNode* error_ne_null_branch = new (Z) SequenceNode( 204 SequenceNode* error_ne_null_branch = new (Z) SequenceNode(
200 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); 205 token_pos, ChainNewScope(preamble_->scope()));
201 error_ne_null_branch->Add(new (Z) ThrowNode( 206 error_ne_null_branch->Add(new (Z) ThrowNode(
202 Scanner::kNoSourcePos, 207 token_pos,
203 load_error_param, 208 load_error_param,
204 load_stack_trace_param)); 209 load_stack_trace_param));
205 preamble_->Add(new (Z) IfNode( 210 preamble_->Add(new (Z) IfNode(
206 Scanner::kNoSourcePos, 211 token_pos,
207 new (Z) ComparisonNode( 212 new (Z) ComparisonNode(
208 Scanner::kNoSourcePos, 213 token_pos,
209 Token::kNE, 214 Token::kNE,
210 load_error_param, 215 load_error_param,
211 new (Z) LiteralNode(Scanner::kNoSourcePos, 216 new (Z) LiteralNode(token_pos,
212 Object::null_instance())), 217 Object::null_instance())),
213 error_ne_null_branch, 218 error_ne_null_branch,
214 NULL)); 219 NULL));
215 220
216 LocalVariable* result = AddToPreambleNewTempVar(new(Z) LoadLocalNode( 221 LocalVariable* result = AddToPreambleNewTempVar(new(Z) LoadLocalNode(
217 Scanner::kNoSourcePos, result_param)); 222 token_pos, result_param), ST(node->token_pos()));
218 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 223 result_ = new(Z) LoadLocalNode(token_pos, result);
219 } 224 }
220 225
221 226
222 // Transforms boolean expressions into a sequence of evaluatons that only lazily 227 // Transforms boolean expressions into a sequence of evaluatons that only lazily
223 // evaluate subexpressions. 228 // evaluate subexpressions.
224 // 229 //
225 // Example: 230 // Example:
226 // 231 //
227 // (a || b) only evaluates b if a is false 232 // (a || b) only evaluates b if a is false
228 // 233 //
229 // Transformation (roughly): 234 // Transformation (roughly):
230 // 235 //
231 // t_1 = a; 236 // t_1 = a;
232 // if (!t_1) { 237 // if (!t_1) {
233 // t_2 = b; 238 // t_2 = b;
234 // } 239 // }
235 // t_3 = t_1 || t_2; // Compiler takes care that lazy evaluation takes place 240 // t_3 = t_1 || t_2; // Compiler takes care that lazy evaluation takes place
236 // on this level. 241 // on this level.
237 AstNode* AwaitTransformer::LazyTransform(const Token::Kind logical_op, 242 AstNode* AwaitTransformer::LazyTransform(const Token::Kind logical_op,
238 AstNode* new_left, 243 AstNode* new_left,
239 AstNode* right) { 244 AstNode* right) {
240 ASSERT(logical_op == Token::kAND || logical_op == Token::kOR); 245 ASSERT(logical_op == Token::kAND || logical_op == Token::kOR);
241 AstNode* result = NULL; 246 AstNode* result = NULL;
242 const Token::Kind compare_logical_op = (logical_op == Token::kAND) ? 247 const Token::Kind compare_logical_op = (logical_op == Token::kAND) ?
243 Token::kEQ : Token::kNE; 248 Token::kEQ : Token::kNE;
244 SequenceNode* eval = new (Z) SequenceNode( 249 SequenceNode* eval = new (Z) SequenceNode(
245 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); 250 ST(new_left->token_pos()), ChainNewScope(preamble_->scope()));
246 SequenceNode* saved_preamble = preamble_; 251 SequenceNode* saved_preamble = preamble_;
247 preamble_ = eval; 252 preamble_ = eval;
248 result = Transform(right); 253 result = Transform(right);
249 preamble_ = saved_preamble; 254 preamble_ = saved_preamble;
250 IfNode* right_body = new(Z) IfNode( 255 IfNode* right_body = new(Z) IfNode(
251 Scanner::kNoSourcePos, 256 ST(new_left->token_pos()),
252 new(Z) ComparisonNode( 257 new(Z) ComparisonNode(
253 Scanner::kNoSourcePos, 258 ST(new_left->token_pos()),
254 compare_logical_op, 259 compare_logical_op,
255 new_left, 260 new_left,
256 new(Z) LiteralNode(Scanner::kNoSourcePos, Bool::True())), 261 new(Z) LiteralNode(ST(new_left->token_pos()), Bool::True())),
257 eval, 262 eval,
258 NULL); 263 NULL);
259 preamble_->Add(right_body); 264 preamble_->Add(right_body);
260 return result; 265 return result;
261 } 266 }
262 267
263 268
264 LocalScope* AwaitTransformer::ChainNewScope(LocalScope* parent) { 269 LocalScope* AwaitTransformer::ChainNewScope(LocalScope* parent) {
265 return new (Z) LocalScope( 270 return new (Z) LocalScope(
266 parent, parent->function_level(), parent->loop_level()); 271 parent, parent->function_level(), parent->loop_level());
267 } 272 }
268 273
269 274
270 void AwaitTransformer::VisitBinaryOpNode(BinaryOpNode* node) { 275 void AwaitTransformer::VisitBinaryOpNode(BinaryOpNode* node) {
271 AstNode* new_left = Transform(node->left()); 276 AstNode* new_left = Transform(node->left());
272 AstNode* new_right = NULL; 277 AstNode* new_right = NULL;
273 // Preserve lazy evaluaton. 278 // Preserve lazy evaluaton.
274 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 279 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
275 new_right = LazyTransform(node->kind(), new_left, node->right()); 280 new_right = LazyTransform(node->kind(), new_left, node->right());
276 } else { 281 } else {
277 new_right = Transform(node->right()); 282 new_right = Transform(node->right());
278 } 283 }
279 LocalVariable* result = AddToPreambleNewTempVar( 284 LocalVariable* result = AddToPreambleNewTempVar(
280 new(Z) BinaryOpNode(node->token_pos(), 285 new(Z) BinaryOpNode(node->token_pos(),
281 node->kind(), 286 node->kind(),
282 new_left, 287 new_left,
283 new_right)); 288 new_right), ST(node->token_pos()));
284 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 289 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
285 } 290 }
286 291
287 292
288 void AwaitTransformer::VisitBinaryOpWithMask32Node( 293 void AwaitTransformer::VisitBinaryOpWithMask32Node(
289 BinaryOpWithMask32Node* node) { 294 BinaryOpWithMask32Node* node) {
290 ASSERT((node->kind() != Token::kAND) && (node->kind() != Token::kOR)); 295 ASSERT((node->kind() != Token::kAND) && (node->kind() != Token::kOR));
291 AstNode* new_left = Transform(node->left()); 296 AstNode* new_left = Transform(node->left());
292 AstNode* new_right = Transform(node->right()); 297 AstNode* new_right = Transform(node->right());
293 LocalVariable* result = AddToPreambleNewTempVar( 298 LocalVariable* result = AddToPreambleNewTempVar(
294 new(Z) BinaryOpWithMask32Node(node->token_pos(), 299 new(Z) BinaryOpWithMask32Node(node->token_pos(),
295 node->kind(), 300 node->kind(),
296 new_left, 301 new_left,
297 new_right, 302 new_right,
298 node->mask32())); 303 node->mask32()), ST(node->token_pos()));
299 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 304 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
300 } 305 }
301 306
302 307
303 void AwaitTransformer::VisitComparisonNode(ComparisonNode* node) { 308 void AwaitTransformer::VisitComparisonNode(ComparisonNode* node) {
304 AstNode* new_left = Transform(node->left()); 309 AstNode* new_left = Transform(node->left());
305 AstNode* new_right = Transform(node->right()); 310 AstNode* new_right = Transform(node->right());
306 LocalVariable* result = AddToPreambleNewTempVar( 311 LocalVariable* result = AddToPreambleNewTempVar(
307 new(Z) ComparisonNode(node->token_pos(), 312 new(Z) ComparisonNode(node->token_pos(),
308 node->kind(), 313 node->kind(),
309 new_left, 314 new_left,
310 new_right)); 315 new_right), ST(node->token_pos()));
311 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 316 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
312 } 317 }
313 318
314 319
315 void AwaitTransformer::VisitUnaryOpNode(UnaryOpNode* node) { 320 void AwaitTransformer::VisitUnaryOpNode(UnaryOpNode* node) {
316 AstNode* new_operand = Transform(node->operand()); 321 AstNode* new_operand = Transform(node->operand());
317 LocalVariable* result = AddToPreambleNewTempVar( 322 LocalVariable* result = AddToPreambleNewTempVar(
318 new(Z) UnaryOpNode(node->token_pos(), node->kind(), new_operand)); 323 new(Z) UnaryOpNode(node->token_pos(), node->kind(), new_operand),
319 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 324 ST(node->token_pos()));
325 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
320 } 326 }
321 327
322 328
323 // ::= (<condition>) ? <true-branch> : <false-branch> 329 // ::= (<condition>) ? <true-branch> : <false-branch>
324 // 330 //
325 void AwaitTransformer::VisitConditionalExprNode(ConditionalExprNode* node) { 331 void AwaitTransformer::VisitConditionalExprNode(ConditionalExprNode* node) {
326 AstNode* new_condition = Transform(node->condition()); 332 AstNode* new_condition = Transform(node->condition());
327 SequenceNode* new_true = new (Z) SequenceNode( 333 SequenceNode* new_true = new (Z) SequenceNode(
328 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); 334 ST(node->true_expr()->token_pos()), ChainNewScope(preamble_->scope()));
329 SequenceNode* saved_preamble = preamble_; 335 SequenceNode* saved_preamble = preamble_;
330 preamble_ = new_true; 336 preamble_ = new_true;
331 AstNode* new_true_result = Transform(node->true_expr()); 337 AstNode* new_true_result = Transform(node->true_expr());
332 SequenceNode* new_false = new (Z) SequenceNode( 338 SequenceNode* new_false = new (Z) SequenceNode(
333 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); 339 ST(node->false_expr()->token_pos()), ChainNewScope(preamble_->scope()));
334 preamble_ = new_false; 340 preamble_ = new_false;
335 AstNode* new_false_result = Transform(node->false_expr()); 341 AstNode* new_false_result = Transform(node->false_expr());
336 preamble_ = saved_preamble; 342 preamble_ = saved_preamble;
337 IfNode* new_if = new(Z) IfNode(Scanner::kNoSourcePos, 343 IfNode* new_if = new(Z) IfNode(ST(node->token_pos()),
338 new_condition, 344 new_condition,
339 new_true, 345 new_true,
340 new_false); 346 new_false);
341 preamble_->Add(new_if); 347 preamble_->Add(new_if);
342 LocalVariable* result = AddToPreambleNewTempVar( 348 LocalVariable* result = AddToPreambleNewTempVar(
343 new(Z) ConditionalExprNode(Scanner::kNoSourcePos, 349 new(Z) ConditionalExprNode(ST(node->token_pos()),
344 new_condition, 350 new_condition,
345 new_true_result, 351 new_true_result,
346 new_false_result)); 352 new_false_result), ST(node->token_pos()));
347 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 353 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
348 } 354 }
349 355
350 356
351 void AwaitTransformer::VisitArgumentListNode(ArgumentListNode* node) { 357 void AwaitTransformer::VisitArgumentListNode(ArgumentListNode* node) {
352 ArgumentListNode* new_args = new(Z) ArgumentListNode(node->token_pos()); 358 ArgumentListNode* new_args = new(Z) ArgumentListNode(node->token_pos());
353 for (intptr_t i = 0; i < node->length(); i++) { 359 for (intptr_t i = 0; i < node->length(); i++) {
354 new_args->Add(Transform(node->NodeAt(i))); 360 new_args->Add(Transform(node->NodeAt(i)));
355 } 361 }
356 new_args->set_names(node->names()); 362 new_args->set_names(node->names());
357 result_ = new_args; 363 result_ = new_args;
358 } 364 }
359 365
360 366
361 void AwaitTransformer::VisitArrayNode(ArrayNode* node) { 367 void AwaitTransformer::VisitArrayNode(ArrayNode* node) {
362 GrowableArray<AstNode*> new_elements; 368 GrowableArray<AstNode*> new_elements;
363 for (intptr_t i = 0; i < node->length(); i++) { 369 for (intptr_t i = 0; i < node->length(); i++) {
364 new_elements.Add(Transform(node->ElementAt(i))); 370 new_elements.Add(Transform(node->ElementAt(i)));
365 } 371 }
366 result_ = new(Z) ArrayNode(node->token_pos(), node->type(), new_elements); 372 result_ = new(Z) ArrayNode(node->token_pos(), node->type(), new_elements);
367 } 373 }
368 374
369 375
370 void AwaitTransformer::VisitStringInterpolateNode(StringInterpolateNode* node) { 376 void AwaitTransformer::VisitStringInterpolateNode(StringInterpolateNode* node) {
371 ArrayNode* new_value = Transform(node->value())->AsArrayNode(); 377 ArrayNode* new_value = Transform(node->value())->AsArrayNode();
372 LocalVariable* result = AddToPreambleNewTempVar( 378 LocalVariable* result = AddToPreambleNewTempVar(
373 new(Z) StringInterpolateNode(node->token_pos(), 379 new(Z) StringInterpolateNode(node->token_pos(),
374 new_value)); 380 new_value), ST(node->token_pos()));
375 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 381 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
376 } 382 }
377 383
378 384
379 void AwaitTransformer::VisitClosureNode(ClosureNode* node) { 385 void AwaitTransformer::VisitClosureNode(ClosureNode* node) {
380 AstNode* new_receiver = node->receiver(); 386 AstNode* new_receiver = node->receiver();
381 if (new_receiver != NULL) { 387 if (new_receiver != NULL) {
382 new_receiver = Transform(new_receiver); 388 new_receiver = Transform(new_receiver);
383 } 389 }
384 LocalVariable* result = AddToPreambleNewTempVar( 390 LocalVariable* result = AddToPreambleNewTempVar(
385 new(Z) ClosureNode(node->token_pos(), 391 new(Z) ClosureNode(node->token_pos(),
386 node->function(), 392 node->function(),
387 new_receiver, 393 new_receiver,
388 node->scope())); 394 node->scope()), ST(node->token_pos()));
389 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 395 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
390 } 396 }
391 397
392 398
393 void AwaitTransformer::VisitInstanceCallNode(InstanceCallNode* node) { 399 void AwaitTransformer::VisitInstanceCallNode(InstanceCallNode* node) {
394 AstNode* new_receiver = Transform(node->receiver()); 400 AstNode* new_receiver = Transform(node->receiver());
395 ArgumentListNode* new_args = 401 ArgumentListNode* new_args =
396 Transform(node->arguments())->AsArgumentListNode(); 402 Transform(node->arguments())->AsArgumentListNode();
397 LocalVariable* result = AddToPreambleNewTempVar( 403 LocalVariable* result = AddToPreambleNewTempVar(
398 new(Z) InstanceCallNode(node->token_pos(), 404 new(Z) InstanceCallNode(node->token_pos(),
399 new_receiver, 405 new_receiver,
400 node->function_name(), 406 node->function_name(),
401 new_args, 407 new_args,
402 node->is_conditional())); 408 node->is_conditional()), ST(node->token_pos()));
403 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 409 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
404 } 410 }
405 411
406 412
407 void AwaitTransformer::VisitStaticCallNode(StaticCallNode* node) { 413 void AwaitTransformer::VisitStaticCallNode(StaticCallNode* node) {
408 ArgumentListNode* new_args = 414 ArgumentListNode* new_args =
409 Transform(node->arguments())->AsArgumentListNode(); 415 Transform(node->arguments())->AsArgumentListNode();
410 LocalVariable* result = AddToPreambleNewTempVar( 416 LocalVariable* result = AddToPreambleNewTempVar(
411 new(Z) StaticCallNode(node->token_pos(), 417 new(Z) StaticCallNode(node->token_pos(),
412 node->function(), 418 node->function(),
413 new_args)); 419 new_args), ST(node->token_pos()));
414 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 420 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
415 } 421 }
416 422
417 423
418 void AwaitTransformer::VisitConstructorCallNode(ConstructorCallNode* node) { 424 void AwaitTransformer::VisitConstructorCallNode(ConstructorCallNode* node) {
419 ArgumentListNode* new_args = 425 ArgumentListNode* new_args =
420 Transform(node->arguments())->AsArgumentListNode(); 426 Transform(node->arguments())->AsArgumentListNode();
421 LocalVariable* result = AddToPreambleNewTempVar( 427 LocalVariable* result = AddToPreambleNewTempVar(
422 new(Z) ConstructorCallNode(node->token_pos(), 428 new(Z) ConstructorCallNode(node->token_pos(),
423 node->type_arguments(), 429 node->type_arguments(),
424 node->constructor(), 430 node->constructor(),
425 new_args)); 431 new_args), ST(node->token_pos()));
426 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 432 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
427 } 433 }
428 434
429 435
430 void AwaitTransformer::VisitInstanceGetterNode(InstanceGetterNode* node) { 436 void AwaitTransformer::VisitInstanceGetterNode(InstanceGetterNode* node) {
431 AstNode* new_receiver = Transform(node->receiver()); 437 AstNode* new_receiver = Transform(node->receiver());
432 LocalVariable* result = AddToPreambleNewTempVar( 438 LocalVariable* result = AddToPreambleNewTempVar(
433 new(Z) InstanceGetterNode(node->token_pos(), 439 new(Z) InstanceGetterNode(node->token_pos(),
434 new_receiver, 440 new_receiver,
435 node->field_name(), 441 node->field_name(),
436 node->is_conditional())); 442 node->is_conditional()), ST(node->token_pos()));
437 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 443 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
438 } 444 }
439 445
440 446
441 void AwaitTransformer::VisitInstanceSetterNode(InstanceSetterNode* node) { 447 void AwaitTransformer::VisitInstanceSetterNode(InstanceSetterNode* node) {
442 AstNode* new_receiver = node->receiver(); 448 AstNode* new_receiver = node->receiver();
443 if (new_receiver != NULL) { 449 if (new_receiver != NULL) {
444 new_receiver = Transform(new_receiver); 450 new_receiver = Transform(new_receiver);
445 } 451 }
446 AstNode* new_value = Transform(node->value()); 452 AstNode* new_value = Transform(node->value());
447 LocalVariable* result = AddToPreambleNewTempVar( 453 LocalVariable* result = AddToPreambleNewTempVar(
448 new(Z) InstanceSetterNode(node->token_pos(), 454 new(Z) InstanceSetterNode(node->token_pos(),
449 new_receiver, 455 new_receiver,
450 node->field_name(), 456 node->field_name(),
451 new_value, 457 new_value,
452 node->is_conditional())); 458 node->is_conditional()), ST(node->token_pos()));
453 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 459 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
454 } 460 }
455 461
456 462
457 void AwaitTransformer::VisitStaticGetterNode(StaticGetterNode* node) { 463 void AwaitTransformer::VisitStaticGetterNode(StaticGetterNode* node) {
458 AstNode* new_receiver = node->receiver(); 464 AstNode* new_receiver = node->receiver();
459 if (new_receiver != NULL) { 465 if (new_receiver != NULL) {
460 new_receiver = Transform(new_receiver); 466 new_receiver = Transform(new_receiver);
461 } 467 }
462 StaticGetterNode* new_getter = 468 StaticGetterNode* new_getter =
463 new(Z) StaticGetterNode(node->token_pos(), 469 new(Z) StaticGetterNode(node->token_pos(),
464 new_receiver, 470 new_receiver,
465 node->cls(), 471 node->cls(),
466 node->field_name()); 472 node->field_name());
467 new_getter->set_owner(node->owner()); 473 new_getter->set_owner(node->owner());
468 LocalVariable* result = AddToPreambleNewTempVar(new_getter); 474 LocalVariable* result =
469 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 475 AddToPreambleNewTempVar(new_getter, ST(node->token_pos()));
476 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
470 } 477 }
471 478
472 479
473 void AwaitTransformer::VisitStaticSetterNode(StaticSetterNode* node) { 480 void AwaitTransformer::VisitStaticSetterNode(StaticSetterNode* node) {
474 AstNode* new_receiver = node->receiver(); 481 AstNode* new_receiver = node->receiver();
475 if (new_receiver != NULL) { 482 if (new_receiver != NULL) {
476 new_receiver = Transform(new_receiver); 483 new_receiver = Transform(new_receiver);
477 } 484 }
478 AstNode* new_value = Transform(node->value()); 485 AstNode* new_value = Transform(node->value());
479 StaticSetterNode* new_setter = 486 StaticSetterNode* new_setter =
480 node->function().IsNull() 487 node->function().IsNull()
481 ? new(Z) StaticSetterNode(node->token_pos(), 488 ? new(Z) StaticSetterNode(node->token_pos(),
482 new_receiver, 489 new_receiver,
483 node->cls(), 490 node->cls(),
484 node->field_name(), 491 node->field_name(),
485 new_value) 492 new_value)
486 : new(Z) StaticSetterNode(node->token_pos(), 493 : new(Z) StaticSetterNode(node->token_pos(),
487 new_receiver, 494 new_receiver,
488 node->field_name(), 495 node->field_name(),
489 node->function(), 496 node->function(),
490 new_value); 497 new_value);
491 498
492 LocalVariable* result = AddToPreambleNewTempVar(new_setter); 499 LocalVariable* result =
493 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 500 AddToPreambleNewTempVar(new_setter, ST(node->token_pos()));
501 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
494 } 502 }
495 503
496 504
497 void AwaitTransformer::VisitLoadLocalNode(LoadLocalNode* node) { 505 void AwaitTransformer::VisitLoadLocalNode(LoadLocalNode* node) {
498 result_ = node; 506 result_ = node;
499 } 507 }
500 508
501 509
502 void AwaitTransformer::VisitStoreLocalNode(StoreLocalNode* node) { 510 void AwaitTransformer::VisitStoreLocalNode(StoreLocalNode* node) {
503 AstNode* new_value = Transform(node->value()); 511 AstNode* new_value = Transform(node->value());
(...skipping 14 matching lines...) Expand all
518 } 526 }
519 527
520 528
521 void AwaitTransformer::VisitLoadIndexedNode(LoadIndexedNode* node) { 529 void AwaitTransformer::VisitLoadIndexedNode(LoadIndexedNode* node) {
522 AstNode* new_array = Transform(node->array()); 530 AstNode* new_array = Transform(node->array());
523 AstNode* new_index = Transform(node->index_expr()); 531 AstNode* new_index = Transform(node->index_expr());
524 LocalVariable* result = AddToPreambleNewTempVar( 532 LocalVariable* result = AddToPreambleNewTempVar(
525 new(Z) LoadIndexedNode(node->token_pos(), 533 new(Z) LoadIndexedNode(node->token_pos(),
526 new_array, 534 new_array,
527 new_index, 535 new_index,
528 node->super_class())); 536 node->super_class()), ST(node->token_pos()));
529 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 537 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
530 } 538 }
531 539
532 540
533 void AwaitTransformer::VisitStoreIndexedNode(StoreIndexedNode* node) { 541 void AwaitTransformer::VisitStoreIndexedNode(StoreIndexedNode* node) {
534 AstNode* new_array = Transform(node->array()); 542 AstNode* new_array = Transform(node->array());
535 AstNode* new_index = Transform(node->index_expr()); 543 AstNode* new_index = Transform(node->index_expr());
536 AstNode* new_value = Transform(node->value()); 544 AstNode* new_value = Transform(node->value());
537 LocalVariable* result = AddToPreambleNewTempVar( 545 LocalVariable* result = AddToPreambleNewTempVar(
538 new(Z) StoreIndexedNode(node->token_pos(), 546 new(Z) StoreIndexedNode(node->token_pos(),
539 new_array, 547 new_array,
540 new_index, 548 new_index,
541 new_value, 549 new_value,
542 node->super_class())); 550 node->super_class()), ST(node->token_pos()));
543 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 551 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
544 } 552 }
545 553
546 554
547 void AwaitTransformer::VisitAssignableNode(AssignableNode* node) { 555 void AwaitTransformer::VisitAssignableNode(AssignableNode* node) {
548 AstNode* new_expr = Transform(node->expr()); 556 AstNode* new_expr = Transform(node->expr());
549 LocalVariable* result = AddToPreambleNewTempVar( 557 LocalVariable* result = AddToPreambleNewTempVar(
550 new(Z) AssignableNode(node->token_pos(), 558 new(Z) AssignableNode(node->token_pos(),
551 new_expr, 559 new_expr,
552 node->type(), 560 node->type(),
553 node->dst_name())); 561 node->dst_name()), ST(node->token_pos()));
554 result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result); 562 result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
555 } 563 }
556 564
557 565
558 void AwaitTransformer::VisitLetNode(LetNode* node) { 566 void AwaitTransformer::VisitLetNode(LetNode* node) {
559 // Add all the initializer nodes to the preamble and the 567 // Add all the initializer nodes to the preamble and the
560 // temporary variables to the scope for async temporary variables. 568 // temporary variables to the scope for async temporary variables.
561 // The temporary variables will be captured as a side effect of being 569 // The temporary variables will be captured as a side effect of being
562 // added to a scope, and the subsequent nodes that are added to the 570 // added to a scope, and the subsequent nodes that are added to the
563 // preample can access them. 571 // preample can access them.
564 for (intptr_t i = 0; i < node->num_temps(); i++) { 572 for (intptr_t i = 0; i < node->num_temps(); i++) {
565 async_temp_scope_->AddVariable(node->TempAt(i)); 573 async_temp_scope_->AddVariable(node->TempAt(i));
566 AstNode* new_init_val = Transform(node->InitializerAt(i)); 574 AstNode* new_init_val = Transform(node->InitializerAt(i));
567 preamble_->Add(new(Z) StoreLocalNode(node->token_pos(), 575 preamble_->Add(new(Z) StoreLocalNode(node->token_pos(),
568 node->TempAt(i), 576 node->TempAt(i),
569 new_init_val)); 577 new_init_val));
570 } 578 }
571 579
572 // Add all expressions but the last to the preamble. We must do 580 // Add all expressions but the last to the preamble. We must do
573 // this because subexpressions of the awaitable expression we 581 // this because subexpressions of the awaitable expression we
574 // are currently transforming may depend on each other, 582 // are currently transforming may depend on each other,
575 // e.g. await foo(a++, a++). Thus we must preserve the order of the 583 // e.g. await foo(a++, a++). Thus we must preserve the order of the
576 // transformed subexpressions. 584 // transformed subexpressions.
577 for (intptr_t i = 0; i < node->nodes().length() - 1; i++) { 585 for (intptr_t i = 0; i < node->nodes().length() - 1; i++) {
578 preamble_->Add(Transform(node->nodes()[i])); 586 preamble_->Add(Transform(node->nodes()[i]));
579 } 587 }
580 588
581 // The last expression in the let node is the value of the node. 589 // The last expression in the let node is the value of the node.
582 // The result of the transformed let node is this expression. 590 // The result of the transformed let node is this expression.
583 ASSERT(node->nodes().length() > 0); 591 ASSERT(node->nodes().length() > 0);
584 const intptr_t last_node_index = node->nodes().length() - 1; 592 const intptr_t last_node_index = node->nodes().length() - 1;
585 result_ = Transform(node->nodes()[last_node_index]); 593 result_ = Transform(node->nodes()[last_node_index]);
586 } 594 }
587 595
588 596
589 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { 597 void AwaitTransformer::VisitThrowNode(ThrowNode* node) {
590 AstNode* new_exception = Transform(node->exception()); 598 AstNode* new_exception = Transform(node->exception());
591 result_ = new(Z) ThrowNode(node->token_pos(), 599 result_ = new(Z) ThrowNode(node->token_pos(),
592 new_exception, 600 new_exception,
593 node->stacktrace()); 601 node->stacktrace());
594 } 602 }
595 603
596 } // namespace dart 604 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/ast_transformer.h ('k') | runtime/vm/class_finalizer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698