Chromium Code Reviews| 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 |