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

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

Issue 1308163006: Reduce the number of captured variables in async code, by only capturing local (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: address comments Created 5 years, 3 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/flow_graph_builder.cc ('k') | runtime/vm/scopes.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 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 3472 matching lines...) Expand 10 before | Expand all | Expand 10 after
3483 SequenceNode* body = CloseBlock(); 3483 SequenceNode* body = CloseBlock();
3484 if (func.IsAsyncFunction()) { 3484 if (func.IsAsyncFunction()) {
3485 body = CloseAsyncFunction(generated_body_closure, body); 3485 body = CloseAsyncFunction(generated_body_closure, body);
3486 generated_body_closure.set_end_token_pos(end_token_pos); 3486 generated_body_closure.set_end_token_pos(end_token_pos);
3487 } else if (func.IsAsyncClosure()) { 3487 } else if (func.IsAsyncClosure()) {
3488 body = CloseAsyncClosure(body); 3488 body = CloseAsyncClosure(body);
3489 } else if (func.IsSyncGenerator()) { 3489 } else if (func.IsSyncGenerator()) {
3490 body = CloseSyncGenFunction(generated_body_closure, body); 3490 body = CloseSyncGenFunction(generated_body_closure, body);
3491 generated_body_closure.set_end_token_pos(end_token_pos); 3491 generated_body_closure.set_end_token_pos(end_token_pos);
3492 } else if (func.IsSyncGenClosure()) { 3492 } else if (func.IsSyncGenClosure()) {
3493 body->scope()->RecursivelyCaptureAllVariables(); 3493 // body is unchanged.
3494 } else if (func.IsAsyncGenerator()) { 3494 } else if (func.IsAsyncGenerator()) {
3495 body = CloseAsyncGeneratorFunction(generated_body_closure, body); 3495 body = CloseAsyncGeneratorFunction(generated_body_closure, body);
3496 generated_body_closure.set_end_token_pos(end_token_pos); 3496 generated_body_closure.set_end_token_pos(end_token_pos);
3497 } else if (func.IsAsyncGenClosure()) { 3497 } else if (func.IsAsyncGenClosure()) {
3498 body = CloseAsyncGeneratorClosure(body); 3498 body = CloseAsyncGeneratorClosure(body);
3499 } 3499 }
3500 EnsureHasReturnStatement(body, end_token_pos); 3500 EnsureHasReturnStatement(body, end_token_pos);
3501 current_block_->statements->Add(body); 3501 current_block_->statements->Add(body);
3502 innermost_function_ = saved_innermost_function.raw(); 3502 innermost_function_ = saved_innermost_function.raw();
3503 last_used_try_index_ = saved_try_index; 3503 last_used_try_index_ = saved_try_index;
(...skipping 2808 matching lines...) Expand 10 before | Expand all | Expand 10 after
6312 OpenBlock(); 6312 OpenBlock();
6313 ArgumentListNode* no_args = 6313 ArgumentListNode* no_args =
6314 new(Z) ArgumentListNode(Scanner::kNoSourcePos); 6314 new(Z) ArgumentListNode(Scanner::kNoSourcePos);
6315 current_block_->statements->Add( 6315 current_block_->statements->Add(
6316 new(Z) InstanceCallNode(try_end_pos, 6316 new(Z) InstanceCallNode(try_end_pos,
6317 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller), 6317 new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
6318 Symbols::Close(), 6318 Symbols::Close(),
6319 no_args)); 6319 no_args));
6320 6320
6321 // Suspend after the close. 6321 // Suspend after the close.
6322 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode(); 6322 AwaitMarkerNode* await_marker =
6323 await_marker->set_scope(current_block_->scope); 6323 new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
6324 current_block_->statements->Add(await_marker); 6324 current_block_->statements->Add(await_marker);
6325 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); 6325 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
6326 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); 6326 continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
6327 current_block_->statements->Add(continuation_ret); 6327 current_block_->statements->Add(continuation_ret);
6328 6328
6329 finally_clause = CloseBlock(); 6329 finally_clause = CloseBlock();
6330 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); 6330 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
6331 if (node_to_inline != NULL) { 6331 if (node_to_inline != NULL) {
6332 InlinedFinallyNode* node = 6332 InlinedFinallyNode* node =
6333 new(Z) InlinedFinallyNode(try_end_pos, 6333 new(Z) InlinedFinallyNode(try_end_pos,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
6602 } 6602 }
6603 6603
6604 OpenFunctionBlock(body); 6604 OpenFunctionBlock(body);
6605 AddFormalParamsToScope(&closure_params, current_block_->scope); 6605 AddFormalParamsToScope(&closure_params, current_block_->scope);
6606 async_temp_scope_ = current_block_->scope; 6606 async_temp_scope_ = current_block_->scope;
6607 return body.raw(); 6607 return body.raw();
6608 } 6608 }
6609 6609
6610 SequenceNode* Parser::CloseSyncGenFunction(const Function& closure, 6610 SequenceNode* Parser::CloseSyncGenFunction(const Function& closure,
6611 SequenceNode* closure_body) { 6611 SequenceNode* closure_body) {
6612 // Explicitly reference variables of the sync generator function from the
6613 // closure body in order to mark them as captured.
6612 LocalVariable* existing_var = 6614 LocalVariable* existing_var =
6613 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 6615 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
6614 ASSERT((existing_var != NULL) && existing_var->is_captured()); 6616 ASSERT((existing_var != NULL) && existing_var->is_captured());
6615 existing_var = 6617 existing_var =
6616 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); 6618 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
6617 ASSERT((existing_var != NULL) && existing_var->is_captured()); 6619 ASSERT((existing_var != NULL) && existing_var->is_captured());
6618 6620
6619 // :await_jump_var = -1; 6621 // :await_jump_var = -1;
6620 LocalVariable* jump_var = 6622 LocalVariable* jump_var =
6621 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); 6623 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
6747 6749
6748 6750
6749 void Parser::AddContinuationVariables() { 6751 void Parser::AddContinuationVariables() {
6750 // Add to current block's scope: 6752 // Add to current block's scope:
6751 // var :await_jump_var; 6753 // var :await_jump_var;
6752 // var :await_ctx_var; 6754 // var :await_ctx_var;
6753 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6755 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6754 LocalVariable* await_jump_var = new (Z) LocalVariable( 6756 LocalVariable* await_jump_var = new (Z) LocalVariable(
6755 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type); 6757 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type);
6756 current_block_->scope->AddVariable(await_jump_var); 6758 current_block_->scope->AddVariable(await_jump_var);
6757 current_block_->scope->CaptureVariable(await_jump_var);
6758 LocalVariable* await_ctx_var = new (Z) LocalVariable( 6759 LocalVariable* await_ctx_var = new (Z) LocalVariable(
6759 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type); 6760 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type);
6760 current_block_->scope->AddVariable(await_ctx_var); 6761 current_block_->scope->AddVariable(await_ctx_var);
6761 current_block_->scope->CaptureVariable(await_ctx_var);
6762 } 6762 }
6763 6763
6764 6764
6765 void Parser::AddAsyncClosureVariables() { 6765 void Parser::AddAsyncClosureVariables() {
6766 // Add to current block's scope: 6766 // Add to current block's scope:
6767 // var :async_op; 6767 // var :async_op;
6768 // var :async_then_callback; 6768 // var :async_then_callback;
6769 // var :async_catch_error_callback; 6769 // var :async_catch_error_callback;
6770 // var :async_completer; 6770 // var :async_completer;
6771 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6771 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6772 LocalVariable* async_op_var = new(Z) LocalVariable( 6772 LocalVariable* async_op_var = new(Z) LocalVariable(
6773 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); 6773 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
6774 current_block_->scope->AddVariable(async_op_var); 6774 current_block_->scope->AddVariable(async_op_var);
6775 current_block_->scope->CaptureVariable(async_op_var);
6776 LocalVariable* async_then_callback_var = new(Z) LocalVariable( 6775 LocalVariable* async_then_callback_var = new(Z) LocalVariable(
6777 Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type); 6776 Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
6778 current_block_->scope->AddVariable(async_then_callback_var); 6777 current_block_->scope->AddVariable(async_then_callback_var);
6779 current_block_->scope->CaptureVariable(async_then_callback_var);
6780 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( 6778 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
6781 Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type); 6779 Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
6782 current_block_->scope->AddVariable(async_catch_error_callback_var); 6780 current_block_->scope->AddVariable(async_catch_error_callback_var);
6783 current_block_->scope->CaptureVariable(async_catch_error_callback_var);
6784 LocalVariable* async_completer = new(Z) LocalVariable( 6781 LocalVariable* async_completer = new(Z) LocalVariable(
6785 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); 6782 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type);
6786 current_block_->scope->AddVariable(async_completer); 6783 current_block_->scope->AddVariable(async_completer);
6787 current_block_->scope->CaptureVariable(async_completer);
6788 } 6784 }
6789 6785
6790 6786
6791 void Parser::AddAsyncGeneratorVariables() { 6787 void Parser::AddAsyncGeneratorVariables() {
6792 // Add to current block's scope: 6788 // Add to current block's scope:
6793 // var :controller; 6789 // var :controller;
6794 // The :controller variable is used by the async generator closure to 6790 // The :controller variable is used by the async generator closure to
6795 // store the StreamController object to which the yielded expressions 6791 // store the StreamController object to which the yielded expressions
6796 // are added. 6792 // are added.
6797 // var :async_op; 6793 // var :async_op;
6798 // var :async_then_callback; 6794 // var :async_then_callback;
6799 // var :async_catch_error_callback; 6795 // var :async_catch_error_callback;
6800 // These variables are used to store the async generator closure containing 6796 // These variables are used to store the async generator closure containing
6801 // the body of the async* function. They are used by the await operator. 6797 // the body of the async* function. They are used by the await operator.
6802 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); 6798 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
6803 LocalVariable* controller_var = new(Z) LocalVariable( 6799 LocalVariable* controller_var = new(Z) LocalVariable(
6804 Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type); 6800 Scanner::kNoSourcePos, Symbols::Controller(), dynamic_type);
6805 current_block_->scope->AddVariable(controller_var); 6801 current_block_->scope->AddVariable(controller_var);
6806 current_block_->scope->CaptureVariable(controller_var);
6807 LocalVariable* async_op_var = new(Z) LocalVariable( 6802 LocalVariable* async_op_var = new(Z) LocalVariable(
6808 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); 6803 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type);
6809 current_block_->scope->AddVariable(async_op_var); 6804 current_block_->scope->AddVariable(async_op_var);
6810 current_block_->scope->CaptureVariable(async_op_var);
6811 LocalVariable* async_then_callback_var = new(Z) LocalVariable( 6805 LocalVariable* async_then_callback_var = new(Z) LocalVariable(
6812 Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type); 6806 Scanner::kNoSourcePos, Symbols::AsyncThenCallback(), dynamic_type);
6813 current_block_->scope->AddVariable(async_then_callback_var); 6807 current_block_->scope->AddVariable(async_then_callback_var);
6814 current_block_->scope->CaptureVariable(async_then_callback_var);
6815 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( 6808 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
6816 Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type); 6809 Scanner::kNoSourcePos, Symbols::AsyncCatchErrorCallback(), dynamic_type);
6817 current_block_->scope->AddVariable(async_catch_error_callback_var); 6810 current_block_->scope->AddVariable(async_catch_error_callback_var);
6818 current_block_->scope->CaptureVariable(async_catch_error_callback_var);
6819 } 6811 }
6820 6812
6821 6813
6822 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) { 6814 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) {
6823 TRACE_PARSER("OpenAsyncGeneratorFunction"); 6815 TRACE_PARSER("OpenAsyncGeneratorFunction");
6824 AddContinuationVariables(); 6816 AddContinuationVariables();
6825 AddAsyncGeneratorVariables(); 6817 AddAsyncGeneratorVariables();
6826 6818
6827 Function& closure = Function::Handle(Z); 6819 Function& closure = Function::Handle(Z);
6828 bool is_new_closure = false; 6820 bool is_new_closure = false;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6900 // var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op); 6892 // var :async_catch_error_callback = _asyncCatchErrorWrapperHelper(:async_op);
6901 // :controller = new _AsyncStarStreamController(:async_op); 6893 // :controller = new _AsyncStarStreamController(:async_op);
6902 // return :controller.stream; 6894 // return :controller.stream;
6903 // } 6895 // }
6904 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func, 6896 SequenceNode* Parser::CloseAsyncGeneratorFunction(const Function& closure_func,
6905 SequenceNode* closure_body) { 6897 SequenceNode* closure_body) {
6906 TRACE_PARSER("CloseAsyncGeneratorFunction"); 6898 TRACE_PARSER("CloseAsyncGeneratorFunction");
6907 ASSERT(!closure_func.IsNull()); 6899 ASSERT(!closure_func.IsNull());
6908 ASSERT(closure_body != NULL); 6900 ASSERT(closure_body != NULL);
6909 6901
6910 // Make sure the implicit variables of the async generator function 6902 // Explicitly reference variables of the async genenerator function from the
6911 // are captured. 6903 // closure body in order to mark them as captured.
6912 LocalVariable* existing_var = closure_body->scope()->LookupVariable( 6904 LocalVariable* existing_var = closure_body->scope()->LookupVariable(
6913 Symbols::AwaitJumpVar(), false); 6905 Symbols::AwaitJumpVar(), false);
6914 ASSERT((existing_var != NULL) && existing_var->is_captured()); 6906 ASSERT((existing_var != NULL) && existing_var->is_captured());
6915 existing_var = closure_body->scope()->LookupVariable( 6907 existing_var = closure_body->scope()->LookupVariable(
6916 Symbols::AwaitContextVar(), false); 6908 Symbols::AwaitContextVar(), false);
6917 ASSERT((existing_var != NULL) && existing_var->is_captured()); 6909 ASSERT((existing_var != NULL) && existing_var->is_captured());
6918 existing_var = closure_body->scope()->LookupVariable( 6910 existing_var = closure_body->scope()->LookupVariable(
6919 Symbols::Controller(), false); 6911 Symbols::Controller(), false);
6920 ASSERT((existing_var != NULL) && existing_var->is_captured()); 6912 ASSERT((existing_var != NULL) && existing_var->is_captured());
6921 existing_var = closure_body->scope()->LookupVariable( 6913 existing_var = closure_body->scope()->LookupVariable(
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
7039 } 7031 }
7040 7032
7041 7033
7042 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { 7034 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) {
7043 // We need a temporary expression to store intermediate return values. 7035 // We need a temporary expression to store intermediate return values.
7044 parsed_function()->EnsureExpressionTemp(); 7036 parsed_function()->EnsureExpressionTemp();
7045 7037
7046 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); 7038 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body);
7047 ASSERT(new_body != NULL); 7039 ASSERT(new_body != NULL);
7048 ASSERT(new_body->scope() != NULL); 7040 ASSERT(new_body->scope() != NULL);
7049
7050 // Implicitly mark those variables below as captured. We currently mark all
7051 // variables of all scopes as captured, but as soon as we do something
7052 // smarter we rely on these internal variables to be available.
7053 LocalVariable* existing_var = new_body->scope()->LookupVariable(
7054 Symbols::AwaitJumpVar(), false);
7055 ASSERT((existing_var != NULL) && existing_var->is_captured());
7056 existing_var = new_body->scope()->LookupVariable(
7057 Symbols::AwaitContextVar(), false);
7058 ASSERT((existing_var != NULL) && existing_var->is_captured());
7059 existing_var = new_body->scope()->LookupVariable(
7060 Symbols::Controller(), false);
7061 ASSERT((existing_var != NULL) && existing_var->is_captured());
7062 existing_var = new_body->scope()->LookupVariable(
7063 Symbols::AsyncOperationParam(), false);
7064 ASSERT(existing_var != NULL);
7065 existing_var = new_body->scope()->LookupVariable(
7066 Symbols::AsyncOperationErrorParam(), false);
7067 ASSERT(existing_var != NULL);
7068 existing_var = new_body->scope()->LookupVariable(
7069 Symbols::AsyncOperationStackTraceParam(), false);
7070 ASSERT(existing_var != NULL);
7071 new_body->scope()->RecursivelyCaptureAllVariables();
7072 return new_body; 7041 return new_body;
7073 } 7042 }
7074 7043
7075 7044
7076 // Add a return node to the sequence if necessary. 7045 // Add a return node to the sequence if necessary.
7077 void Parser::EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos) { 7046 void Parser::EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos) {
7078 if ((seq->length() == 0) || 7047 if ((seq->length() == 0) ||
7079 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { 7048 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) {
7080 const Function& func = innermost_function(); 7049 const Function& func = innermost_function();
7081 // The implicit return value of synchronous generator closures is false, 7050 // The implicit return value of synchronous generator closures is false,
(...skipping 19 matching lines...) Expand all
7101 return statements; 7070 return statements;
7102 } 7071 }
7103 7072
7104 7073
7105 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, 7074 SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
7106 SequenceNode* closure_body) { 7075 SequenceNode* closure_body) {
7107 TRACE_PARSER("CloseAsyncFunction"); 7076 TRACE_PARSER("CloseAsyncFunction");
7108 ASSERT(!closure.IsNull()); 7077 ASSERT(!closure.IsNull());
7109 ASSERT(closure_body != NULL); 7078 ASSERT(closure_body != NULL);
7110 7079
7080 // Explicitly reference variables of the async function from the
7081 // closure body in order to mark them as captured.
7111 LocalVariable* existing_var = 7082 LocalVariable* existing_var =
7112 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 7083 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
7113 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7084 ASSERT((existing_var != NULL) && existing_var->is_captured());
7114 existing_var = 7085 existing_var =
7115 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); 7086 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
7116 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7087 ASSERT((existing_var != NULL) && existing_var->is_captured());
7117 existing_var = 7088 existing_var =
7118 closure_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false); 7089 closure_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
7119 ASSERT((existing_var != NULL) && existing_var->is_captured()); 7090 ASSERT((existing_var != NULL) && existing_var->is_captured());
7120 7091
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
7244 async_completer), 7215 async_completer),
7245 Symbols::CompleterFuture())); 7216 Symbols::CompleterFuture()));
7246 current_block_->statements->Add(return_node); 7217 current_block_->statements->Add(return_node);
7247 return CloseBlock(); 7218 return CloseBlock();
7248 } 7219 }
7249 7220
7250 7221
7251 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { 7222 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) {
7252 // We need a temporary expression to store intermediate return values. 7223 // We need a temporary expression to store intermediate return values.
7253 parsed_function()->EnsureExpressionTemp(); 7224 parsed_function()->EnsureExpressionTemp();
7254 // Implicitly mark those variables below as captured. We currently mark all 7225
7255 // variables of all scopes as captured (below), but as soon as we do something
7256 // smarter we rely on these internal variables to be available.
7257 SequenceNode* new_body = CloseAsyncTryBlock(body); 7226 SequenceNode* new_body = CloseAsyncTryBlock(body);
7258 ASSERT(new_body != NULL); 7227 ASSERT(new_body != NULL);
7259 ASSERT(new_body->scope() != NULL); 7228 ASSERT(new_body->scope() != NULL);
7260 LocalVariable* existing_var =
7261 new_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
7262 ASSERT((existing_var != NULL) && existing_var->is_captured());
7263 existing_var =
7264 new_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false);
7265 ASSERT((existing_var != NULL) && existing_var->is_captured());
7266 existing_var =
7267 new_body->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
7268 ASSERT((existing_var != NULL) && existing_var->is_captured());
7269 new_body->scope()->RecursivelyCaptureAllVariables();
7270 return new_body; 7229 return new_body;
7271 } 7230 }
7272 7231
7273 7232
7274 // Set up default values for all optional parameters to the function. 7233 // Set up default values for all optional parameters to the function.
7275 void Parser::SetupDefaultsForOptionalParams(const ParamList& params) { 7234 void Parser::SetupDefaultsForOptionalParams(const ParamList& params) {
7276 if ((current_function().raw() == innermost_function().raw()) && 7235 if ((current_function().raw() == innermost_function().raw()) &&
7277 (params.num_optional_parameters > 0)) { 7236 (params.num_optional_parameters > 0)) {
7278 ZoneGrowableArray<const Instance*>* default_values = 7237 ZoneGrowableArray<const Instance*>* default_values =
7279 new ZoneGrowableArray<const Instance*>(zone(), 7238 new ZoneGrowableArray<const Instance*>(zone(),
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after
8536 8495
8537 static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope, 8496 static LocalVariable* LookupAsyncSavedTryContextVar(LocalScope* scope,
8538 uint16_t try_index) { 8497 uint16_t try_index) {
8539 const String& async_saved_try_ctx_name = 8498 const String& async_saved_try_ctx_name =
8540 String::ZoneHandle(Symbols::New(String::Handle( 8499 String::ZoneHandle(Symbols::New(String::Handle(
8541 String::NewFormatted( 8500 String::NewFormatted(
8542 "%s%d", 8501 "%s%d",
8543 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), 8502 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
8544 try_index)))); 8503 try_index))));
8545 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name); 8504 LocalVariable* var = scope->LocalLookupVariable(async_saved_try_ctx_name);
8546 ASSERT((var != NULL) && var->is_captured()); 8505 ASSERT(var != NULL);
8547 return var; 8506 return var;
8548 } 8507 }
8549 8508
8550 8509
8551 // If the await or yield being parsed is in a try block, the continuation code 8510 // If the await or yield being parsed is in a try block, the continuation code
8552 // needs to restore the corresponding stack-based variable :saved_try_ctx_var, 8511 // needs to restore the corresponding stack-based variable :saved_try_ctx_var,
8553 // and the stack-based variable :saved_try_ctx_var of the outer try block. 8512 // and the stack-based variable :saved_try_ctx_var of the outer try block.
8554 // The inner :saved_try_ctx_var is used by a finally clause handling an 8513 // The inner :saved_try_ctx_var is used by a finally clause handling an
8555 // exception thrown by the continuation code in a try block or catch block. 8514 // exception thrown by the continuation code in a try block or catch block.
8556 // If no finally clause exists, the catch or finally clause of the outer try 8515 // If no finally clause exists, the catch or finally clause of the outer try
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
8728 CheckAsyncOpInTryBlock(&saved_try_ctx, 8687 CheckAsyncOpInTryBlock(&saved_try_ctx,
8729 &async_saved_try_ctx, 8688 &async_saved_try_ctx,
8730 &outer_saved_try_ctx, 8689 &outer_saved_try_ctx,
8731 &outer_async_saved_try_ctx); 8690 &outer_async_saved_try_ctx);
8732 ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos); 8691 ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos);
8733 AstNode* iterator_moveNext = new(Z) InstanceCallNode( 8692 AstNode* iterator_moveNext = new(Z) InstanceCallNode(
8734 stream_pos, 8693 stream_pos,
8735 new(Z) LoadLocalNode(stream_pos, iterator_var), 8694 new(Z) LoadLocalNode(stream_pos, iterator_var),
8736 Symbols::MoveNext(), 8695 Symbols::MoveNext(),
8737 no_args); 8696 no_args);
8697 OpenBlock();
8738 AstNode* await_moveNext = 8698 AstNode* await_moveNext =
8739 new(Z) AwaitNode(stream_pos, 8699 new(Z) AwaitNode(stream_pos,
8740 iterator_moveNext, 8700 iterator_moveNext,
8741 saved_try_ctx, 8701 saved_try_ctx,
8742 async_saved_try_ctx, 8702 async_saved_try_ctx,
8743 outer_saved_try_ctx, 8703 outer_saved_try_ctx,
8744 outer_async_saved_try_ctx); 8704 outer_async_saved_try_ctx,
8745 OpenBlock(); 8705 current_block_->scope);
8746 AwaitTransformer at(current_block_->statements, async_temp_scope_); 8706 AwaitTransformer at(current_block_->statements, async_temp_scope_);
8747 await_moveNext = at.Transform(await_moveNext); 8707 await_moveNext = at.Transform(await_moveNext);
8748 SequenceNode* await_preamble = CloseBlock(); 8708 SequenceNode* await_preamble = CloseBlock();
8749 8709
8750 // Parse the for loop body. Ideally, we would use ParseNestedStatement() 8710 // Parse the for loop body. Ideally, we would use ParseNestedStatement()
8751 // here, but that does not work well because we have to insert an implicit 8711 // here, but that does not work well because we have to insert an implicit
8752 // variable assignment and potentially a variable declaration in the 8712 // variable assignment and potentially a variable declaration in the
8753 // loop body. 8713 // loop body.
8754 OpenLoopBlock(); 8714 OpenLoopBlock();
8755 8715
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
9567 Symbols::New(String::Handle(Z, 9527 Symbols::New(String::Handle(Z,
9568 String::NewFormatted("%s%d", 9528 String::NewFormatted("%s%d",
9569 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), 9529 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
9570 last_used_try_index_ - 1)))); 9530 last_used_try_index_ - 1))));
9571 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( 9531 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
9572 Scanner::kNoSourcePos, 9532 Scanner::kNoSourcePos,
9573 async_saved_try_ctx_name, 9533 async_saved_try_ctx_name,
9574 Type::ZoneHandle(Z, Type::DynamicType())); 9534 Type::ZoneHandle(Z, Type::DynamicType()));
9575 ASSERT(async_temp_scope_ != NULL); 9535 ASSERT(async_temp_scope_ != NULL);
9576 async_temp_scope_->AddVariable(async_saved_try_ctx); 9536 async_temp_scope_->AddVariable(async_saved_try_ctx);
9577 current_block_->scope->CaptureVariable(async_saved_try_ctx);
9578 ASSERT(saved_try_context != NULL); 9537 ASSERT(saved_try_context != NULL);
9579 current_block_->statements->Add(new(Z) StoreLocalNode( 9538 current_block_->statements->Add(new(Z) StoreLocalNode(
9580 Scanner::kNoSourcePos, 9539 Scanner::kNoSourcePos,
9581 async_saved_try_ctx, 9540 async_saved_try_ctx,
9582 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context))); 9541 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context)));
9583 } 9542 }
9584 9543
9585 9544
9586 // We create three variables for exceptions: 9545 // We create three variables for exceptions:
9587 // ':saved_try_context_var' - Used to save the context before the start of 9546 // ':saved_try_context_var' - Used to save the context before the start of
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
9901 yield->AddNode(store_current); 9860 yield->AddNode(store_current);
9902 if (is_yield_each) { 9861 if (is_yield_each) {
9903 // Generate :iterator.isYieldEach = true; 9862 // Generate :iterator.isYieldEach = true;
9904 AstNode* set_is_yield_each = 9863 AstNode* set_is_yield_each =
9905 new(Z) InstanceSetterNode(Scanner::kNoSourcePos, 9864 new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
9906 iterator, 9865 iterator,
9907 String::ZoneHandle(Symbols::IsYieldEach().raw()), 9866 String::ZoneHandle(Symbols::IsYieldEach().raw()),
9908 new(Z) LiteralNode(TokenPos(), Bool::True())); 9867 new(Z) LiteralNode(TokenPos(), Bool::True()));
9909 yield->AddNode(set_is_yield_each); 9868 yield->AddNode(set_is_yield_each);
9910 } 9869 }
9911 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode(); 9870 AwaitMarkerNode* await_marker =
9912 await_marker->set_scope(current_block_->scope); 9871 new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
9913 yield->AddNode(await_marker); 9872 yield->AddNode(await_marker);
9914 // Return true to indicate that a value has been generated. 9873 // Return true to indicate that a value has been generated.
9915 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, 9874 ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
9916 new(Z) LiteralNode(TokenPos(), Bool::True())); 9875 new(Z) LiteralNode(TokenPos(), Bool::True()));
9917 return_true->set_return_type(ReturnNode::kContinuationTarget); 9876 return_true->set_return_type(ReturnNode::kContinuationTarget);
9918 yield->AddNode(return_true); 9877 yield->AddNode(return_true);
9919 9878
9920 // If this expression is part of a try block, also append the code for 9879 // If this expression is part of a try block, also append the code for
9921 // restoring the saved try context that lives on the stack and possibly the 9880 // restoring the saved try context that lives on the stack and possibly the
9922 // saved try context of the outer try block. 9881 // saved try context of the outer try block.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
9969 9928
9970 SequenceNode* true_branch = 9929 SequenceNode* true_branch =
9971 new(Z) SequenceNode(Scanner::kNoSourcePos, NULL); 9930 new(Z) SequenceNode(Scanner::kNoSourcePos, NULL);
9972 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); 9931 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos);
9973 true_branch->Add(return_from_generator); 9932 true_branch->Add(return_from_generator);
9974 AddNodeForFinallyInlining(return_from_generator); 9933 AddNodeForFinallyInlining(return_from_generator);
9975 AstNode* if_is_cancelled = 9934 AstNode* if_is_cancelled =
9976 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL); 9935 new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
9977 yield->AddNode(if_is_cancelled); 9936 yield->AddNode(if_is_cancelled);
9978 9937
9979 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode(); 9938 AwaitMarkerNode* await_marker =
9980 await_marker->set_scope(current_block_->scope); 9939 new(Z) AwaitMarkerNode(async_temp_scope_, current_block_->scope);
9981 yield->AddNode(await_marker); 9940 yield->AddNode(await_marker);
9982 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); 9941 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
9983 continuation_return->set_return_type(ReturnNode::kContinuationTarget); 9942 continuation_return->set_return_type(ReturnNode::kContinuationTarget);
9984 yield->AddNode(continuation_return); 9943 yield->AddNode(continuation_return);
9985 9944
9986 // If this expression is part of a try block, also append the code for 9945 // If this expression is part of a try block, also append the code for
9987 // restoring the saved try context that lives on the stack and possibly the 9946 // restoring the saved try context that lives on the stack and possibly the
9988 // saved try context of the outer try block. 9947 // saved try context of the outer try block.
9989 LocalVariable* saved_try_ctx; 9948 LocalVariable* saved_try_ctx;
9990 LocalVariable* async_saved_try_ctx; 9949 LocalVariable* async_saved_try_ctx;
(...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after
10990 LocalVariable* outer_async_saved_try_ctx; 10949 LocalVariable* outer_async_saved_try_ctx;
10991 CheckAsyncOpInTryBlock(&saved_try_ctx, 10950 CheckAsyncOpInTryBlock(&saved_try_ctx,
10992 &async_saved_try_ctx, 10951 &async_saved_try_ctx,
10993 &outer_saved_try_ctx, 10952 &outer_saved_try_ctx,
10994 &outer_async_saved_try_ctx); 10953 &outer_async_saved_try_ctx);
10995 expr = new (Z) AwaitNode(op_pos, 10954 expr = new (Z) AwaitNode(op_pos,
10996 ParseUnaryExpr(), 10955 ParseUnaryExpr(),
10997 saved_try_ctx, 10956 saved_try_ctx,
10998 async_saved_try_ctx, 10957 async_saved_try_ctx,
10999 outer_saved_try_ctx, 10958 outer_saved_try_ctx,
11000 outer_async_saved_try_ctx); 10959 outer_async_saved_try_ctx,
10960 current_block_->scope);
11001 } else if (IsPrefixOperator(CurrentToken())) { 10961 } else if (IsPrefixOperator(CurrentToken())) {
11002 Token::Kind unary_op = CurrentToken(); 10962 Token::Kind unary_op = CurrentToken();
11003 if (unary_op == Token::kSUB) { 10963 if (unary_op == Token::kSUB) {
11004 unary_op = Token::kNEGATE; 10964 unary_op = Token::kNEGATE;
11005 } 10965 }
11006 ConsumeToken(); 10966 ConsumeToken();
11007 expr = ParseUnaryExpr(); 10967 expr = ParseUnaryExpr();
11008 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { 10968 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) {
11009 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); 10969 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode());
11010 } else { 10970 } else {
(...skipping 3291 matching lines...) Expand 10 before | Expand all | Expand 10 after
14302 void Parser::SkipQualIdent() { 14262 void Parser::SkipQualIdent() {
14303 ASSERT(IsIdentifier()); 14263 ASSERT(IsIdentifier());
14304 ConsumeToken(); 14264 ConsumeToken();
14305 if (CurrentToken() == Token::kPERIOD) { 14265 if (CurrentToken() == Token::kPERIOD) {
14306 ConsumeToken(); // Consume the kPERIOD token. 14266 ConsumeToken(); // Consume the kPERIOD token.
14307 ExpectIdentifier("identifier expected after '.'"); 14267 ExpectIdentifier("identifier expected after '.'");
14308 } 14268 }
14309 } 14269 }
14310 14270
14311 } // namespace dart 14271 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698