OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/parser.h" | 5 #include "vm/parser.h" |
6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 6798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6809 LocalVariable* saved_stack_trace_var = NULL; | 6809 LocalVariable* saved_stack_trace_var = NULL; |
6810 SetupExceptionVariables(current_block_->scope, true, &context_var, | 6810 SetupExceptionVariables(current_block_->scope, true, &context_var, |
6811 &exception_var, &stack_trace_var, | 6811 &exception_var, &stack_trace_var, |
6812 &saved_exception_var, &saved_stack_trace_var); | 6812 &saved_exception_var, &saved_stack_trace_var); |
6813 | 6813 |
6814 // Open the try block. | 6814 // Open the try block. |
6815 OpenBlock(); | 6815 OpenBlock(); |
6816 // This is the outermost try-catch in the function. | 6816 // This is the outermost try-catch in the function. |
6817 ASSERT(try_stack_ == NULL); | 6817 ASSERT(try_stack_ == NULL); |
6818 PushTry(current_block_); | 6818 PushTry(current_block_); |
| 6819 // Validate that we always get try index of 0. |
| 6820 ASSERT(try_stack_->try_index() == CatchClauseNode::kImplicitAsyncTryIndex); |
6819 | 6821 |
6820 SetupSavedTryContext(context_var); | 6822 SetupSavedTryContext(context_var); |
6821 } | 6823 } |
6822 | 6824 |
6823 | 6825 |
6824 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6826 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
6825 // Create the parameter list for the body closure of a sync generator: | 6827 // Create the parameter list for the body closure of a sync generator: |
6826 // 1) Implicit closure parameter; | 6828 // 1) Implicit closure parameter; |
6827 // 2) Iterator | 6829 // 2) Iterator |
6828 // Add implicit closure parameter if not already present. | 6830 // Add implicit closure parameter if not already present. |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7078 void Parser::AddAsyncGeneratorVariables() { | 7080 void Parser::AddAsyncGeneratorVariables() { |
7079 // Add to current block's scope: | 7081 // Add to current block's scope: |
7080 // var :controller; | 7082 // var :controller; |
7081 // The :controller variable is used by the async generator closure to | 7083 // The :controller variable is used by the async generator closure to |
7082 // store the StreamController object to which the yielded expressions | 7084 // store the StreamController object to which the yielded expressions |
7083 // are added. | 7085 // are added. |
7084 // var :async_op; | 7086 // var :async_op; |
7085 // var :async_then_callback; | 7087 // var :async_then_callback; |
7086 // var :async_catch_error_callback; | 7088 // var :async_catch_error_callback; |
7087 // var :async_stack_trace; | 7089 // var :async_stack_trace; |
| 7090 // var :controller_stream; |
7088 // These variables are used to store the async generator closure containing | 7091 // These variables are used to store the async generator closure containing |
7089 // the body of the async* function. They are used by the await operator. | 7092 // the body of the async* function. They are used by the await operator. |
7090 LocalVariable* controller_var = | 7093 LocalVariable* controller_var = |
7091 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7094 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7092 Symbols::Controller(), Object::dynamic_type()); | 7095 Symbols::Controller(), Object::dynamic_type()); |
7093 current_block_->scope->AddVariable(controller_var); | 7096 current_block_->scope->AddVariable(controller_var); |
7094 LocalVariable* async_op_var = | 7097 LocalVariable* async_op_var = |
7095 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7098 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7096 Symbols::AsyncOperation(), Object::dynamic_type()); | 7099 Symbols::AsyncOperation(), Object::dynamic_type()); |
7097 current_block_->scope->AddVariable(async_op_var); | 7100 current_block_->scope->AddVariable(async_op_var); |
7098 LocalVariable* async_then_callback_var = new (Z) | 7101 LocalVariable* async_then_callback_var = new (Z) |
7099 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7102 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7100 Symbols::AsyncThenCallback(), Object::dynamic_type()); | 7103 Symbols::AsyncThenCallback(), Object::dynamic_type()); |
7101 current_block_->scope->AddVariable(async_then_callback_var); | 7104 current_block_->scope->AddVariable(async_then_callback_var); |
7102 LocalVariable* async_catch_error_callback_var = new (Z) | 7105 LocalVariable* async_catch_error_callback_var = new (Z) |
7103 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7106 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7104 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); | 7107 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); |
7105 current_block_->scope->AddVariable(async_catch_error_callback_var); | 7108 current_block_->scope->AddVariable(async_catch_error_callback_var); |
7106 LocalVariable* async_stack_trace = new (Z) | 7109 LocalVariable* async_stack_trace = new (Z) |
7107 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, | 7110 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
7108 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); | 7111 Symbols::AsyncStackTraceVar(), Object::dynamic_type()); |
7109 current_block_->scope->AddVariable(async_stack_trace); | 7112 current_block_->scope->AddVariable(async_stack_trace); |
| 7113 LocalVariable* controller_stream = new (Z) |
| 7114 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, |
| 7115 Symbols::ControllerStream(), Object::dynamic_type()); |
| 7116 current_block_->scope->AddVariable(controller_stream); |
7110 } | 7117 } |
7111 | 7118 |
7112 | 7119 |
7113 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { | 7120 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { |
7114 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 7121 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
7115 AddContinuationVariables(); | 7122 AddContinuationVariables(); |
7116 AddAsyncGeneratorVariables(); | 7123 AddAsyncGeneratorVariables(); |
7117 | 7124 |
7118 Function& closure = Function::Handle(Z); | 7125 Function& closure = Function::Handle(Z); |
7119 bool is_new_closure = false; | 7126 bool is_new_closure = false; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7169 // var :controller; | 7176 // var :controller; |
7170 // var :await_jump_var = -1; | 7177 // var :await_jump_var = -1; |
7171 // var :await_context_var; | 7178 // var :await_context_var; |
7172 // f_async_body() { | 7179 // f_async_body() { |
7173 // ... source code of f ... | 7180 // ... source code of f ... |
7174 // } | 7181 // } |
7175 // var :async_op = f_async_body; | 7182 // var :async_op = f_async_body; |
7176 // var :async_then_callback = _asyncThenWrapperHelper(:async_op); | 7183 // var :async_then_callback = _asyncThenWrapperHelper(:async_op); |
7177 // var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op); | 7184 // var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op); |
7178 // :controller = new _AsyncStarStreamController(:async_op); | 7185 // :controller = new _AsyncStarStreamController(:async_op); |
7179 // return :controller.stream; | 7186 // var :controller_stream = :controller.stream; |
| 7187 // return :controller_stream; |
7180 // } | 7188 // } |
7181 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, | 7189 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, |
7182 SequenceNode* closure_body) { | 7190 SequenceNode* closure_body) { |
7183 TRACE_PARSER("CloseAsyncGeneratorFunction"); | 7191 TRACE_PARSER("CloseAsyncGeneratorFunction"); |
7184 ASSERT(!closure_func.IsNull()); | 7192 ASSERT(!closure_func.IsNull()); |
7185 ASSERT(closure_body != NULL); | 7193 ASSERT(closure_body != NULL); |
7186 | 7194 |
7187 // Explicitly reference variables of the async genenerator function from the | 7195 // Explicitly reference variables of the async genenerator function from the |
7188 // closure body in order to mark them as captured. | 7196 // closure body in order to mark them as captured. |
7189 LocalVariable* existing_var = | 7197 LocalVariable* existing_var = |
(...skipping 10 matching lines...) Expand all Loading... |
7200 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7208 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7201 existing_var = closure_body->scope()->LookupVariable( | 7209 existing_var = closure_body->scope()->LookupVariable( |
7202 Symbols::AsyncThenCallback(), false); | 7210 Symbols::AsyncThenCallback(), false); |
7203 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7211 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7204 existing_var = closure_body->scope()->LookupVariable( | 7212 existing_var = closure_body->scope()->LookupVariable( |
7205 Symbols::AsyncCatchErrorCallback(), false); | 7213 Symbols::AsyncCatchErrorCallback(), false); |
7206 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7214 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7207 existing_var = closure_body->scope()->LookupVariable( | 7215 existing_var = closure_body->scope()->LookupVariable( |
7208 Symbols::AsyncStackTraceVar(), false); | 7216 Symbols::AsyncStackTraceVar(), false); |
7209 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 7217 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 7218 existing_var = |
| 7219 closure_body->scope()->LookupVariable(Symbols::ControllerStream(), false); |
| 7220 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
7210 | 7221 |
7211 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); | 7222 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); |
7212 | 7223 |
7213 const Class& controller_class = Class::Handle( | 7224 const Class& controller_class = Class::Handle( |
7214 Z, | 7225 Z, |
7215 async_lib.LookupClassAllowPrivate(Symbols::_AsyncStarStreamController())); | 7226 async_lib.LookupClassAllowPrivate(Symbols::_AsyncStarStreamController())); |
7216 ASSERT(!controller_class.IsNull()); | 7227 ASSERT(!controller_class.IsNull()); |
7217 const Function& controller_constructor = Function::ZoneHandle( | 7228 const Function& controller_constructor = Function::ZoneHandle( |
7218 Z, controller_class.LookupConstructorAllowPrivate( | 7229 Z, controller_class.LookupConstructorAllowPrivate( |
7219 Symbols::_AsyncStarStreamControllerConstructor())); | 7230 Symbols::_AsyncStarStreamControllerConstructor())); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7308 ConstructorCallNode* controller_constructor_call = | 7319 ConstructorCallNode* controller_constructor_call = |
7309 new (Z) ConstructorCallNode(TokenPosition::kNoSource, | 7320 new (Z) ConstructorCallNode(TokenPosition::kNoSource, |
7310 TypeArguments::ZoneHandle(Z), | 7321 TypeArguments::ZoneHandle(Z), |
7311 controller_constructor, arguments); | 7322 controller_constructor, arguments); |
7312 LocalVariable* controller_var = | 7323 LocalVariable* controller_var = |
7313 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 7324 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
7314 StoreLocalNode* store_controller = new (Z) StoreLocalNode( | 7325 StoreLocalNode* store_controller = new (Z) StoreLocalNode( |
7315 TokenPosition::kNoSource, controller_var, controller_constructor_call); | 7326 TokenPosition::kNoSource, controller_var, controller_constructor_call); |
7316 current_block_->statements->Add(store_controller); | 7327 current_block_->statements->Add(store_controller); |
7317 | 7328 |
| 7329 // Grab :controller.stream |
| 7330 InstanceGetterNode* controller_stream = new (Z) InstanceGetterNode( |
| 7331 TokenPosition::kNoSource, |
| 7332 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var), |
| 7333 Symbols::Stream()); |
| 7334 |
| 7335 // Store :controller.stream into :controller_stream inside the closure. |
| 7336 // We have to remember the stream because a new instance is generated for |
| 7337 // each getter invocation and in order to recreate the linkage, we need the |
| 7338 // awaited on instance. |
| 7339 LocalVariable* controller_stream_var = |
| 7340 current_block_->scope->LookupVariable(Symbols::ControllerStream(), false); |
| 7341 ASSERT(controller_stream_var != NULL); |
| 7342 |
| 7343 StoreLocalNode* store_controller_stream = new (Z) StoreLocalNode( |
| 7344 TokenPosition::kNoSource, controller_stream_var, controller_stream); |
| 7345 current_block_->statements->Add(store_controller_stream); |
| 7346 |
7318 // return :controller.stream; | 7347 // return :controller.stream; |
7319 ReturnNode* return_node = new (Z) ReturnNode( | 7348 ReturnNode* return_node = new (Z) ReturnNode( |
7320 TokenPosition::kNoSource, | 7349 TokenPosition::kNoSource, |
7321 new (Z) InstanceGetterNode( | 7350 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var)); |
7322 TokenPosition::kNoSource, | |
7323 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var), | |
7324 Symbols::Stream())); | |
7325 current_block_->statements->Add(return_node); | 7351 current_block_->statements->Add(return_node); |
7326 return CloseBlock(); | 7352 return CloseBlock(); |
7327 } | 7353 } |
7328 | 7354 |
7329 | 7355 |
7330 void Parser::OpenAsyncGeneratorClosure() { | 7356 void Parser::OpenAsyncGeneratorClosure() { |
7331 async_temp_scope_ = current_block_->scope; | 7357 async_temp_scope_ = current_block_->scope; |
7332 OpenAsyncTryBlock(); | 7358 OpenAsyncTryBlock(); |
7333 } | 7359 } |
7334 | 7360 |
(...skipping 1723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9058 // contexts and if they have a matching token position range, | 9084 // contexts and if they have a matching token position range, |
9059 // it can be an issue (cf. bug 26941). | 9085 // it can be an issue (cf. bug 26941). |
9060 OpenBlock(); | 9086 OpenBlock(); |
9061 const Block* await_for_block = current_block_; | 9087 const Block* await_for_block = current_block_; |
9062 | 9088 |
9063 const TokenPosition stream_expr_pos = TokenPos(); | 9089 const TokenPosition stream_expr_pos = TokenPos(); |
9064 AstNode* stream_expr = | 9090 AstNode* stream_expr = |
9065 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9091 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
9066 ExpectToken(Token::kRPAREN); | 9092 ExpectToken(Token::kRPAREN); |
9067 | 9093 |
| 9094 // Create :stream to store the stream into temporarily. |
| 9095 LocalVariable* stream_var = |
| 9096 new (Z) LocalVariable(stream_expr_pos, stream_expr_pos, |
| 9097 Symbols::ColonStream(), Object::dynamic_type()); |
| 9098 current_block_->scope->AddVariable(stream_var); |
| 9099 |
| 9100 // Store the stream expression into a variable. |
| 9101 StoreLocalNode* store_stream_var = |
| 9102 new (Z) StoreLocalNode(stream_expr_pos, stream_var, stream_expr); |
| 9103 current_block_->statements->Add(store_stream_var); |
| 9104 |
| 9105 // Register the awaiter on the stream by invoking `_asyncStarListenHelper`. |
| 9106 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); |
| 9107 const Function& async_star_listen_helper = Function::ZoneHandle( |
| 9108 Z, |
| 9109 async_lib.LookupFunctionAllowPrivate(Symbols::_AsyncStarListenHelper())); |
| 9110 ASSERT(!async_star_listen_helper.IsNull()); |
| 9111 LocalVariable* async_op_var = |
| 9112 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
| 9113 ASSERT(async_op_var != NULL); |
| 9114 ArgumentListNode* async_star_listen_helper_args = |
| 9115 new (Z) ArgumentListNode(stream_expr_pos); |
| 9116 async_star_listen_helper_args->Add( |
| 9117 new (Z) LoadLocalNode(stream_expr_pos, stream_var)); |
| 9118 async_star_listen_helper_args->Add( |
| 9119 new (Z) LoadLocalNode(stream_expr_pos, async_op_var)); |
| 9120 StaticCallNode* async_star_listen_helper_call = new (Z) StaticCallNode( |
| 9121 stream_expr_pos, async_star_listen_helper, async_star_listen_helper_args); |
| 9122 |
| 9123 current_block_->statements->Add(async_star_listen_helper_call); |
| 9124 |
9068 // Build creation of implicit StreamIterator. | 9125 // Build creation of implicit StreamIterator. |
9069 // var :for-in-iter = new StreamIterator(stream_expr). | 9126 // var :for-in-iter = new StreamIterator(stream_expr). |
9070 const Class& stream_iterator_cls = | 9127 const Class& stream_iterator_cls = |
9071 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); | 9128 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); |
9072 ASSERT(!stream_iterator_cls.IsNull()); | 9129 ASSERT(!stream_iterator_cls.IsNull()); |
9073 const Function& iterator_ctor = Function::ZoneHandle( | 9130 const Function& iterator_ctor = Function::ZoneHandle( |
9074 Z, | 9131 Z, |
9075 stream_iterator_cls.LookupFunction(Symbols::StreamIteratorConstructor())); | 9132 stream_iterator_cls.LookupFunction(Symbols::StreamIteratorConstructor())); |
9076 ASSERT(!iterator_ctor.IsNull()); | 9133 ASSERT(!iterator_ctor.IsNull()); |
9077 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos); | 9134 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos); |
9078 ctor_args->Add(stream_expr); | 9135 ctor_args->Add(new (Z) LoadLocalNode(stream_expr_pos, stream_var)); |
9079 ConstructorCallNode* ctor_call = new (Z) ConstructorCallNode( | 9136 ConstructorCallNode* ctor_call = new (Z) ConstructorCallNode( |
9080 stream_expr_pos, TypeArguments::ZoneHandle(Z), iterator_ctor, ctor_args); | 9137 stream_expr_pos, TypeArguments::ZoneHandle(Z), iterator_ctor, ctor_args); |
9081 const AbstractType& iterator_type = Object::dynamic_type(); | 9138 const AbstractType& iterator_type = Object::dynamic_type(); |
9082 LocalVariable* iterator_var = new (Z) LocalVariable( | 9139 LocalVariable* iterator_var = new (Z) LocalVariable( |
9083 stream_expr_pos, stream_expr_pos, Symbols::ForInIter(), iterator_type); | 9140 stream_expr_pos, stream_expr_pos, Symbols::ForInIter(), iterator_type); |
9084 current_block_->scope->AddVariable(iterator_var); | 9141 current_block_->scope->AddVariable(iterator_var); |
9085 AstNode* iterator_init = | 9142 AstNode* iterator_init = |
9086 new (Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call); | 9143 new (Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call); |
9087 current_block_->statements->Add(iterator_init); | 9144 current_block_->statements->Add(iterator_init); |
9088 | 9145 |
(...skipping 5985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15074 const ArgumentListNode& function_args, | 15131 const ArgumentListNode& function_args, |
15075 const LocalVariable* temp_for_last_arg, | 15132 const LocalVariable* temp_for_last_arg, |
15076 bool is_super_invocation) { | 15133 bool is_super_invocation) { |
15077 UNREACHABLE(); | 15134 UNREACHABLE(); |
15078 return NULL; | 15135 return NULL; |
15079 } | 15136 } |
15080 | 15137 |
15081 } // namespace dart | 15138 } // namespace dart |
15082 | 15139 |
15083 #endif // DART_PRECOMPILED_RUNTIME | 15140 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |