| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 AwaitTransformer::AwaitTransformer(SequenceNode* preamble, | 54 AwaitTransformer::AwaitTransformer(SequenceNode* preamble, |
| 55 LocalScope* async_temp_scope) | 55 LocalScope* async_temp_scope) |
| 56 : preamble_(preamble), | 56 : preamble_(preamble), |
| 57 temp_cnt_(0), | 57 temp_cnt_(0), |
| 58 async_temp_scope_(async_temp_scope), | 58 async_temp_scope_(async_temp_scope), |
| 59 thread_(Thread::Current()) { | 59 thread_(Thread::Current()) { |
| 60 ASSERT(async_temp_scope_ != NULL); | 60 ASSERT(async_temp_scope_ != NULL); |
| 61 } | 61 } |
| 62 | 62 |
| 63 | |
| 64 AstNode* AwaitTransformer::Transform(AstNode* expr) { | 63 AstNode* AwaitTransformer::Transform(AstNode* expr) { |
| 65 expr->Visit(this); | 64 expr->Visit(this); |
| 66 return result_; | 65 return result_; |
| 67 } | 66 } |
| 68 | 67 |
| 69 | |
| 70 LocalVariable* AwaitTransformer::EnsureCurrentTempVar() { | 68 LocalVariable* AwaitTransformer::EnsureCurrentTempVar() { |
| 71 String& symbol = | 69 String& symbol = |
| 72 String::ZoneHandle(Z, Symbols::NewFormatted(T, "%d", temp_cnt_)); | 70 String::ZoneHandle(Z, Symbols::NewFormatted(T, "%d", temp_cnt_)); |
| 73 symbol = Symbols::FromConcat(T, Symbols::AwaitTempVarPrefix(), symbol); | 71 symbol = Symbols::FromConcat(T, Symbols::AwaitTempVarPrefix(), symbol); |
| 74 ASSERT(!symbol.IsNull()); | 72 ASSERT(!symbol.IsNull()); |
| 75 // Look up the variable in the scope used for async temp variables. | 73 // Look up the variable in the scope used for async temp variables. |
| 76 LocalVariable* await_tmp = async_temp_scope_->LocalLookupVariable(symbol); | 74 LocalVariable* await_tmp = async_temp_scope_->LocalLookupVariable(symbol); |
| 77 if (await_tmp == NULL) { | 75 if (await_tmp == NULL) { |
| 78 // We need a new temp variable; add it to the function's top scope. | 76 // We need a new temp variable; add it to the function's top scope. |
| 79 await_tmp = new (Z) | 77 await_tmp = new (Z) |
| 80 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 78 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 81 symbol, Object::dynamic_type()); | 79 symbol, Object::dynamic_type()); |
| 82 async_temp_scope_->AddVariable(await_tmp); | 80 async_temp_scope_->AddVariable(await_tmp); |
| 83 // After adding it to the top scope, we can look it up from the preamble. | 81 // After adding it to the top scope, we can look it up from the preamble. |
| 84 // The following call includes an ASSERT check. | 82 // The following call includes an ASSERT check. |
| 85 await_tmp = GetVariableInScope(preamble_->scope(), symbol); | 83 await_tmp = GetVariableInScope(preamble_->scope(), symbol); |
| 86 } | 84 } |
| 87 return await_tmp; | 85 return await_tmp; |
| 88 } | 86 } |
| 89 | 87 |
| 90 | |
| 91 LocalVariable* AwaitTransformer::GetVariableInScope(LocalScope* scope, | 88 LocalVariable* AwaitTransformer::GetVariableInScope(LocalScope* scope, |
| 92 const String& symbol) { | 89 const String& symbol) { |
| 93 LocalVariable* var = scope->LookupVariable(symbol, false); | 90 LocalVariable* var = scope->LookupVariable(symbol, false); |
| 94 ASSERT(var != NULL); | 91 ASSERT(var != NULL); |
| 95 return var; | 92 return var; |
| 96 } | 93 } |
| 97 | 94 |
| 98 | |
| 99 LocalVariable* AwaitTransformer::AddNewTempVarToPreamble( | 95 LocalVariable* AwaitTransformer::AddNewTempVarToPreamble( |
| 100 AstNode* node, | 96 AstNode* node, |
| 101 TokenPosition token_pos) { | 97 TokenPosition token_pos) { |
| 102 LocalVariable* tmp_var = EnsureCurrentTempVar(); | 98 LocalVariable* tmp_var = EnsureCurrentTempVar(); |
| 103 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource()); | 99 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource()); |
| 104 preamble_->Add(new (Z) StoreLocalNode(token_pos, tmp_var, node)); | 100 preamble_->Add(new (Z) StoreLocalNode(token_pos, tmp_var, node)); |
| 105 NextTempVar(); | 101 NextTempVar(); |
| 106 return tmp_var; | 102 return tmp_var; |
| 107 } | 103 } |
| 108 | 104 |
| 109 | |
| 110 LoadLocalNode* AwaitTransformer::MakeName(AstNode* node) { | 105 LoadLocalNode* AwaitTransformer::MakeName(AstNode* node) { |
| 111 LocalVariable* temp = AddNewTempVarToPreamble(node, ST(node->token_pos())); | 106 LocalVariable* temp = AddNewTempVarToPreamble(node, ST(node->token_pos())); |
| 112 return new (Z) LoadLocalNode(ST(node->token_pos()), temp); | 107 return new (Z) LoadLocalNode(ST(node->token_pos()), temp); |
| 113 } | 108 } |
| 114 | 109 |
| 115 | |
| 116 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { | 110 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { |
| 117 result_ = node; | 111 result_ = node; |
| 118 } | 112 } |
| 119 | 113 |
| 120 | |
| 121 void AwaitTransformer::VisitTypeNode(TypeNode* node) { | 114 void AwaitTransformer::VisitTypeNode(TypeNode* node) { |
| 122 if (node->is_deferred_reference()) { | 115 if (node->is_deferred_reference()) { |
| 123 // Deferred references must use a temporary even after loading | 116 // Deferred references must use a temporary even after loading |
| 124 // happened, so that the number of await temps is the same as | 117 // happened, so that the number of await temps is the same as |
| 125 // before the loading. | 118 // before the loading. |
| 126 result_ = MakeName(node); | 119 result_ = MakeName(node); |
| 127 } else { | 120 } else { |
| 128 result_ = node; | 121 result_ = node; |
| 129 } | 122 } |
| 130 } | 123 } |
| 131 | 124 |
| 132 | |
| 133 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { | 125 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { |
| 134 // Await transformation: | 126 // Await transformation: |
| 135 // | 127 // |
| 136 // :await_temp_var_X = <expr>; | 128 // :await_temp_var_X = <expr>; |
| 137 // AwaitMarker(kNewContinuationState); | 129 // AwaitMarker(kNewContinuationState); |
| 138 // :result_param = _awaitHelper( | 130 // :result_param = _awaitHelper( |
| 139 // :await_temp_var_X, | 131 // :await_temp_var_X, |
| 140 // :async_then_callback, | 132 // :async_then_callback, |
| 141 // :async_catch_error_callback, | 133 // :async_catch_error_callback, |
| 142 // :async_op); | 134 // :async_op); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 209 |
| 218 LoadLocalNode* load_error_param = | 210 LoadLocalNode* load_error_param = |
| 219 new (Z) LoadLocalNode(token_pos, error_param); | 211 new (Z) LoadLocalNode(token_pos, error_param); |
| 220 LoadLocalNode* load_stack_trace_param = | 212 LoadLocalNode* load_stack_trace_param = |
| 221 new (Z) LoadLocalNode(token_pos, stack_trace_param); | 213 new (Z) LoadLocalNode(token_pos, stack_trace_param); |
| 222 SequenceNode* error_ne_null_branch = | 214 SequenceNode* error_ne_null_branch = |
| 223 new (Z) SequenceNode(token_pos, ChainNewScope(preamble_->scope())); | 215 new (Z) SequenceNode(token_pos, ChainNewScope(preamble_->scope())); |
| 224 error_ne_null_branch->Add( | 216 error_ne_null_branch->Add( |
| 225 new (Z) ThrowNode(token_pos, load_error_param, load_stack_trace_param)); | 217 new (Z) ThrowNode(token_pos, load_error_param, load_stack_trace_param)); |
| 226 preamble_->Add(new (Z) IfNode( | 218 preamble_->Add(new (Z) IfNode( |
| 227 token_pos, new (Z) ComparisonNode( | 219 token_pos, |
| 228 token_pos, Token::kNE, load_error_param, | 220 new (Z) ComparisonNode( |
| 229 new (Z) LiteralNode(token_pos, Object::null_instance())), | 221 token_pos, Token::kNE, load_error_param, |
| 222 new (Z) LiteralNode(token_pos, Object::null_instance())), |
| 230 error_ne_null_branch, NULL)); | 223 error_ne_null_branch, NULL)); |
| 231 | 224 |
| 232 result_ = MakeName(new (Z) LoadLocalNode(token_pos, result_param)); | 225 result_ = MakeName(new (Z) LoadLocalNode(token_pos, result_param)); |
| 233 } | 226 } |
| 234 | 227 |
| 235 | |
| 236 // Transforms boolean expressions into a sequence of evaluations that only | 228 // Transforms boolean expressions into a sequence of evaluations that only |
| 237 // lazily evaluate subexpressions. | 229 // lazily evaluate subexpressions. |
| 238 // | 230 // |
| 239 // Example: | 231 // Example: |
| 240 // | 232 // |
| 241 // (a || b) only evaluates b if a is false | 233 // (a || b) only evaluates b if a is false |
| 242 // | 234 // |
| 243 // Transformation (roughly): | 235 // Transformation (roughly): |
| 244 // | 236 // |
| 245 // t_1 = a; | 237 // t_1 = a; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 264 IfNode* right_body = new (Z) | 256 IfNode* right_body = new (Z) |
| 265 IfNode(ST(new_left->token_pos()), | 257 IfNode(ST(new_left->token_pos()), |
| 266 new (Z) ComparisonNode( | 258 new (Z) ComparisonNode( |
| 267 ST(new_left->token_pos()), compare_logical_op, new_left, | 259 ST(new_left->token_pos()), compare_logical_op, new_left, |
| 268 new (Z) LiteralNode(ST(new_left->token_pos()), Bool::True())), | 260 new (Z) LiteralNode(ST(new_left->token_pos()), Bool::True())), |
| 269 eval, NULL); | 261 eval, NULL); |
| 270 preamble_->Add(right_body); | 262 preamble_->Add(right_body); |
| 271 return result; | 263 return result; |
| 272 } | 264 } |
| 273 | 265 |
| 274 | |
| 275 LocalScope* AwaitTransformer::ChainNewScope(LocalScope* parent) { | 266 LocalScope* AwaitTransformer::ChainNewScope(LocalScope* parent) { |
| 276 return new (Z) | 267 return new (Z) |
| 277 LocalScope(parent, parent->function_level(), parent->loop_level()); | 268 LocalScope(parent, parent->function_level(), parent->loop_level()); |
| 278 } | 269 } |
| 279 | 270 |
| 280 | |
| 281 void AwaitTransformer::VisitBinaryOpNode(BinaryOpNode* node) { | 271 void AwaitTransformer::VisitBinaryOpNode(BinaryOpNode* node) { |
| 282 AstNode* new_left = Transform(node->left()); | 272 AstNode* new_left = Transform(node->left()); |
| 283 AstNode* new_right = NULL; | 273 AstNode* new_right = NULL; |
| 284 // Preserve lazy evaluation. | 274 // Preserve lazy evaluation. |
| 285 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 275 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 286 new_right = LazyTransform(node->kind(), new_left, node->right()); | 276 new_right = LazyTransform(node->kind(), new_left, node->right()); |
| 287 } else { | 277 } else { |
| 288 new_right = Transform(node->right()); | 278 new_right = Transform(node->right()); |
| 289 } | 279 } |
| 290 result_ = MakeName(new (Z) BinaryOpNode(node->token_pos(), node->kind(), | 280 result_ = MakeName(new (Z) BinaryOpNode(node->token_pos(), node->kind(), |
| 291 new_left, new_right)); | 281 new_left, new_right)); |
| 292 } | 282 } |
| 293 | 283 |
| 294 | |
| 295 void AwaitTransformer::VisitComparisonNode(ComparisonNode* node) { | 284 void AwaitTransformer::VisitComparisonNode(ComparisonNode* node) { |
| 296 AstNode* new_left = Transform(node->left()); | 285 AstNode* new_left = Transform(node->left()); |
| 297 AstNode* new_right = Transform(node->right()); | 286 AstNode* new_right = Transform(node->right()); |
| 298 result_ = MakeName(new (Z) ComparisonNode(node->token_pos(), node->kind(), | 287 result_ = MakeName(new (Z) ComparisonNode(node->token_pos(), node->kind(), |
| 299 new_left, new_right)); | 288 new_left, new_right)); |
| 300 } | 289 } |
| 301 | 290 |
| 302 | |
| 303 void AwaitTransformer::VisitUnaryOpNode(UnaryOpNode* node) { | 291 void AwaitTransformer::VisitUnaryOpNode(UnaryOpNode* node) { |
| 304 AstNode* new_operand = Transform(node->operand()); | 292 AstNode* new_operand = Transform(node->operand()); |
| 305 result_ = MakeName( | 293 result_ = MakeName( |
| 306 new (Z) UnaryOpNode(node->token_pos(), node->kind(), new_operand)); | 294 new (Z) UnaryOpNode(node->token_pos(), node->kind(), new_operand)); |
| 307 } | 295 } |
| 308 | 296 |
| 309 | |
| 310 // ::= (<condition>) ? <true-branch> : <false-branch> | 297 // ::= (<condition>) ? <true-branch> : <false-branch> |
| 311 // | 298 // |
| 312 void AwaitTransformer::VisitConditionalExprNode(ConditionalExprNode* node) { | 299 void AwaitTransformer::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 313 AstNode* new_condition = Transform(node->condition()); | 300 AstNode* new_condition = Transform(node->condition()); |
| 314 SequenceNode* new_true = new (Z) SequenceNode( | 301 SequenceNode* new_true = new (Z) SequenceNode( |
| 315 ST(node->true_expr()->token_pos()), ChainNewScope(preamble_->scope())); | 302 ST(node->true_expr()->token_pos()), ChainNewScope(preamble_->scope())); |
| 316 SequenceNode* saved_preamble = preamble_; | 303 SequenceNode* saved_preamble = preamble_; |
| 317 preamble_ = new_true; | 304 preamble_ = new_true; |
| 318 AstNode* new_true_result = Transform(node->true_expr()); | 305 AstNode* new_true_result = Transform(node->true_expr()); |
| 319 SequenceNode* new_false = new (Z) SequenceNode( | 306 SequenceNode* new_false = new (Z) SequenceNode( |
| 320 ST(node->false_expr()->token_pos()), ChainNewScope(preamble_->scope())); | 307 ST(node->false_expr()->token_pos()), ChainNewScope(preamble_->scope())); |
| 321 preamble_ = new_false; | 308 preamble_ = new_false; |
| 322 AstNode* new_false_result = Transform(node->false_expr()); | 309 AstNode* new_false_result = Transform(node->false_expr()); |
| 323 preamble_ = saved_preamble; | 310 preamble_ = saved_preamble; |
| 324 IfNode* new_if = | 311 IfNode* new_if = |
| 325 new (Z) IfNode(ST(node->token_pos()), new_condition, new_true, new_false); | 312 new (Z) IfNode(ST(node->token_pos()), new_condition, new_true, new_false); |
| 326 preamble_->Add(new_if); | 313 preamble_->Add(new_if); |
| 327 result_ = MakeName(new (Z) ConditionalExprNode( | 314 result_ = MakeName(new (Z) ConditionalExprNode( |
| 328 ST(node->token_pos()), new_condition, new_true_result, new_false_result)); | 315 ST(node->token_pos()), new_condition, new_true_result, new_false_result)); |
| 329 } | 316 } |
| 330 | 317 |
| 331 | |
| 332 void AwaitTransformer::VisitArgumentListNode(ArgumentListNode* node) { | 318 void AwaitTransformer::VisitArgumentListNode(ArgumentListNode* node) { |
| 333 ArgumentListNode* new_args = new (Z) ArgumentListNode(node->token_pos()); | 319 ArgumentListNode* new_args = new (Z) ArgumentListNode(node->token_pos()); |
| 334 for (intptr_t i = 0; i < node->length(); i++) { | 320 for (intptr_t i = 0; i < node->length(); i++) { |
| 335 new_args->Add(Transform(node->NodeAt(i))); | 321 new_args->Add(Transform(node->NodeAt(i))); |
| 336 } | 322 } |
| 337 new_args->set_names(node->names()); | 323 new_args->set_names(node->names()); |
| 338 result_ = new_args; | 324 result_ = new_args; |
| 339 } | 325 } |
| 340 | 326 |
| 341 | |
| 342 void AwaitTransformer::VisitArrayNode(ArrayNode* node) { | 327 void AwaitTransformer::VisitArrayNode(ArrayNode* node) { |
| 343 GrowableArray<AstNode*> new_elements; | 328 GrowableArray<AstNode*> new_elements; |
| 344 for (intptr_t i = 0; i < node->length(); i++) { | 329 for (intptr_t i = 0; i < node->length(); i++) { |
| 345 new_elements.Add(Transform(node->ElementAt(i))); | 330 new_elements.Add(Transform(node->ElementAt(i))); |
| 346 } | 331 } |
| 347 result_ = new (Z) ArrayNode(node->token_pos(), node->type(), new_elements); | 332 result_ = new (Z) ArrayNode(node->token_pos(), node->type(), new_elements); |
| 348 } | 333 } |
| 349 | 334 |
| 350 | |
| 351 void AwaitTransformer::VisitStringInterpolateNode(StringInterpolateNode* node) { | 335 void AwaitTransformer::VisitStringInterpolateNode(StringInterpolateNode* node) { |
| 352 ArrayNode* new_value = Transform(node->value())->AsArrayNode(); | 336 ArrayNode* new_value = Transform(node->value())->AsArrayNode(); |
| 353 result_ = | 337 result_ = |
| 354 MakeName(new (Z) StringInterpolateNode(node->token_pos(), new_value)); | 338 MakeName(new (Z) StringInterpolateNode(node->token_pos(), new_value)); |
| 355 } | 339 } |
| 356 | 340 |
| 357 | |
| 358 void AwaitTransformer::VisitClosureNode(ClosureNode* node) { | 341 void AwaitTransformer::VisitClosureNode(ClosureNode* node) { |
| 359 AstNode* new_receiver = node->receiver(); | 342 AstNode* new_receiver = node->receiver(); |
| 360 if (new_receiver != NULL) { | 343 if (new_receiver != NULL) { |
| 361 new_receiver = Transform(new_receiver); | 344 new_receiver = Transform(new_receiver); |
| 362 } | 345 } |
| 363 result_ = MakeName(new (Z) ClosureNode(node->token_pos(), node->function(), | 346 result_ = MakeName(new (Z) ClosureNode(node->token_pos(), node->function(), |
| 364 new_receiver, node->scope())); | 347 new_receiver, node->scope())); |
| 365 } | 348 } |
| 366 | 349 |
| 367 | |
| 368 void AwaitTransformer::VisitInstanceCallNode(InstanceCallNode* node) { | 350 void AwaitTransformer::VisitInstanceCallNode(InstanceCallNode* node) { |
| 369 AstNode* new_receiver = Transform(node->receiver()); | 351 AstNode* new_receiver = Transform(node->receiver()); |
| 370 ArgumentListNode* new_args = | 352 ArgumentListNode* new_args = |
| 371 Transform(node->arguments())->AsArgumentListNode(); | 353 Transform(node->arguments())->AsArgumentListNode(); |
| 372 result_ = MakeName(new (Z) InstanceCallNode(node->token_pos(), new_receiver, | 354 result_ = MakeName(new (Z) InstanceCallNode(node->token_pos(), new_receiver, |
| 373 node->function_name(), new_args, | 355 node->function_name(), new_args, |
| 374 node->is_conditional())); | 356 node->is_conditional())); |
| 375 } | 357 } |
| 376 | 358 |
| 377 | |
| 378 void AwaitTransformer::VisitStaticCallNode(StaticCallNode* node) { | 359 void AwaitTransformer::VisitStaticCallNode(StaticCallNode* node) { |
| 379 ArgumentListNode* new_args = | 360 ArgumentListNode* new_args = |
| 380 Transform(node->arguments())->AsArgumentListNode(); | 361 Transform(node->arguments())->AsArgumentListNode(); |
| 381 result_ = MakeName( | 362 result_ = MakeName( |
| 382 new (Z) StaticCallNode(node->token_pos(), node->function(), new_args)); | 363 new (Z) StaticCallNode(node->token_pos(), node->function(), new_args)); |
| 383 } | 364 } |
| 384 | 365 |
| 385 | |
| 386 void AwaitTransformer::VisitConstructorCallNode(ConstructorCallNode* node) { | 366 void AwaitTransformer::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 387 ArgumentListNode* new_args = | 367 ArgumentListNode* new_args = |
| 388 Transform(node->arguments())->AsArgumentListNode(); | 368 Transform(node->arguments())->AsArgumentListNode(); |
| 389 result_ = MakeName( | 369 result_ = MakeName( |
| 390 new (Z) ConstructorCallNode(node->token_pos(), node->type_arguments(), | 370 new (Z) ConstructorCallNode(node->token_pos(), node->type_arguments(), |
| 391 node->constructor(), new_args)); | 371 node->constructor(), new_args)); |
| 392 } | 372 } |
| 393 | 373 |
| 394 | |
| 395 void AwaitTransformer::VisitInstanceGetterNode(InstanceGetterNode* node) { | 374 void AwaitTransformer::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 396 AstNode* new_receiver = Transform(node->receiver()); | 375 AstNode* new_receiver = Transform(node->receiver()); |
| 397 result_ = MakeName(new (Z) InstanceGetterNode(node->token_pos(), new_receiver, | 376 result_ = MakeName(new (Z) InstanceGetterNode(node->token_pos(), new_receiver, |
| 398 node->field_name(), | 377 node->field_name(), |
| 399 node->is_conditional())); | 378 node->is_conditional())); |
| 400 } | 379 } |
| 401 | 380 |
| 402 | |
| 403 void AwaitTransformer::VisitInstanceSetterNode(InstanceSetterNode* node) { | 381 void AwaitTransformer::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 404 AstNode* new_receiver = node->receiver(); | 382 AstNode* new_receiver = node->receiver(); |
| 405 if (new_receiver != NULL) { | 383 if (new_receiver != NULL) { |
| 406 new_receiver = Transform(new_receiver); | 384 new_receiver = Transform(new_receiver); |
| 407 } | 385 } |
| 408 AstNode* new_value = Transform(node->value()); | 386 AstNode* new_value = Transform(node->value()); |
| 409 result_ = MakeName(new (Z) InstanceSetterNode(node->token_pos(), new_receiver, | 387 result_ = MakeName(new (Z) InstanceSetterNode(node->token_pos(), new_receiver, |
| 410 node->field_name(), new_value, | 388 node->field_name(), new_value, |
| 411 node->is_conditional())); | 389 node->is_conditional())); |
| 412 } | 390 } |
| 413 | 391 |
| 414 | |
| 415 void AwaitTransformer::VisitStaticGetterNode(StaticGetterNode* node) { | 392 void AwaitTransformer::VisitStaticGetterNode(StaticGetterNode* node) { |
| 416 AstNode* new_receiver = node->receiver(); | 393 AstNode* new_receiver = node->receiver(); |
| 417 if (new_receiver != NULL) { | 394 if (new_receiver != NULL) { |
| 418 new_receiver = Transform(new_receiver); | 395 new_receiver = Transform(new_receiver); |
| 419 } | 396 } |
| 420 StaticGetterNode* new_getter = new (Z) StaticGetterNode( | 397 StaticGetterNode* new_getter = new (Z) StaticGetterNode( |
| 421 node->token_pos(), new_receiver, node->cls(), node->field_name()); | 398 node->token_pos(), new_receiver, node->cls(), node->field_name()); |
| 422 new_getter->set_owner(node->owner()); | 399 new_getter->set_owner(node->owner()); |
| 423 result_ = MakeName(new_getter); | 400 result_ = MakeName(new_getter); |
| 424 } | 401 } |
| 425 | 402 |
| 426 | |
| 427 void AwaitTransformer::VisitStaticSetterNode(StaticSetterNode* node) { | 403 void AwaitTransformer::VisitStaticSetterNode(StaticSetterNode* node) { |
| 428 AstNode* new_receiver = node->receiver(); | 404 AstNode* new_receiver = node->receiver(); |
| 429 if (new_receiver != NULL) { | 405 if (new_receiver != NULL) { |
| 430 new_receiver = Transform(new_receiver); | 406 new_receiver = Transform(new_receiver); |
| 431 } | 407 } |
| 432 AstNode* new_value = Transform(node->value()); | 408 AstNode* new_value = Transform(node->value()); |
| 433 StaticSetterNode* new_setter = | 409 StaticSetterNode* new_setter = |
| 434 node->function().IsNull() | 410 node->function().IsNull() |
| 435 ? new (Z) StaticSetterNode(node->token_pos(), new_receiver, | 411 ? new (Z) StaticSetterNode(node->token_pos(), new_receiver, |
| 436 node->cls(), node->field_name(), new_value) | 412 node->cls(), node->field_name(), new_value) |
| 437 : new (Z) StaticSetterNode(node->token_pos(), new_receiver, | 413 : new (Z) StaticSetterNode(node->token_pos(), new_receiver, |
| 438 node->field_name(), node->function(), | 414 node->field_name(), node->function(), |
| 439 new_value); | 415 new_value); |
| 440 | 416 |
| 441 result_ = MakeName(new_setter); | 417 result_ = MakeName(new_setter); |
| 442 } | 418 } |
| 443 | 419 |
| 444 | |
| 445 void AwaitTransformer::VisitLoadLocalNode(LoadLocalNode* node) { | 420 void AwaitTransformer::VisitLoadLocalNode(LoadLocalNode* node) { |
| 446 result_ = MakeName(node); | 421 result_ = MakeName(node); |
| 447 } | 422 } |
| 448 | 423 |
| 449 | |
| 450 void AwaitTransformer::VisitStoreLocalNode(StoreLocalNode* node) { | 424 void AwaitTransformer::VisitStoreLocalNode(StoreLocalNode* node) { |
| 451 AstNode* new_value = Transform(node->value()); | 425 AstNode* new_value = Transform(node->value()); |
| 452 result_ = MakeName( | 426 result_ = MakeName( |
| 453 new (Z) StoreLocalNode(node->token_pos(), &node->local(), new_value)); | 427 new (Z) StoreLocalNode(node->token_pos(), &node->local(), new_value)); |
| 454 } | 428 } |
| 455 | 429 |
| 456 | |
| 457 void AwaitTransformer::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 430 void AwaitTransformer::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 458 result_ = MakeName(node); | 431 result_ = MakeName(node); |
| 459 } | 432 } |
| 460 | 433 |
| 461 | |
| 462 void AwaitTransformer::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 434 void AwaitTransformer::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 463 AstNode* new_value = Transform(node->value()); | 435 AstNode* new_value = Transform(node->value()); |
| 464 result_ = MakeName(new (Z) StoreStaticFieldNode( | 436 result_ = MakeName(new (Z) StoreStaticFieldNode( |
| 465 node->token_pos(), Field::ZoneHandle(Z, node->field().Original()), | 437 node->token_pos(), Field::ZoneHandle(Z, node->field().Original()), |
| 466 new_value)); | 438 new_value)); |
| 467 } | 439 } |
| 468 | 440 |
| 469 | |
| 470 void AwaitTransformer::VisitLoadIndexedNode(LoadIndexedNode* node) { | 441 void AwaitTransformer::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 471 AstNode* new_array = Transform(node->array()); | 442 AstNode* new_array = Transform(node->array()); |
| 472 AstNode* new_index = Transform(node->index_expr()); | 443 AstNode* new_index = Transform(node->index_expr()); |
| 473 result_ = MakeName(new (Z) LoadIndexedNode(node->token_pos(), new_array, | 444 result_ = MakeName(new (Z) LoadIndexedNode(node->token_pos(), new_array, |
| 474 new_index, node->super_class())); | 445 new_index, node->super_class())); |
| 475 } | 446 } |
| 476 | 447 |
| 477 | |
| 478 void AwaitTransformer::VisitStoreIndexedNode(StoreIndexedNode* node) { | 448 void AwaitTransformer::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 479 AstNode* new_array = Transform(node->array()); | 449 AstNode* new_array = Transform(node->array()); |
| 480 AstNode* new_index = Transform(node->index_expr()); | 450 AstNode* new_index = Transform(node->index_expr()); |
| 481 AstNode* new_value = Transform(node->value()); | 451 AstNode* new_value = Transform(node->value()); |
| 482 result_ = MakeName(new (Z) StoreIndexedNode( | 452 result_ = MakeName(new (Z) StoreIndexedNode( |
| 483 node->token_pos(), new_array, new_index, new_value, node->super_class())); | 453 node->token_pos(), new_array, new_index, new_value, node->super_class())); |
| 484 } | 454 } |
| 485 | 455 |
| 486 | |
| 487 void AwaitTransformer::VisitAssignableNode(AssignableNode* node) { | 456 void AwaitTransformer::VisitAssignableNode(AssignableNode* node) { |
| 488 AstNode* new_expr = Transform(node->expr()); | 457 AstNode* new_expr = Transform(node->expr()); |
| 489 result_ = MakeName(new (Z) AssignableNode(node->token_pos(), new_expr, | 458 result_ = MakeName(new (Z) AssignableNode(node->token_pos(), new_expr, |
| 490 node->type(), node->dst_name())); | 459 node->type(), node->dst_name())); |
| 491 } | 460 } |
| 492 | 461 |
| 493 | |
| 494 void AwaitTransformer::VisitLetNode(LetNode* node) { | 462 void AwaitTransformer::VisitLetNode(LetNode* node) { |
| 495 // Add all the initializer nodes to the preamble and the | 463 // Add all the initializer nodes to the preamble and the |
| 496 // temporary variables to the scope for async temporary variables. | 464 // temporary variables to the scope for async temporary variables. |
| 497 // The temporary variables will be captured as a side effect of being | 465 // The temporary variables will be captured as a side effect of being |
| 498 // added to a scope, and the subsequent nodes that are added to the | 466 // added to a scope, and the subsequent nodes that are added to the |
| 499 // preample can access them. | 467 // preample can access them. |
| 500 for (intptr_t i = 0; i < node->num_temps(); i++) { | 468 for (intptr_t i = 0; i < node->num_temps(); i++) { |
| 501 async_temp_scope_->AddVariable(node->TempAt(i)); | 469 async_temp_scope_->AddVariable(node->TempAt(i)); |
| 502 AstNode* new_init_val = Transform(node->InitializerAt(i)); | 470 AstNode* new_init_val = Transform(node->InitializerAt(i)); |
| 503 preamble_->Add(new (Z) StoreLocalNode(node->token_pos(), node->TempAt(i), | 471 preamble_->Add(new (Z) StoreLocalNode(node->token_pos(), node->TempAt(i), |
| 504 new_init_val)); | 472 new_init_val)); |
| 505 } | 473 } |
| 506 | 474 |
| 507 // Add all expressions but the last to the preamble. We must do | 475 // Add all expressions but the last to the preamble. We must do |
| 508 // this because subexpressions of the awaitable expression we | 476 // this because subexpressions of the awaitable expression we |
| 509 // are currently transforming may depend on each other, | 477 // are currently transforming may depend on each other, |
| 510 // e.g. await foo(a++, a++). Thus we must preserve the order of the | 478 // e.g. await foo(a++, a++). Thus we must preserve the order of the |
| 511 // transformed subexpressions. | 479 // transformed subexpressions. |
| 512 for (intptr_t i = 0; i < node->nodes().length() - 1; i++) { | 480 for (intptr_t i = 0; i < node->nodes().length() - 1; i++) { |
| 513 preamble_->Add(Transform(node->nodes()[i])); | 481 preamble_->Add(Transform(node->nodes()[i])); |
| 514 } | 482 } |
| 515 | 483 |
| 516 // The last expression in the let node is the value of the node. | 484 // The last expression in the let node is the value of the node. |
| 517 // The result of the transformed let node is this expression. | 485 // The result of the transformed let node is this expression. |
| 518 ASSERT(node->nodes().length() > 0); | 486 ASSERT(node->nodes().length() > 0); |
| 519 const intptr_t last_node_index = node->nodes().length() - 1; | 487 const intptr_t last_node_index = node->nodes().length() - 1; |
| 520 result_ = Transform(node->nodes()[last_node_index]); | 488 result_ = Transform(node->nodes()[last_node_index]); |
| 521 } | 489 } |
| 522 | 490 |
| 523 | |
| 524 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { | 491 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { |
| 525 AstNode* new_exception = Transform(node->exception()); | 492 AstNode* new_exception = Transform(node->exception()); |
| 526 result_ = MakeName( | 493 result_ = MakeName( |
| 527 new (Z) ThrowNode(node->token_pos(), new_exception, node->stacktrace())); | 494 new (Z) ThrowNode(node->token_pos(), new_exception, node->stacktrace())); |
| 528 } | 495 } |
| 529 | 496 |
| 530 } // namespace dart | 497 } // namespace dart |
| OLD | NEW |