Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: runtime/vm/parser.cc

Issue 2692803006: Track the 'awaiter return' call stack use it to detect uncaught exceptions in async functions (Closed)
Patch Set: port to other architectures Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698