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 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 // Quick access to the current zone. | 13 // Quick access to the current zone. |
14 #define Z (thread()->zone()) | 14 #define Z (thread()->zone()) |
15 | 15 |
16 // Quick synthetic token position. | 16 // Quick synthetic token position. |
17 #define ST(token_pos) Token::ToSynthetic(token_pos) | 17 #define ST(token_pos) ((token_pos).ToSynthetic()) |
18 | 18 |
19 // Nodes that are unreachable from already parsed expressions. | 19 // Nodes that are unreachable from already parsed expressions. |
20 #define FOR_EACH_UNREACHABLE_NODE(V) \ | 20 #define FOR_EACH_UNREACHABLE_NODE(V) \ |
21 V(AwaitMarker) \ | 21 V(AwaitMarker) \ |
22 V(Case) \ | 22 V(Case) \ |
23 V(CatchClause) \ | 23 V(CatchClause) \ |
24 V(CloneContext) \ | 24 V(CloneContext) \ |
25 V(ClosureCall) \ | 25 V(ClosureCall) \ |
26 V(DoWhile) \ | 26 V(DoWhile) \ |
27 V(If) \ | 27 V(If) \ |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Token::kNoSourcePos, 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(AstNode* node, | 95 LocalVariable* AwaitTransformer::AddToPreambleNewTempVar( |
96 intptr_t token_pos) { | 96 AstNode* node, |
| 97 TokenPosition token_pos) { |
97 LocalVariable* tmp_var = EnsureCurrentTempVar(); | 98 LocalVariable* tmp_var = EnsureCurrentTempVar(); |
98 ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos)); | 99 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource()); |
99 preamble_->Add(new(Z) StoreLocalNode(token_pos, tmp_var, node)); | 100 preamble_->Add(new(Z) StoreLocalNode(token_pos, tmp_var, node)); |
100 NextTempVar(); | 101 NextTempVar(); |
101 return tmp_var; | 102 return tmp_var; |
102 } | 103 } |
103 | 104 |
104 | 105 |
105 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { | 106 void AwaitTransformer::VisitLiteralNode(LiteralNode* node) { |
106 result_ = node; | 107 result_ = node; |
107 } | 108 } |
108 | 109 |
109 | 110 |
110 void AwaitTransformer::VisitTypeNode(TypeNode* node) { | 111 void AwaitTransformer::VisitTypeNode(TypeNode* node) { |
111 result_ = new(Z) TypeNode(node->token_pos(), node->type()); | 112 result_ = new(Z) TypeNode(node->token_pos(), node->type()); |
112 } | 113 } |
113 | 114 |
114 | 115 |
115 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { | 116 void AwaitTransformer::VisitAwaitNode(AwaitNode* node) { |
116 // Await transformation: | 117 // Await transformation: |
117 // | 118 // |
118 // :await_temp_var_X = <expr>; | 119 // :await_temp_var_X = <expr>; |
119 // AwaitMarker(kNewContinuationState); | 120 // AwaitMarker(kNewContinuationState); |
120 // :result_param = _awaitHelper( | 121 // :result_param = _awaitHelper( |
121 // :await_temp_var_X, :async_then_callback, :async_catch_error_callback); | 122 // :await_temp_var_X, :async_then_callback, :async_catch_error_callback); |
122 // return; // (return_type() == kContinuationTarget) | 123 // return; // (return_type() == kContinuationTarget) |
123 // | 124 // |
124 // :saved_try_ctx_var = :await_saved_try_ctx_var_y; | 125 // :saved_try_ctx_var = :await_saved_try_ctx_var_y; |
125 // :await_temp_var_(X+1) = :result_param; | 126 // :await_temp_var_(X+1) = :result_param; |
126 | 127 |
127 const intptr_t token_pos = ST(node->token_pos()); | 128 const TokenPosition token_pos = ST(node->token_pos()); |
128 LocalVariable* async_op = GetVariableInScope( | 129 LocalVariable* async_op = GetVariableInScope( |
129 preamble_->scope(), Symbols::AsyncOperation()); | 130 preamble_->scope(), Symbols::AsyncOperation()); |
130 LocalVariable* async_then_callback = GetVariableInScope( | 131 LocalVariable* async_then_callback = GetVariableInScope( |
131 preamble_->scope(), Symbols::AsyncThenCallback()); | 132 preamble_->scope(), Symbols::AsyncThenCallback()); |
132 LocalVariable* async_catch_error_callback = GetVariableInScope( | 133 LocalVariable* async_catch_error_callback = GetVariableInScope( |
133 preamble_->scope(), Symbols::AsyncCatchErrorCallback()); | 134 preamble_->scope(), Symbols::AsyncCatchErrorCallback()); |
134 LocalVariable* result_param = GetVariableInScope( | 135 LocalVariable* result_param = GetVariableInScope( |
135 preamble_->scope(), Symbols::AsyncOperationParam()); | 136 preamble_->scope(), Symbols::AsyncOperationParam()); |
136 LocalVariable* error_param = GetVariableInScope( | 137 LocalVariable* error_param = GetVariableInScope( |
137 preamble_->scope(), Symbols::AsyncOperationErrorParam()); | 138 preamble_->scope(), Symbols::AsyncOperationErrorParam()); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 | 596 |
596 | 597 |
597 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { | 598 void AwaitTransformer::VisitThrowNode(ThrowNode* node) { |
598 AstNode* new_exception = Transform(node->exception()); | 599 AstNode* new_exception = Transform(node->exception()); |
599 result_ = new(Z) ThrowNode(node->token_pos(), | 600 result_ = new(Z) ThrowNode(node->token_pos(), |
600 new_exception, | 601 new_exception, |
601 node->stacktrace()); | 602 node->stacktrace()); |
602 } | 603 } |
603 | 604 |
604 } // namespace dart | 605 } // namespace dart |
OLD | NEW |