| 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/parser.h" | 7 #include "vm/parser.h" |
| 8 | 8 |
| 9 namespace dart { | 9 namespace dart { |
| 10 | 10 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { | 112 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { |
| 113 // Await transformation: | 113 // Await transformation: |
| 114 // | 114 // |
| 115 // :await_temp_var_X = <expr>; | 115 // :await_temp_var_X = <expr>; |
| 116 // :result_param = :await_temp_var_X; | 116 // :result_param = :await_temp_var_X; |
| 117 // if (:result_param is Future) { | 117 // if (:result_param is Future) { |
| 118 // AwaitMarker(kNewContinuationState); | 118 // AwaitMarker(kNewContinuationState); |
| 119 // :result_param.then(:async_op); | 119 // :result_param = :result_param.then(:async_op); |
| 120 // _asyncCatchHelper(:result_param.catchError, :async_op); |
| 120 // return; // (return_type() == kContinuation) | 121 // return; // (return_type() == kContinuation) |
| 121 // } | 122 // } |
| 122 // AwaitMarker(kTargetForContinuation); // Join happens here. | 123 // AwaitMarker(kTargetForContinuation); // Join happens here. |
| 123 // :saved_try_ctx_var = :await_saved_try_ctx_var_y; | 124 // :saved_try_ctx_var = :await_saved_try_ctx_var_y; |
| 124 // :await_temp_var_(X+1) = :result_param; | 125 // :await_temp_var_(X+1) = :result_param; |
| 125 | 126 |
| 126 LocalVariable* async_op = GetVariableInScope( | 127 LocalVariable* async_op = GetVariableInScope( |
| 127 preamble_->scope(), Symbols::AsyncOperation()); | 128 preamble_->scope(), Symbols::AsyncOperation()); |
| 128 LocalVariable* result_param = GetVariableInScope( | 129 LocalVariable* result_param = GetVariableInScope( |
| 129 preamble_->scope(), Symbols::AsyncOperationParam()); | 130 preamble_->scope(), Symbols::AsyncOperationParam()); |
| 131 LocalVariable* error_param = GetVariableInScope( |
| 132 preamble_->scope(), Symbols::AsyncOperationErrorParam()); |
| 130 | 133 |
| 131 node->expr()->Visit(this); | 134 node->expr()->Visit(this); |
| 132 preamble_->Add(new(I) StoreLocalNode( | 135 preamble_->Add(new(I) StoreLocalNode( |
| 133 Scanner::kNoSourcePos, result_param, result_)); | 136 Scanner::kNoSourcePos, result_param, result_)); |
| 134 LoadLocalNode* load_result_param = new(I) LoadLocalNode( | 137 LoadLocalNode* load_result_param = new(I) LoadLocalNode( |
| 135 Scanner::kNoSourcePos, result_param); | 138 Scanner::kNoSourcePos, result_param); |
| 136 LocalScope* is_future_scope = ChainNewScope(preamble_->scope()); | 139 LocalScope* is_future_scope = ChainNewScope(preamble_->scope()); |
| 137 SequenceNode* is_future_branch = new (I) SequenceNode( | 140 SequenceNode* is_future_branch = new (I) SequenceNode( |
| 138 Scanner::kNoSourcePos, is_future_scope); | 141 Scanner::kNoSourcePos, is_future_scope); |
| 139 AwaitMarkerNode* await_marker = new (I) AwaitMarkerNode( | 142 AwaitMarkerNode* await_marker = new (I) AwaitMarkerNode( |
| 140 AwaitMarkerNode::kNewContinuationState); | 143 AwaitMarkerNode::kNewContinuationState); |
| 141 await_marker->set_scope(is_future_scope); | 144 await_marker->set_scope(is_future_scope); |
| 142 GetVariableInScope(is_future_scope, Symbols::AwaitJumpVar()); | 145 GetVariableInScope(is_future_scope, Symbols::AwaitJumpVar()); |
| 143 GetVariableInScope(is_future_scope, Symbols::AwaitContextVar()); | 146 GetVariableInScope(is_future_scope, Symbols::AwaitContextVar()); |
| 144 is_future_branch->Add(await_marker); | 147 is_future_branch->Add(await_marker); |
| 145 ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos); | 148 ArgumentListNode* args = new(I) ArgumentListNode(Scanner::kNoSourcePos); |
| 146 args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op)); | 149 args->Add(new(I) LoadLocalNode(Scanner::kNoSourcePos, async_op)); |
| 147 is_future_branch->Add(new(I) InstanceCallNode( | 150 is_future_branch->Add(new (I) StoreLocalNode( |
| 148 Scanner::kNoSourcePos, load_result_param, Symbols::FutureThen(), args)); | 151 Scanner::kNoSourcePos, |
| 152 result_param, |
| 153 new(I) InstanceCallNode( |
| 154 Scanner::kNoSourcePos, |
| 155 load_result_param, |
| 156 Symbols::FutureThen(), |
| 157 args))); |
| 158 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 159 const Function& async_catch_helper = Function::ZoneHandle( |
| 160 I, core_lib.LookupFunctionAllowPrivate(Symbols::AsyncCatchHelper())); |
| 161 ASSERT(!async_catch_helper.IsNull()); |
| 162 ArgumentListNode* catch_helper_args = new (I) ArgumentListNode( |
| 163 Scanner::kNoSourcePos); |
| 164 InstanceGetterNode* catch_error_getter = new (I) InstanceGetterNode( |
| 165 Scanner::kNoSourcePos, |
| 166 load_result_param, |
| 167 Symbols::FutureCatchError()); |
| 168 catch_helper_args->Add(catch_error_getter); |
| 169 catch_helper_args->Add(new (I) LoadLocalNode( |
| 170 Scanner::kNoSourcePos, async_op)); |
| 171 is_future_branch->Add(new (I) StaticCallNode( |
| 172 Scanner::kNoSourcePos, |
| 173 async_catch_helper, |
| 174 catch_helper_args)); |
| 149 ReturnNode* continuation_return = new(I) ReturnNode(Scanner::kNoSourcePos); | 175 ReturnNode* continuation_return = new(I) ReturnNode(Scanner::kNoSourcePos); |
| 150 continuation_return->set_return_type(ReturnNode::kContinuation); | 176 continuation_return->set_return_type(ReturnNode::kContinuation); |
| 151 is_future_branch->Add(continuation_return); | 177 is_future_branch->Add(continuation_return); |
| 152 | 178 |
| 153 const Class& cls = Class::ZoneHandle( | 179 const Class& cls = Class::ZoneHandle( |
| 154 I, library_.LookupClass(Symbols::Future())); | 180 I, library_.LookupClass(Symbols::Future())); |
| 155 const AbstractType& future_type = AbstractType::ZoneHandle(I, cls.RareType()); | 181 const AbstractType& future_type = AbstractType::ZoneHandle(I, cls.RareType()); |
| 156 ASSERT(!future_type.IsNull()); | 182 ASSERT(!future_type.IsNull()); |
| 157 preamble_->Add(new(I) IfNode( | 183 preamble_->Add(new(I) IfNode( |
| 158 Scanner::kNoSourcePos, | 184 Scanner::kNoSourcePos, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 172 String::Handle(I, parsed_function_->async_saved_try_ctx_name()); | 198 String::Handle(I, parsed_function_->async_saved_try_ctx_name()); |
| 173 if (!async_saved_try_ctx_name.IsNull()) { | 199 if (!async_saved_try_ctx_name.IsNull()) { |
| 174 LocalVariable* async_saved_try_ctx = | 200 LocalVariable* async_saved_try_ctx = |
| 175 GetVariableInScope(preamble_->scope(), async_saved_try_ctx_name); | 201 GetVariableInScope(preamble_->scope(), async_saved_try_ctx_name); |
| 176 preamble_->Add(new (I) StoreLocalNode( | 202 preamble_->Add(new (I) StoreLocalNode( |
| 177 Scanner::kNoSourcePos, | 203 Scanner::kNoSourcePos, |
| 178 parsed_function_->saved_try_ctx(), | 204 parsed_function_->saved_try_ctx(), |
| 179 new (I) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx))); | 205 new (I) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx))); |
| 180 } | 206 } |
| 181 | 207 |
| 208 LoadLocalNode* load_error_param = new (I) LoadLocalNode( |
| 209 Scanner::kNoSourcePos, error_param); |
| 210 SequenceNode* error_ne_null_branch = new (I) SequenceNode( |
| 211 Scanner::kNoSourcePos, ChainNewScope(preamble_->scope())); |
| 212 error_ne_null_branch->Add(new (I) ThrowNode( |
| 213 Scanner::kNoSourcePos, |
| 214 load_error_param, |
| 215 NULL)); |
| 216 preamble_->Add(new (I) IfNode( |
| 217 Scanner::kNoSourcePos, |
| 218 new (I) ComparisonNode( |
| 219 Scanner::kNoSourcePos, |
| 220 Token::kNE, |
| 221 load_error_param, |
| 222 new (I) LiteralNode(Scanner::kNoSourcePos, |
| 223 Object::null_instance())), |
| 224 error_ne_null_branch, |
| 225 NULL)); |
| 226 |
| 182 LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode( | 227 LocalVariable* result = AddToPreambleNewTempVar(new(I) LoadLocalNode( |
| 183 Scanner::kNoSourcePos, result_param)); | 228 Scanner::kNoSourcePos, result_param)); |
| 184 result_ = new(I) LoadLocalNode(Scanner::kNoSourcePos, result); | 229 result_ = new(I) LoadLocalNode(Scanner::kNoSourcePos, result); |
| 185 } | 230 } |
| 186 | 231 |
| 187 | 232 |
| 188 // Transforms boolean expressions into a sequence of evaluatons that only lazily | 233 // Transforms boolean expressions into a sequence of evaluatons that only lazily |
| 189 // evaluate subexpressions. | 234 // evaluate subexpressions. |
| 190 // | 235 // |
| 191 // Example: | 236 // Example: |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { | 584 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { |
| 540 // TODO(mlippautz): Check if relevant. | 585 // TODO(mlippautz): Check if relevant. |
| 541 AstNode* new_exception = Transform(node->exception()); | 586 AstNode* new_exception = Transform(node->exception()); |
| 542 AstNode* new_stacktrace = Transform(node->stacktrace()); | 587 AstNode* new_stacktrace = Transform(node->stacktrace()); |
| 543 result_ = new(I) ThrowNode(node->token_pos(), | 588 result_ = new(I) ThrowNode(node->token_pos(), |
| 544 new_exception, | 589 new_exception, |
| 545 new_stacktrace); | 590 new_stacktrace); |
| 546 } | 591 } |
| 547 | 592 |
| 548 } // namespace dart | 593 } // namespace dart |
| OLD | NEW |