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

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

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

Powered by Google App Engine
This is Rietveld 408576698