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