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 28 matching lines...) Expand all Loading... |
39 | 39 |
40 #define DEFINE_UNREACHABLE(BaseName) \ | 40 #define DEFINE_UNREACHABLE(BaseName) \ |
41 void AwaitTransformer::Visit##BaseName##Node(BaseName##Node* node) { \ | 41 void AwaitTransformer::Visit##BaseName##Node(BaseName##Node* node) { \ |
42 UNREACHABLE(); \ | 42 UNREACHABLE(); \ |
43 } | 43 } |
44 | 44 |
45 FOR_EACH_UNREACHABLE_NODE(DEFINE_UNREACHABLE) | 45 FOR_EACH_UNREACHABLE_NODE(DEFINE_UNREACHABLE) |
46 #undef DEFINE_UNREACHABLE | 46 #undef DEFINE_UNREACHABLE |
47 | 47 |
48 AwaitTransformer::AwaitTransformer(SequenceNode* preamble, | 48 AwaitTransformer::AwaitTransformer(SequenceNode* preamble, |
49 LocalScope* function_top) | 49 LocalScope* async_temp_scope) |
50 : preamble_(preamble), | 50 : preamble_(preamble), |
51 temp_cnt_(0), | 51 temp_cnt_(0), |
52 function_top_(function_top), | 52 async_temp_scope_(async_temp_scope), |
53 thread_(Thread::Current()) { | 53 thread_(Thread::Current()) { |
54 ASSERT(function_top_ != NULL); | 54 ASSERT(async_temp_scope_ != NULL); |
55 } | 55 } |
56 | 56 |
57 | 57 |
58 AstNode* AwaitTransformer::Transform(AstNode* expr) { | 58 AstNode* AwaitTransformer::Transform(AstNode* expr) { |
59 expr->Visit(this); | 59 expr->Visit(this); |
60 return result_; | 60 return result_; |
61 } | 61 } |
62 | 62 |
63 | 63 |
64 LocalVariable* AwaitTransformer::EnsureCurrentTempVar() { | 64 LocalVariable* AwaitTransformer::EnsureCurrentTempVar() { |
65 const char* await_temp_prefix = ":await_temp_var_"; | 65 String& symbol = String::ZoneHandle(Z, String::NewFormatted("%d", temp_cnt_)); |
66 const String& cnt_str = String::ZoneHandle( | 66 symbol = Symbols::FromConcat(Symbols::AwaitTempVarPrefix(), symbol); |
67 Z, String::NewFormatted("%s%d", await_temp_prefix, temp_cnt_)); | |
68 const String& symbol = String::ZoneHandle(Z, Symbols::New(cnt_str)); | |
69 ASSERT(!symbol.IsNull()); | 67 ASSERT(!symbol.IsNull()); |
70 // Look up the variable in the scope used for async temp variables. | 68 // Look up the variable in the scope used for async temp variables. |
71 LocalVariable* await_tmp = function_top_->LocalLookupVariable(symbol); | 69 LocalVariable* await_tmp = async_temp_scope_->LocalLookupVariable(symbol); |
72 if (await_tmp == NULL) { | 70 if (await_tmp == NULL) { |
73 // We need a new temp variable; add it to the function's top scope. | 71 // We need a new temp variable; add it to the function's top scope. |
74 await_tmp = new (Z) LocalVariable( | 72 await_tmp = new (Z) LocalVariable( |
75 Scanner::kNoSourcePos, symbol, Type::ZoneHandle(Type::DynamicType())); | 73 Scanner::kNoSourcePos, symbol, Type::ZoneHandle(Type::DynamicType())); |
76 function_top_->AddVariable(await_tmp); | 74 async_temp_scope_->AddVariable(await_tmp); |
77 // After adding it to the top scope, we can look it up from the preamble. | 75 // After adding it to the top scope, we can look it up from the preamble. |
78 // The following call includes an ASSERT check. | 76 // The following call includes an ASSERT check. |
79 await_tmp = GetVariableInScope(preamble_->scope(), symbol); | 77 await_tmp = GetVariableInScope(preamble_->scope(), symbol); |
80 } | 78 } |
81 return await_tmp; | 79 return await_tmp; |
82 } | 80 } |
83 | 81 |
84 | 82 |
85 LocalVariable* AwaitTransformer::GetVariableInScope(LocalScope* scope, | 83 LocalVariable* AwaitTransformer::GetVariableInScope(LocalScope* scope, |
86 const String& symbol) { | 84 const String& symbol) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 LocalVariable* result_param = GetVariableInScope( | 127 LocalVariable* result_param = GetVariableInScope( |
130 preamble_->scope(), Symbols::AsyncOperationParam()); | 128 preamble_->scope(), Symbols::AsyncOperationParam()); |
131 LocalVariable* error_param = GetVariableInScope( | 129 LocalVariable* error_param = GetVariableInScope( |
132 preamble_->scope(), Symbols::AsyncOperationErrorParam()); | 130 preamble_->scope(), Symbols::AsyncOperationErrorParam()); |
133 LocalVariable* stack_trace_param = GetVariableInScope( | 131 LocalVariable* stack_trace_param = GetVariableInScope( |
134 preamble_->scope(), Symbols::AsyncOperationStackTraceParam()); | 132 preamble_->scope(), Symbols::AsyncOperationStackTraceParam()); |
135 | 133 |
136 AstNode* transformed_expr = Transform(node->expr()); | 134 AstNode* transformed_expr = Transform(node->expr()); |
137 LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr); | 135 LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr); |
138 | 136 |
139 AwaitMarkerNode* await_marker = new (Z) AwaitMarkerNode(); | 137 AwaitMarkerNode* await_marker = |
140 await_marker->set_scope(preamble_->scope()); | 138 new (Z) AwaitMarkerNode(async_temp_scope_, node->scope()); |
141 preamble_->Add(await_marker); | 139 preamble_->Add(await_marker); |
142 | 140 |
143 // :result_param = _awaitHelper( | 141 // :result_param = _awaitHelper( |
144 // :await_temp, :async_then_callback, :async_catch_error_callback) | 142 // :await_temp, :async_then_callback, :async_catch_error_callback) |
145 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | 143 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); |
146 const Function& async_await_helper = Function::ZoneHandle( | 144 const Function& async_await_helper = Function::ZoneHandle( |
147 Z, async_lib.LookupFunctionAllowPrivate(Symbols::AsyncAwaitHelper())); | 145 Z, async_lib.LookupFunctionAllowPrivate(Symbols::AsyncAwaitHelper())); |
148 ASSERT(!async_await_helper.IsNull()); | 146 ASSERT(!async_await_helper.IsNull()); |
149 ArgumentListNode* async_await_helper_args = new (Z) ArgumentListNode( | 147 ArgumentListNode* async_await_helper_args = new (Z) ArgumentListNode( |
150 Scanner::kNoSourcePos); | 148 Scanner::kNoSourcePos); |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 } | 553 } |
556 | 554 |
557 | 555 |
558 void AwaitTransformer::VisitLetNode(LetNode* node) { | 556 void AwaitTransformer::VisitLetNode(LetNode* node) { |
559 // Add all the initializer nodes to the preamble and the | 557 // Add all the initializer nodes to the preamble and the |
560 // temporary variables to the scope for async temporary variables. | 558 // temporary variables to the scope for async temporary variables. |
561 // The temporary variables will be captured as a side effect of being | 559 // 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 | 560 // added to a scope, and the subsequent nodes that are added to the |
563 // preample can access them. | 561 // preample can access them. |
564 for (intptr_t i = 0; i < node->num_temps(); i++) { | 562 for (intptr_t i = 0; i < node->num_temps(); i++) { |
565 function_top_->AddVariable(node->TempAt(i)); | 563 async_temp_scope_->AddVariable(node->TempAt(i)); |
566 AstNode* new_init_val = Transform(node->InitializerAt(i)); | 564 AstNode* new_init_val = Transform(node->InitializerAt(i)); |
567 preamble_->Add(new(Z) StoreLocalNode(node->token_pos(), | 565 preamble_->Add(new(Z) StoreLocalNode(node->token_pos(), |
568 node->TempAt(i), | 566 node->TempAt(i), |
569 new_init_val)); | 567 new_init_val)); |
570 } | 568 } |
571 // The transformed LetNode does not have any temporary variables. | 569 // The transformed LetNode does not have any temporary variables. |
572 LetNode* result = new(Z) LetNode(node->token_pos()); | 570 LetNode* result = new(Z) LetNode(node->token_pos()); |
573 for (intptr_t i = 0; i < node->nodes().length(); i++) { | 571 for (intptr_t i = 0; i < node->nodes().length(); i++) { |
574 result->AddNode(Transform(node->nodes()[i])); | 572 result->AddNode(Transform(node->nodes()[i])); |
575 } | 573 } |
576 result_ = result; | 574 result_ = result; |
577 } | 575 } |
578 | 576 |
579 | 577 |
580 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { | 578 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { |
581 AstNode* new_exception = Transform(node->exception()); | 579 AstNode* new_exception = Transform(node->exception()); |
582 result_ = new(Z) ThrowNode(node->token_pos(), | 580 result_ = new(Z) ThrowNode(node->token_pos(), |
583 new_exception, | 581 new_exception, |
584 node->stacktrace()); | 582 node->stacktrace()); |
585 } | 583 } |
586 | 584 |
587 } // namespace dart | 585 } // namespace dart |
OLD | NEW |