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