| 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 |