OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |