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 27 matching lines...) Expand all Loading... | |
38 | 38 |
39 #define DEFINE_UNREACHABLE(BaseName) \ | 39 #define DEFINE_UNREACHABLE(BaseName) \ |
40 void AwaitTransformer::Visit##BaseName##Node(BaseName##Node* node) { \ | 40 void AwaitTransformer::Visit##BaseName##Node(BaseName##Node* node) { \ |
41 UNREACHABLE(); \ | 41 UNREACHABLE(); \ |
42 } | 42 } |
43 | 43 |
44 FOR_EACH_UNREACHABLE_NODE(DEFINE_UNREACHABLE) | 44 FOR_EACH_UNREACHABLE_NODE(DEFINE_UNREACHABLE) |
45 #undef DEFINE_UNREACHABLE | 45 #undef DEFINE_UNREACHABLE |
46 | 46 |
47 AwaitTransformer::AwaitTransformer(SequenceNode* preamble, | 47 AwaitTransformer::AwaitTransformer(SequenceNode* preamble, |
48 const ParsedFunction& parsed_function, | |
49 LocalScope* function_top) | 48 LocalScope* function_top) |
50 : preamble_(preamble), | 49 : preamble_(preamble), |
51 temp_cnt_(0), | 50 temp_cnt_(0), |
52 parsed_function_(parsed_function), | |
53 function_top_(function_top), | 51 function_top_(function_top), |
54 thread_(Thread::Current()) { | 52 thread_(Thread::Current()) { |
55 ASSERT(function_top_ != NULL); | 53 ASSERT(function_top_ != NULL); |
56 } | 54 } |
57 | 55 |
58 | 56 |
59 AstNode* AwaitTransformer::Transform(AstNode* expr) { | 57 AstNode* AwaitTransformer::Transform(AstNode* expr) { |
60 expr->Visit(this); | 58 expr->Visit(this); |
61 return result_; | 59 return result_; |
62 } | 60 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { | 100 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { |
103 result_ = node; | 101 result_ = node; |
104 } | 102 } |
105 | 103 |
106 | 104 |
107 void AwaitTransformer::VisitTypeNode(TypeNode* node) { | 105 void AwaitTransformer::VisitTypeNode(TypeNode* node) { |
108 result_ = new(Z) TypeNode(node->token_pos(), node->type()); | 106 result_ = new(Z) TypeNode(node->token_pos(), node->type()); |
109 } | 107 } |
110 | 108 |
111 | 109 |
110 // Restore the currently relevant :saved_try_context_var on the stack | |
111 // from the captured :async_saved_try_ctx_var_<try_index>. | |
112 // * Try blocks: Set the context variable for this try block. | |
113 // * Catch blocks: Set the context variable for this try block and for any outer | |
114 // try block (if existent). | |
115 // * Finally blocks: Set the context variable for any outer try block (if | |
116 // existent). | |
Ivan Posva
2015/02/27 10:23:43
This second half of the comment makes it sound as
regis
2015/02/27 21:41:53
I've moved the second half of the comment to Parse
| |
117 AstNode* AwaitTransformer::RestoreSavedTryContext(Zone* zone, | |
118 LocalScope* scope, | |
119 int16_t try_index) { | |
120 LocalVariable* saved_try_ctx = | |
121 scope->LookupVariable(Symbols::SavedTryContextVar(), false); | |
122 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured()); | |
123 const String& async_saved_try_ctx_name = String::ZoneHandle(zone, | |
124 Symbols::New(String::Handle(zone, | |
125 String::NewFormatted("%s%d", | |
126 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | |
127 try_index)))); | |
128 LocalVariable* async_saved_try_ctx = | |
129 scope->LookupVariable(async_saved_try_ctx_name, false); | |
130 ASSERT(async_saved_try_ctx != NULL); | |
131 ASSERT(async_saved_try_ctx->is_captured()); | |
132 return new (zone) StoreLocalNode( | |
133 Scanner::kNoSourcePos, | |
134 saved_try_ctx, | |
135 new (zone) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx)); | |
136 } | |
137 | |
138 | |
112 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { | 139 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { |
113 // Await transformation: | 140 // Await transformation: |
114 // | 141 // |
115 // :await_temp_var_X = <expr>; | 142 // :await_temp_var_X = <expr>; |
116 // :result_param = :await_temp_var_X; | 143 // :result_param = :await_temp_var_X; |
117 // if (:result_param is !Future) { | 144 // if (:result_param is !Future) { |
118 // :result_param = Future.value(:result_param); | 145 // :result_param = Future.value(:result_param); |
119 // } | 146 // } |
120 // AwaitMarker(kNewContinuationState); | 147 // AwaitMarker(kNewContinuationState); |
121 // :result_param = :result_param.then(:async_op); | 148 // :result_param = :result_param.then(:async_op); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 Scanner::kNoSourcePos, async_op)); | 232 Scanner::kNoSourcePos, async_op)); |
206 preamble_->Add(new (Z) StaticCallNode( | 233 preamble_->Add(new (Z) StaticCallNode( |
207 Scanner::kNoSourcePos, | 234 Scanner::kNoSourcePos, |
208 async_catch_helper, | 235 async_catch_helper, |
209 catch_helper_args)); | 236 catch_helper_args)); |
210 ReturnNode* continuation_return = new(Z) ReturnNode(Scanner::kNoSourcePos); | 237 ReturnNode* continuation_return = new(Z) ReturnNode(Scanner::kNoSourcePos); |
211 continuation_return->set_return_type(ReturnNode::kContinuationTarget); | 238 continuation_return->set_return_type(ReturnNode::kContinuationTarget); |
212 preamble_->Add(continuation_return); | 239 preamble_->Add(continuation_return); |
213 | 240 |
214 // If this expression is part of a try block, also append the code for | 241 // If this expression is part of a try block, also append the code for |
215 // restoring the saved try context that lives on the stack. | 242 // restoring the saved try context that lives on the stack and possibly the |
216 const String& async_saved_try_ctx_name = | 243 // saved try context of the outer try block. |
217 String::Handle(Z, parsed_function_.async_saved_try_ctx_name()); | 244 if (node->try_scope() != NULL) { |
218 if (!async_saved_try_ctx_name.IsNull()) { | 245 preamble_->Add(RestoreSavedTryContext(Z, |
219 LocalVariable* async_saved_try_ctx = | 246 node->try_scope(), |
Florian Schneider
2015/02/27 11:52:53
How about passing the correct LocalVariable object
regis
2015/02/27 21:41:53
I am not sure that all variables are already setup
| |
220 GetVariableInScope(preamble_->scope(), async_saved_try_ctx_name); | 247 node->try_index())); |
221 preamble_->Add(new (Z) StoreLocalNode( | 248 if (node->outer_try_scope() != NULL) { |
222 Scanner::kNoSourcePos, | 249 preamble_->Add(RestoreSavedTryContext(Z, |
223 parsed_function_.saved_try_ctx(), | 250 node->outer_try_scope(), |
224 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx))); | 251 node->outer_try_index())); |
252 } | |
253 } else { | |
254 ASSERT(node->outer_try_scope() == NULL); | |
225 } | 255 } |
226 | 256 |
227 LoadLocalNode* load_error_param = new (Z) LoadLocalNode( | 257 LoadLocalNode* load_error_param = new (Z) LoadLocalNode( |
228 Scanner::kNoSourcePos, error_param); | 258 Scanner::kNoSourcePos, error_param); |
229 LoadLocalNode* load_stack_trace_param = new (Z) LoadLocalNode( | 259 LoadLocalNode* load_stack_trace_param = new (Z) LoadLocalNode( |
230 Scanner::kNoSourcePos, stack_trace_param); | 260 Scanner::kNoSourcePos, stack_trace_param); |
231 SequenceNode* error_ne_null_branch = new (Z) SequenceNode( | 261 SequenceNode* error_ne_null_branch = new (Z) SequenceNode( |
232 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); | 262 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); |
233 error_ne_null_branch->Add(new (Z) ThrowNode( | 263 error_ne_null_branch->Add(new (Z) ThrowNode( |
234 Scanner::kNoSourcePos, | 264 Scanner::kNoSourcePos, |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
599 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { | 629 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { |
600 // TODO(mlippautz): Check if relevant. | 630 // TODO(mlippautz): Check if relevant. |
601 AstNode* new_exception = Transform(node->exception()); | 631 AstNode* new_exception = Transform(node->exception()); |
602 AstNode* new_stacktrace = Transform(node->stacktrace()); | 632 AstNode* new_stacktrace = Transform(node->stacktrace()); |
603 result_ = new(Z) ThrowNode(node->token_pos(), | 633 result_ = new(Z) ThrowNode(node->token_pos(), |
604 new_exception, | 634 new_exception, |
605 new_stacktrace); | 635 new_stacktrace); |
606 } | 636 } |
607 | 637 |
608 } // namespace dart | 638 } // namespace dart |
OLD | NEW |