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