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

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: rebase Created 3 years, 9 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 6798 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/object_test.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698