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

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

Issue 2603383004: Sane asynchronous debugging and stack traces (Closed)
Patch Set: rebase Created 3 years, 11 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
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3450 matching lines...) Expand 10 before | Expand all | Expand 10 after
3461 func.set_modifier(func_modifier); 3461 func.set_modifier(func_modifier);
3462 } 3462 }
3463 3463
3464 OpenBlock(); // Open a nested scope for the outermost function block. 3464 OpenBlock(); // Open a nested scope for the outermost function block.
3465 3465
3466 Function& generated_body_closure = Function::ZoneHandle(Z); 3466 Function& generated_body_closure = Function::ZoneHandle(Z);
3467 if (func.IsAsyncFunction()) { 3467 if (func.IsAsyncFunction()) {
3468 ASSERT(!func.is_generated_body()); 3468 ASSERT(!func.is_generated_body());
3469 // The code of an async function is synthesized. Disable debugging. 3469 // The code of an async function is synthesized. Disable debugging.
3470 func.set_is_debuggable(false); 3470 func.set_is_debuggable(false);
3471 // In order to produce sane asynchronous stacks we rely on this function
3472 // not being inlined.
3473 func.set_is_inlinable(false);
3471 generated_body_closure = OpenAsyncFunction(func.token_pos()); 3474 generated_body_closure = OpenAsyncFunction(func.token_pos());
3472 } else if (func.IsAsyncClosure()) { 3475 } else if (func.IsAsyncClosure()) {
3473 // The closure containing the body of an async function is debuggable. 3476 // The closure containing the body of an async function is debuggable.
3474 ASSERT(func.is_debuggable()); 3477 ASSERT(func.is_debuggable());
3475 OpenAsyncClosure(); 3478 OpenAsyncClosure();
3476 } else if (func.IsSyncGenerator()) { 3479 } else if (func.IsSyncGenerator()) {
3477 // The code of a sync generator is synthesized. Disable debugging. 3480 // The code of a sync generator is synthesized. Disable debugging.
3478 func.set_is_debuggable(false); 3481 func.set_is_debuggable(false);
3479 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos()); 3482 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos());
3480 } else if (func.IsSyncGenClosure()) { 3483 } else if (func.IsSyncGenClosure()) {
(...skipping 3320 matching lines...) Expand 10 before | Expand all | Expand 10 after
6801 } else { 6804 } else {
6802 // Create the closure containing the body of this async function. 6805 // Create the closure containing the body of this async function.
6803 const String& async_func_name = 6806 const String& async_func_name =
6804 String::Handle(Z, innermost_function().name()); 6807 String::Handle(Z, innermost_function().name());
6805 String& closure_name = 6808 String& closure_name =
6806 String::Handle(Z, Symbols::NewFormatted(T, "<%s_async_body>", 6809 String::Handle(Z, Symbols::NewFormatted(T, "<%s_async_body>",
6807 async_func_name.ToCString())); 6810 async_func_name.ToCString()));
6808 closure = Function::NewClosureFunction(closure_name, innermost_function(), 6811 closure = Function::NewClosureFunction(closure_name, innermost_function(),
6809 async_func_pos); 6812 async_func_pos);
6810 closure.set_is_generated_body(true); 6813 closure.set_is_generated_body(true);
6814 // In order to generate sane asynchronous stacks we rely on this function
6815 // not being inlined.
6816 closure.set_is_inlinable(false);
6811 closure.set_result_type(Object::dynamic_type()); 6817 closure.set_result_type(Object::dynamic_type());
6812 is_new_closure = true; 6818 is_new_closure = true;
6813 } 6819 }
6814 // Create the parameter list for the async body closure. 6820 // Create the parameter list for the async body closure.
6815 ParamList closure_params; 6821 ParamList closure_params;
6816 AddAsyncClosureParameters(&closure_params); 6822 AddAsyncClosureParameters(&closure_params);
6817 if (is_new_closure) { 6823 if (is_new_closure) {
6818 // Add the parameters to the newly created closure. 6824 // Add the parameters to the newly created closure.
6819 AddFormalParamsToFunction(&closure_params, closure); 6825 AddFormalParamsToFunction(&closure_params, closure);
6820 6826
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6854 current_block_->scope->AddVariable(await_ctx_var); 6860 current_block_->scope->AddVariable(await_ctx_var);
6855 } 6861 }
6856 6862
6857 6863
6858 void Parser::AddAsyncClosureVariables() { 6864 void Parser::AddAsyncClosureVariables() {
6859 // Add to current block's scope: 6865 // Add to current block's scope:
6860 // var :async_op; 6866 // var :async_op;
6861 // var :async_then_callback; 6867 // var :async_then_callback;
6862 // var :async_catch_error_callback; 6868 // var :async_catch_error_callback;
6863 // var :async_completer; 6869 // var :async_completer;
6870 // var :async_stack_trace;
6864 LocalVariable* async_op_var = 6871 LocalVariable* async_op_var =
6865 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6872 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6866 Symbols::AsyncOperation(), Object::dynamic_type()); 6873 Symbols::AsyncOperation(), Object::dynamic_type());
6867 current_block_->scope->AddVariable(async_op_var); 6874 current_block_->scope->AddVariable(async_op_var);
6868 LocalVariable* async_then_callback_var = new (Z) 6875 LocalVariable* async_then_callback_var = new (Z)
6869 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6876 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6870 Symbols::AsyncThenCallback(), Object::dynamic_type()); 6877 Symbols::AsyncThenCallback(), Object::dynamic_type());
6871 current_block_->scope->AddVariable(async_then_callback_var); 6878 current_block_->scope->AddVariable(async_then_callback_var);
6872 LocalVariable* async_catch_error_callback_var = new (Z) 6879 LocalVariable* async_catch_error_callback_var = new (Z)
6873 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6880 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6874 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); 6881 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type());
6875 current_block_->scope->AddVariable(async_catch_error_callback_var); 6882 current_block_->scope->AddVariable(async_catch_error_callback_var);
6876 LocalVariable* async_completer = 6883 LocalVariable* async_completer =
6877 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6884 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6878 Symbols::AsyncCompleter(), Object::dynamic_type()); 6885 Symbols::AsyncCompleter(), Object::dynamic_type());
6879 current_block_->scope->AddVariable(async_completer); 6886 current_block_->scope->AddVariable(async_completer);
6887 LocalVariable* async_stack_trace = new (Z)
6888 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6889 Symbols::AsyncStackTraceVar(), Object::dynamic_type());
6890 current_block_->scope->AddVariable(async_stack_trace);
6880 } 6891 }
6881 6892
6882 6893
6883 void Parser::AddAsyncGeneratorVariables() { 6894 void Parser::AddAsyncGeneratorVariables() {
6884 // Add to current block's scope: 6895 // Add to current block's scope:
6885 // var :controller; 6896 // var :controller;
6886 // The :controller variable is used by the async generator closure to 6897 // The :controller variable is used by the async generator closure to
6887 // store the StreamController object to which the yielded expressions 6898 // store the StreamController object to which the yielded expressions
6888 // are added. 6899 // are added.
6889 // var :async_op; 6900 // var :async_op;
6890 // var :async_then_callback; 6901 // var :async_then_callback;
6891 // var :async_catch_error_callback; 6902 // var :async_catch_error_callback;
6903 // var :async_stack_trace;
6904 // var :controller_stream
6892 // These variables are used to store the async generator closure containing 6905 // These variables are used to store the async generator closure containing
6893 // the body of the async* function. They are used by the await operator. 6906 // the body of the async* function. They are used by the await operator.
6894 LocalVariable* controller_var = 6907 LocalVariable* controller_var =
6895 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6908 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6896 Symbols::Controller(), Object::dynamic_type()); 6909 Symbols::Controller(), Object::dynamic_type());
6897 current_block_->scope->AddVariable(controller_var); 6910 current_block_->scope->AddVariable(controller_var);
6898 LocalVariable* async_op_var = 6911 LocalVariable* async_op_var =
6899 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6912 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6900 Symbols::AsyncOperation(), Object::dynamic_type()); 6913 Symbols::AsyncOperation(), Object::dynamic_type());
6901 current_block_->scope->AddVariable(async_op_var); 6914 current_block_->scope->AddVariable(async_op_var);
6902 LocalVariable* async_then_callback_var = new (Z) 6915 LocalVariable* async_then_callback_var = new (Z)
6903 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6916 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6904 Symbols::AsyncThenCallback(), Object::dynamic_type()); 6917 Symbols::AsyncThenCallback(), Object::dynamic_type());
6905 current_block_->scope->AddVariable(async_then_callback_var); 6918 current_block_->scope->AddVariable(async_then_callback_var);
6906 LocalVariable* async_catch_error_callback_var = new (Z) 6919 LocalVariable* async_catch_error_callback_var = new (Z)
6907 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 6920 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6908 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type()); 6921 Symbols::AsyncCatchErrorCallback(), Object::dynamic_type());
6909 current_block_->scope->AddVariable(async_catch_error_callback_var); 6922 current_block_->scope->AddVariable(async_catch_error_callback_var);
6923 LocalVariable* async_stack_trace = new (Z)
6924 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6925 Symbols::AsyncStackTraceVar(), Object::dynamic_type());
6926 current_block_->scope->AddVariable(async_stack_trace);
6927 LocalVariable* controller_stream = new (Z)
6928 LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
6929 Symbols::ControllerStream(), Object::dynamic_type());
6930 current_block_->scope->AddVariable(controller_stream);
6910 } 6931 }
6911 6932
6912 6933
6913 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) { 6934 RawFunction* Parser::OpenAsyncGeneratorFunction(TokenPosition async_func_pos) {
6914 TRACE_PARSER("OpenAsyncGeneratorFunction"); 6935 TRACE_PARSER("OpenAsyncGeneratorFunction");
6915 AddContinuationVariables(); 6936 AddContinuationVariables();
6916 AddAsyncGeneratorVariables(); 6937 AddAsyncGeneratorVariables();
6917 6938
6918 Function& closure = Function::Handle(Z); 6939 Function& closure = Function::Handle(Z);
6919 bool is_new_closure = false; 6940 bool is_new_closure = false;
6920 6941
6921 // Check whether a function for the asynchronous function body of 6942 // Check whether a function for the asynchronous function body of
6922 // this async generator has already been created by a previous 6943 // this async generator has already been created by a previous
6923 // compilation of this function. 6944 // compilation of this function.
6924 const Function& found_func = Function::Handle( 6945 const Function& found_func = Function::Handle(
6925 Z, I->LookupClosureFunction(innermost_function(), async_func_pos)); 6946 Z, I->LookupClosureFunction(innermost_function(), async_func_pos));
6926 if (!found_func.IsNull()) { 6947 if (!found_func.IsNull()) {
6927 ASSERT(found_func.IsAsyncGenClosure()); 6948 ASSERT(found_func.IsAsyncGenClosure());
6928 closure = found_func.raw(); 6949 closure = found_func.raw();
6929 } else { 6950 } else {
6930 // Create the closure containing the body of this async generator function. 6951 // Create the closure containing the body of this async generator function.
6931 const String& async_generator_name = 6952 const String& async_generator_name =
6932 String::Handle(Z, innermost_function().name()); 6953 String::Handle(Z, innermost_function().name());
6933 const String& closure_name = String::Handle( 6954 const String& closure_name = String::Handle(
6934 Z, Symbols::NewFormatted(T, "<%s_async_gen_body>", 6955 Z, Symbols::NewFormatted(T, "<%s_async_gen_body>",
6935 async_generator_name.ToCString())); 6956 async_generator_name.ToCString()));
6936 closure = Function::NewClosureFunction(closure_name, innermost_function(), 6957 closure = Function::NewClosureFunction(closure_name, innermost_function(),
6937 async_func_pos); 6958 async_func_pos);
6938 closure.set_is_generated_body(true); 6959 closure.set_is_generated_body(true);
6960 closure.set_is_inlinable(false);
6939 closure.set_result_type(Object::dynamic_type()); 6961 closure.set_result_type(Object::dynamic_type());
6940 is_new_closure = true; 6962 is_new_closure = true;
6941 } 6963 }
6942 6964
6943 ParamList closure_params; 6965 ParamList closure_params;
6944 AddAsyncGenClosureParameters(&closure_params); 6966 AddAsyncGenClosureParameters(&closure_params);
6945 6967
6946 if (is_new_closure) { 6968 if (is_new_closure) {
6947 // Add the parameters to the newly created closure. 6969 // Add the parameters to the newly created closure.
6948 AddFormalParamsToFunction(&closure_params, closure); 6970 AddFormalParamsToFunction(&closure_params, closure);
(...skipping 20 matching lines...) Expand all
6969 // var :controller; 6991 // var :controller;
6970 // var :await_jump_var = -1; 6992 // var :await_jump_var = -1;
6971 // var :await_context_var; 6993 // var :await_context_var;
6972 // f_async_body() { 6994 // f_async_body() {
6973 // ... source code of f ... 6995 // ... source code of f ...
6974 // } 6996 // }
6975 // var :async_op = f_async_body; 6997 // var :async_op = f_async_body;
6976 // var :async_then_callback = _asyncThenWrapperHelper(:async_op); 6998 // var :async_then_callback = _asyncThenWrapperHelper(:async_op);
6977 // var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op); 6999 // var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op);
6978 // :controller = new _AsyncStarStreamController(:async_op); 7000 // :controller = new _AsyncStarStreamController(:async_op);
6979 // return :controller.stream; 7001 // var :controller_stream = :controller.stream;
7002 // return :controller_stream;
6980 // } 7003 // }
6981 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, 7004 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
6982 SequenceNode* closure_body) { 7005 SequenceNode* closure_body) {
6983 TRACE_PARSER("CloseAsyncGeneratorFunction"); 7006 TRACE_PARSER("CloseAsyncGeneratorFunction");
6984 ASSERT(!closure_func.IsNull()); 7007 ASSERT(!closure_func.IsNull());
6985 ASSERT(closure_body != NULL); 7008 ASSERT(closure_body != NULL);
6986 7009
6987 // Explicitly reference variables of the async genenerator function from the 7010 // Explicitly reference variables of the async genenerator function from the
6988 // closure body in order to mark them as captured. 7011 // closure body in order to mark them as captured.
6989 LocalVariable* existing_var = 7012 LocalVariable* existing_var =
6990 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 7013 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6991 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7014 ASSERT((existing_var != NULL) && existing_var->is_captured());
6992 existing_var = 7015 existing_var =
6993 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); 7016 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6994 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7017 ASSERT((existing_var != NULL) && existing_var->is_captured());
6995 existing_var = 7018 existing_var =
6996 closure_body->scope()->LookupVariable(Symbols::Controller(), false); 7019 closure_body->scope()->LookupVariable(Symbols::Controller(), false);
6997 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7020 ASSERT((existing_var != NULL) && existing_var->is_captured());
6998 existing_var = 7021 existing_var =
6999 closure_body->scope()->LookupVariable(Symbols::AsyncOperation(), false); 7022 closure_body->scope()->LookupVariable(Symbols::AsyncOperation(), false);
7000 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7023 ASSERT((existing_var != NULL) && existing_var->is_captured());
7001 existing_var = closure_body->scope()->LookupVariable( 7024 existing_var = closure_body->scope()->LookupVariable(
7002 Symbols::AsyncThenCallback(), false); 7025 Symbols::AsyncThenCallback(), false);
7003 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7026 ASSERT((existing_var != NULL) && existing_var->is_captured());
7004 existing_var = closure_body->scope()->LookupVariable( 7027 existing_var = closure_body->scope()->LookupVariable(
7005 Symbols::AsyncCatchErrorCallback(), false); 7028 Symbols::AsyncCatchErrorCallback(), false);
7006 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7029 ASSERT((existing_var != NULL) && existing_var->is_captured());
7030 existing_var = closure_body->scope()->LookupVariable(
7031 Symbols::AsyncStackTraceVar(), false);
7032 ASSERT((existing_var != NULL) && existing_var->is_captured());
7033 existing_var =
7034 closure_body->scope()->LookupVariable(Symbols::ControllerStream(), false);
7035 ASSERT((existing_var != NULL) && existing_var->is_captured());
7007 7036
7008 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); 7037 const Library& async_lib = Library::Handle(Library::AsyncLibrary());
7009 7038
7010 const Class& controller_class = Class::Handle( 7039 const Class& controller_class = Class::Handle(
7011 Z, 7040 Z,
7012 async_lib.LookupClassAllowPrivate(Symbols::_AsyncStarStreamController())); 7041 async_lib.LookupClassAllowPrivate(Symbols::_AsyncStarStreamController()));
7013 ASSERT(!controller_class.IsNull()); 7042 ASSERT(!controller_class.IsNull());
7014 const Function& controller_constructor = Function::ZoneHandle( 7043 const Function& controller_constructor = Function::ZoneHandle(
7015 Z, controller_class.LookupConstructorAllowPrivate( 7044 Z, controller_class.LookupConstructorAllowPrivate(
7016 Symbols::_AsyncStarStreamControllerConstructor())); 7045 Symbols::_AsyncStarStreamControllerConstructor()));
7017 7046
7047 TokenPosition token_pos = TokenPosition::kNoSource;
7048
7018 // :await_jump_var = -1; 7049 // :await_jump_var = -1;
7019 LocalVariable* jump_var = 7050 LocalVariable* jump_var =
7020 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); 7051 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
7021 LiteralNode* init_value = new (Z) 7052 LiteralNode* init_value = new (Z)
7022 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1))); 7053 LiteralNode(TokenPosition::kNoSource, Smi::ZoneHandle(Smi::New(-1)));
7023 current_block_->statements->Add( 7054 current_block_->statements->Add(
7024 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value)); 7055 new (Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value));
7025 7056
7026 // Add to AST: 7057 // Add to AST:
7027 // :async_op = <closure>; (containing the original body) 7058 // :async_op = <closure>; (containing the original body)
7028 LocalVariable* async_op_var = 7059 LocalVariable* async_op_var =
7029 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); 7060 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
7030 ClosureNode* closure_obj = new (Z) ClosureNode( 7061 ClosureNode* closure_obj = new (Z) ClosureNode(
7031 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope()); 7062 TokenPosition::kNoSource, closure_func, NULL, closure_body->scope());
7032 StoreLocalNode* store_async_op = new (Z) 7063 StoreLocalNode* store_async_op = new (Z)
7033 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj); 7064 StoreLocalNode(TokenPosition::kNoSource, async_op_var, closure_obj);
7034 7065
7035 current_block_->statements->Add(store_async_op); 7066 current_block_->statements->Add(store_async_op);
7036 7067
7068 // Add to AST:
7069 // :async_stack_trace = _asyncStackTraceHelper(:async_op);
7070 const Function& async_stack_trace_helper = Function::ZoneHandle(
7071 Z,
7072 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncStackTraceHelper()));
7073 ASSERT(!async_stack_trace_helper.IsNull());
7074 ArgumentListNode* async_stack_trace_helper_args =
7075 new (Z) ArgumentListNode(TokenPosition::kNoSource);
7076 async_stack_trace_helper_args->Add(
7077 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var));
7078 StaticCallNode* async_stack_trace_helper_call = new (Z) StaticCallNode(
7079 token_pos, async_stack_trace_helper, async_stack_trace_helper_args);
7080 LocalVariable* async_stack_trace_var = current_block_->scope->LookupVariable(
7081 Symbols::AsyncStackTraceVar(), false);
7082 StoreLocalNode* store_async_stack_trace = new (Z) StoreLocalNode(
7083 token_pos, async_stack_trace_var, async_stack_trace_helper_call);
7084 current_block_->statements->Add(store_async_stack_trace);
7085
7037 // :async_then_callback = _asyncThenWrapperHelper(:async_op) 7086 // :async_then_callback = _asyncThenWrapperHelper(:async_op)
7038 const Function& async_then_wrapper_helper = Function::ZoneHandle( 7087 const Function& async_then_wrapper_helper = Function::ZoneHandle(
7039 Z, 7088 Z,
7040 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncThenWrapperHelper())); 7089 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncThenWrapperHelper()));
7041 ASSERT(!async_then_wrapper_helper.IsNull()); 7090 ASSERT(!async_then_wrapper_helper.IsNull());
7042 ArgumentListNode* async_then_wrapper_helper_args = 7091 ArgumentListNode* async_then_wrapper_helper_args =
7043 new (Z) ArgumentListNode(TokenPosition::kNoSource); 7092 new (Z) ArgumentListNode(TokenPosition::kNoSource);
7044 async_then_wrapper_helper_args->Add( 7093 async_then_wrapper_helper_args->Add(
7045 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var)); 7094 new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var));
7046 StaticCallNode* then_wrapper_call = new (Z) 7095 StaticCallNode* then_wrapper_call = new (Z)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
7083 ConstructorCallNode* controller_constructor_call = 7132 ConstructorCallNode* controller_constructor_call =
7084 new (Z) ConstructorCallNode(TokenPosition::kNoSource, 7133 new (Z) ConstructorCallNode(TokenPosition::kNoSource,
7085 TypeArguments::ZoneHandle(Z), 7134 TypeArguments::ZoneHandle(Z),
7086 controller_constructor, arguments); 7135 controller_constructor, arguments);
7087 LocalVariable* controller_var = 7136 LocalVariable* controller_var =
7088 current_block_->scope->LookupVariable(Symbols::Controller(), false); 7137 current_block_->scope->LookupVariable(Symbols::Controller(), false);
7089 StoreLocalNode* store_controller = new (Z) StoreLocalNode( 7138 StoreLocalNode* store_controller = new (Z) StoreLocalNode(
7090 TokenPosition::kNoSource, controller_var, controller_constructor_call); 7139 TokenPosition::kNoSource, controller_var, controller_constructor_call);
7091 current_block_->statements->Add(store_controller); 7140 current_block_->statements->Add(store_controller);
7092 7141
7093 // return :controller.stream; 7142 // Grab :controller.stream
7143 InstanceGetterNode* controller_stream = new (Z) InstanceGetterNode(
7144 TokenPosition::kNoSource,
7145 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var),
7146 Symbols::Stream());
7147
7148 // Store :controller.stream into :controller_stream inside the closure.
7149 // We have to remember the stream because a new instance is generated for
7150 // each getter invocation and in order to recreate the linkage, we need the
7151 // awaited on instance.
7152 LocalVariable* controller_stream_var =
7153 current_block_->scope->LookupVariable(Symbols::ControllerStream(), false);
7154 ASSERT(controller_stream_var != NULL);
7155
7156 StoreLocalNode* store_controller_stream = new (Z) StoreLocalNode(
7157 TokenPosition::kNoSource, controller_stream_var, controller_stream);
7158 current_block_->statements->Add(store_controller_stream);
7159
7160 // return :controller_stream;
7094 ReturnNode* return_node = new (Z) ReturnNode( 7161 ReturnNode* return_node = new (Z) ReturnNode(
7095 TokenPosition::kNoSource, 7162 TokenPosition::kNoSource,
7096 new (Z) InstanceGetterNode( 7163 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_stream_var));
7097 TokenPosition::kNoSource,
7098 new (Z) LoadLocalNode(TokenPosition::kNoSource, controller_var),
7099 Symbols::Stream()));
7100 current_block_->statements->Add(return_node); 7164 current_block_->statements->Add(return_node);
7101 return CloseBlock(); 7165 return CloseBlock();
7102 } 7166 }
7103 7167
7104 7168
7105 void Parser::OpenAsyncGeneratorClosure() { 7169 void Parser::OpenAsyncGeneratorClosure() {
7106 async_temp_scope_ = current_block_->scope; 7170 async_temp_scope_ = current_block_->scope;
7107 OpenAsyncTryBlock(); 7171 OpenAsyncTryBlock();
7108 } 7172 }
7109 7173
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
7159 // closure body in order to mark them as captured. 7223 // closure body in order to mark them as captured.
7160 LocalVariable* existing_var = 7224 LocalVariable* existing_var =
7161 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 7225 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
7162 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7226 ASSERT((existing_var != NULL) && existing_var->is_captured());
7163 existing_var = 7227 existing_var =
7164 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); 7228 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
7165 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7229 ASSERT((existing_var != NULL) && existing_var->is_captured());
7166 existing_var = 7230 existing_var =
7167 closure_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); 7231 closure_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
7168 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7232 ASSERT((existing_var != NULL) && existing_var->is_captured());
7233 existing_var = closure_body->scope()->LookupVariable(
7234 Symbols::AsyncStackTraceVar(), false);
7235 ASSERT((existing_var != NULL) && existing_var->is_captured());
7169 7236
7170 // Create and return a new future that executes a closure with the current 7237 // Create and return a new future that executes a closure with the current
7171 // body. 7238 // body.
7172 7239
7173 // No need to capture parameters or other variables, since they have already 7240 // No need to capture parameters or other variables, since they have already
7174 // been captured in the corresponding scope as the body has been parsed within 7241 // been captured in the corresponding scope as the body has been parsed within
7175 // a nested block (contained in the async function's block). 7242 // a nested block (contained in the async function's block).
7176 const Class& future = Class::ZoneHandle(Z, I->object_store()->future_class()); 7243 const Class& future = Class::ZoneHandle(Z, I->object_store()->future_class());
7177 ASSERT(!future.IsNull()); 7244 ASSERT(!future.IsNull());
7178 const Function& constructor = Function::ZoneHandle( 7245 const Function& constructor = Function::ZoneHandle(
7179 Z, future.LookupFunction(Symbols::FutureMicrotask())); 7246 Z, future.LookupFunction(Symbols::FutureMicrotask()));
7180 ASSERT(!constructor.IsNull()); 7247 ASSERT(!constructor.IsNull());
7181 const Class& completer = 7248 const Class& completer =
7182 Class::ZoneHandle(Z, I->object_store()->completer_class()); 7249 Class::ZoneHandle(Z, I->object_store()->completer_class());
7183 ASSERT(!completer.IsNull()); 7250 ASSERT(!completer.IsNull());
7184 const Function& completer_constructor = Function::ZoneHandle( 7251 const Function& completer_constructor = Function::ZoneHandle(
7185 Z, completer.LookupFunction(Symbols::CompleterSyncConstructor())); 7252 Z, completer.LookupFunction(Symbols::CompleterSyncConstructor()));
7186 ASSERT(!completer_constructor.IsNull()); 7253 ASSERT(!completer_constructor.IsNull());
7187 7254
7255 const Library& async_lib = Library::Handle(Library::AsyncLibrary());
7256
7188 LocalVariable* async_completer = 7257 LocalVariable* async_completer =
7189 current_block_->scope->LookupVariable(Symbols::AsyncCompleter(), false); 7258 current_block_->scope->LookupVariable(Symbols::AsyncCompleter(), false);
7190 7259
7191 const TokenPosition token_pos = ST(closure_body->token_pos()); 7260 const TokenPosition token_pos = ST(closure_body->token_pos());
7192 // Add to AST: 7261 // Add to AST:
7193 // :async_completer = new Completer.sync(); 7262 // :async_completer = new Completer.sync();
7194 ArgumentListNode* empty_args = new (Z) ArgumentListNode(token_pos); 7263 ArgumentListNode* empty_args = new (Z) ArgumentListNode(token_pos);
7195 ConstructorCallNode* completer_constructor_node = 7264 ConstructorCallNode* completer_constructor_node =
7196 new (Z) ConstructorCallNode(token_pos, TypeArguments::ZoneHandle(Z), 7265 new (Z) ConstructorCallNode(token_pos, TypeArguments::ZoneHandle(Z),
7197 completer_constructor, empty_args); 7266 completer_constructor, empty_args);
(...skipping 12 matching lines...) Expand all
7210 // Add to AST: 7279 // Add to AST:
7211 // :async_op = <closure>; (containing the original body) 7280 // :async_op = <closure>; (containing the original body)
7212 LocalVariable* async_op_var = 7281 LocalVariable* async_op_var =
7213 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); 7282 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
7214 ClosureNode* cn = 7283 ClosureNode* cn =
7215 new (Z) ClosureNode(token_pos, closure, NULL, closure_body->scope()); 7284 new (Z) ClosureNode(token_pos, closure, NULL, closure_body->scope());
7216 StoreLocalNode* store_async_op = 7285 StoreLocalNode* store_async_op =
7217 new (Z) StoreLocalNode(token_pos, async_op_var, cn); 7286 new (Z) StoreLocalNode(token_pos, async_op_var, cn);
7218 current_block_->statements->Add(store_async_op); 7287 current_block_->statements->Add(store_async_op);
7219 7288
7220 const Library& async_lib = Library::Handle(Library::AsyncLibrary()); 7289 // Add to AST:
7290 // :async_stack_trace = _asyncStackTraceHelper(:async_op);
7291 const Function& async_stack_trace_helper = Function::ZoneHandle(
7292 Z,
7293 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncStackTraceHelper()));
7294 ASSERT(!async_stack_trace_helper.IsNull());
7295 ArgumentListNode* async_stack_trace_helper_args =
7296 new (Z) ArgumentListNode(token_pos);
7297 async_stack_trace_helper_args->Add(
7298 new (Z) LoadLocalNode(token_pos, async_op_var));
7299 StaticCallNode* async_stack_trace_helper_call = new (Z) StaticCallNode(
7300 token_pos, async_stack_trace_helper, async_stack_trace_helper_args);
7301 LocalVariable* async_stack_trace_var = current_block_->scope->LookupVariable(
7302 Symbols::AsyncStackTraceVar(), false);
7303 StoreLocalNode* store_async_stack_trace = new (Z) StoreLocalNode(
7304 token_pos, async_stack_trace_var, async_stack_trace_helper_call);
7305 current_block_->statements->Add(store_async_stack_trace);
7306
7221 // :async_then_callback = _asyncThenWrapperHelper(:async_op) 7307 // :async_then_callback = _asyncThenWrapperHelper(:async_op)
7222 const Function& async_then_wrapper_helper = Function::ZoneHandle( 7308 const Function& async_then_wrapper_helper = Function::ZoneHandle(
7223 Z, 7309 Z,
7224 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncThenWrapperHelper())); 7310 async_lib.LookupFunctionAllowPrivate(Symbols::AsyncThenWrapperHelper()));
7225 ASSERT(!async_then_wrapper_helper.IsNull()); 7311 ASSERT(!async_then_wrapper_helper.IsNull());
7226 ArgumentListNode* async_then_wrapper_helper_args = 7312 ArgumentListNode* async_then_wrapper_helper_args =
7227 new (Z) ArgumentListNode(token_pos); 7313 new (Z) ArgumentListNode(token_pos);
7228 async_then_wrapper_helper_args->Add( 7314 async_then_wrapper_helper_args->Add(
7229 new (Z) LoadLocalNode(token_pos, async_op_var)); 7315 new (Z) LoadLocalNode(token_pos, async_op_var));
7230 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( 7316 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode(
(...skipping 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after
8772 // contexts and if they have a matching token position range, 8858 // contexts and if they have a matching token position range,
8773 // it can be an issue (cf. bug 26941). 8859 // it can be an issue (cf. bug 26941).
8774 OpenBlock(); 8860 OpenBlock();
8775 const Block* await_for_block = current_block_; 8861 const Block* await_for_block = current_block_;
8776 8862
8777 const TokenPosition stream_expr_pos = TokenPos(); 8863 const TokenPosition stream_expr_pos = TokenPos();
8778 AstNode* stream_expr = 8864 AstNode* stream_expr =
8779 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 8865 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
8780 ExpectToken(Token::kRPAREN); 8866 ExpectToken(Token::kRPAREN);
8781 8867
8868 // Create :stream to store the stream into temporarily.
8869 LocalVariable* stream_var =
8870 new (Z) LocalVariable(stream_expr_pos, stream_expr_pos,
8871 Symbols::ColonStream(), Object::dynamic_type());
8872 current_block_->scope->AddVariable(stream_var);
8873
8874 // Store the stream expression into a variable.
8875 StoreLocalNode* store_stream_var =
8876 new (Z) StoreLocalNode(stream_expr_pos, stream_var, stream_expr);
8877 current_block_->statements->Add(store_stream_var);
8878
8879 // Register the awaiter on the stream by invoking `_asyncStarListenHelper`.
8880 const Library& async_lib = Library::Handle(Library::AsyncLibrary());
8881 const Function& async_star_listen_helper = Function::ZoneHandle(
8882 Z,
8883 async_lib.LookupFunctionAllowPrivate(Symbols::_AsyncStarListenHelper()));
8884 ASSERT(!async_star_listen_helper.IsNull());
8885 LocalVariable* async_op_var =
8886 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
8887 ASSERT(async_op_var != NULL);
8888 ArgumentListNode* async_star_listen_helper_args =
8889 new (Z) ArgumentListNode(stream_expr_pos);
8890 async_star_listen_helper_args->Add(
8891 new (Z) LoadLocalNode(stream_expr_pos, stream_var));
8892 async_star_listen_helper_args->Add(
8893 new (Z) LoadLocalNode(stream_expr_pos, async_op_var));
8894 StaticCallNode* async_star_listen_helper_call = new (Z) StaticCallNode(
8895 stream_expr_pos, async_star_listen_helper, async_star_listen_helper_args);
8896 current_block_->statements->Add(async_star_listen_helper_call);
8897
8782 // Build creation of implicit StreamIterator. 8898 // Build creation of implicit StreamIterator.
8783 // var :for-in-iter = new StreamIterator(stream_expr). 8899 // var :for-in-iter = new StreamIterator(stream_expr).
8784 const Class& stream_iterator_cls = 8900 const Class& stream_iterator_cls =
8785 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); 8901 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class());
8786 ASSERT(!stream_iterator_cls.IsNull()); 8902 ASSERT(!stream_iterator_cls.IsNull());
8787 const Function& iterator_ctor = Function::ZoneHandle( 8903 const Function& iterator_ctor = Function::ZoneHandle(
8788 Z, 8904 Z,
8789 stream_iterator_cls.LookupFunction(Symbols::StreamIteratorConstructor())); 8905 stream_iterator_cls.LookupFunction(Symbols::StreamIteratorConstructor()));
8790 ASSERT(!iterator_ctor.IsNull()); 8906 ASSERT(!iterator_ctor.IsNull());
8791 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos); 8907 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos);
8792 ctor_args->Add(stream_expr); 8908 ctor_args->Add(new (Z) LoadLocalNode(stream_expr_pos, stream_var));
8793 ConstructorCallNode* ctor_call = new (Z) ConstructorCallNode( 8909 ConstructorCallNode* ctor_call = new (Z) ConstructorCallNode(
8794 stream_expr_pos, TypeArguments::ZoneHandle(Z), iterator_ctor, ctor_args); 8910 stream_expr_pos, TypeArguments::ZoneHandle(Z), iterator_ctor, ctor_args);
8795 const AbstractType& iterator_type = Object::dynamic_type(); 8911 const AbstractType& iterator_type = Object::dynamic_type();
8796 LocalVariable* iterator_var = new (Z) LocalVariable( 8912 LocalVariable* iterator_var = new (Z) LocalVariable(
8797 stream_expr_pos, stream_expr_pos, Symbols::ForInIter(), iterator_type); 8913 stream_expr_pos, stream_expr_pos, Symbols::ForInIter(), iterator_type);
8798 current_block_->scope->AddVariable(iterator_var); 8914 current_block_->scope->AddVariable(iterator_var);
8799 AstNode* iterator_init = 8915 AstNode* iterator_init =
8800 new (Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call); 8916 new (Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call);
8801 current_block_->statements->Add(iterator_init); 8917 current_block_->statements->Add(iterator_init);
8802 8918
(...skipping 24 matching lines...) Expand all
8827 LocalVariable* saved_try_ctx; 8943 LocalVariable* saved_try_ctx;
8828 LocalVariable* async_saved_try_ctx; 8944 LocalVariable* async_saved_try_ctx;
8829 LocalVariable* outer_saved_try_ctx; 8945 LocalVariable* outer_saved_try_ctx;
8830 LocalVariable* outer_async_saved_try_ctx; 8946 LocalVariable* outer_async_saved_try_ctx;
8831 CheckAsyncOpInTryBlock(&saved_try_ctx, &async_saved_try_ctx, 8947 CheckAsyncOpInTryBlock(&saved_try_ctx, &async_saved_try_ctx,
8832 &outer_saved_try_ctx, &outer_async_saved_try_ctx); 8948 &outer_saved_try_ctx, &outer_async_saved_try_ctx);
8833 ArgumentListNode* no_args = new (Z) ArgumentListNode(stream_expr_pos); 8949 ArgumentListNode* no_args = new (Z) ArgumentListNode(stream_expr_pos);
8834 AstNode* iterator_moveNext = new (Z) InstanceCallNode( 8950 AstNode* iterator_moveNext = new (Z) InstanceCallNode(
8835 stream_expr_pos, new (Z) LoadLocalNode(stream_expr_pos, iterator_var), 8951 stream_expr_pos, new (Z) LoadLocalNode(stream_expr_pos, iterator_var),
8836 Symbols::MoveNext(), no_args); 8952 Symbols::MoveNext(), no_args);
8953
8837 OpenBlock(); 8954 OpenBlock();
8955 // Give the debugger an opportunity to 'step into' the generator by
8956 // calling '_asyncStarMoveNextHelper'.
8957 const Function& async_star_move_next_helper =
8958 Function::ZoneHandle(Z, async_lib.LookupFunctionAllowPrivate(
8959 Symbols::_AsyncStarMoveNextHelper()));
8960 ASSERT(!async_star_move_next_helper.IsNull());
8961 ASSERT(async_op_var != NULL);
8962 ArgumentListNode* async_star_move_next_helper_args =
8963 new (Z) ArgumentListNode(stream_expr_pos);
8964 async_star_move_next_helper_args->Add(
8965 new (Z) LoadLocalNode(stream_expr_pos, stream_var));
8966 StaticCallNode* async_star_move_next_helper_call =
8967 new (Z) StaticCallNode(stream_expr_pos, async_star_move_next_helper,
8968 async_star_move_next_helper_args);
8969 current_block_->statements->Add(async_star_move_next_helper_call);
8838 AstNode* await_moveNext = new (Z) AwaitNode( 8970 AstNode* await_moveNext = new (Z) AwaitNode(
8839 stream_expr_pos, iterator_moveNext, saved_try_ctx, async_saved_try_ctx, 8971 stream_expr_pos, iterator_moveNext, saved_try_ctx, async_saved_try_ctx,
8840 outer_saved_try_ctx, outer_async_saved_try_ctx, current_block_->scope); 8972 outer_saved_try_ctx, outer_async_saved_try_ctx, current_block_->scope);
8841 AwaitTransformer at(current_block_->statements, async_temp_scope_); 8973 AwaitTransformer at(current_block_->statements, async_temp_scope_);
8842 await_moveNext = at.Transform(await_moveNext); 8974 await_moveNext = at.Transform(await_moveNext);
8843 SequenceNode* await_preamble = CloseBlock(); 8975 SequenceNode* await_preamble = CloseBlock();
8844 8976
8845 // Parse the for loop body. Ideally, we would use ParseNestedStatement() 8977 // Parse the for loop body. Ideally, we would use ParseNestedStatement()
8846 // here, but that does not work well because we have to insert an implicit 8978 // here, but that does not work well because we have to insert an implicit
8847 // variable assignment and potentially a variable declaration in the 8979 // variable assignment and potentially a variable declaration in the
(...skipping 5820 matching lines...) Expand 10 before | Expand all | Expand 10 after
14668 const ArgumentListNode& function_args, 14800 const ArgumentListNode& function_args,
14669 const LocalVariable* temp_for_last_arg, 14801 const LocalVariable* temp_for_last_arg,
14670 bool is_super_invocation) { 14802 bool is_super_invocation) {
14671 UNREACHABLE(); 14803 UNREACHABLE();
14672 return NULL; 14804 return NULL;
14673 } 14805 }
14674 14806
14675 } // namespace dart 14807 } // namespace dart
14676 14808
14677 #endif // DART_PRECOMPILED_RUNTIME 14809 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698