| 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 3135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 } else { | 3146 } else { |
| 3147 UnexpectedToken(); | 3147 UnexpectedToken(); |
| 3148 } | 3148 } |
| 3149 | 3149 |
| 3150 ASSERT(func.end_token_pos() == func.token_pos() || | 3150 ASSERT(func.end_token_pos() == func.token_pos() || |
| 3151 func.end_token_pos() == end_token_pos); | 3151 func.end_token_pos() == end_token_pos); |
| 3152 func.set_end_token_pos(end_token_pos); | 3152 func.set_end_token_pos(end_token_pos); |
| 3153 SequenceNode* body = CloseBlock(); | 3153 SequenceNode* body = CloseBlock(); |
| 3154 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3154 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3155 body = CloseAsyncFunction(async_closure, body); | 3155 body = CloseAsyncFunction(async_closure, body); |
| 3156 async_closure.set_end_token_pos(end_token_pos); |
| 3156 } else if (func.is_async_closure()) { | 3157 } else if (func.is_async_closure()) { |
| 3157 body = CloseAsyncClosure(body); | 3158 body = CloseAsyncClosure(body); |
| 3158 } | 3159 } |
| 3159 current_block_->statements->Add(body); | 3160 current_block_->statements->Add(body); |
| 3160 innermost_function_ = saved_innermost_function.raw(); | 3161 innermost_function_ = saved_innermost_function.raw(); |
| 3161 last_used_try_index_ = saved_try_index; | 3162 last_used_try_index_ = saved_try_index; |
| 3162 await_is_keyword_ = saved_await_is_keyword; | 3163 await_is_keyword_ = saved_await_is_keyword; |
| 3163 async_temp_scope_ = saved_async_temp_scope; | 3164 async_temp_scope_ = saved_async_temp_scope; |
| 3164 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); | 3165 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); |
| 3165 parsed_function()->set_async_saved_try_ctx_name( | 3166 parsed_function()->set_async_saved_try_ctx_name( |
| (...skipping 2564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5730 | 5731 |
| 5731 if (innermost_function().is_async_closure() || | 5732 if (innermost_function().is_async_closure() || |
| 5732 innermost_function().IsAsyncFunction()) { | 5733 innermost_function().IsAsyncFunction()) { |
| 5733 SetupSavedTryContext(context_var); | 5734 SetupSavedTryContext(context_var); |
| 5734 } | 5735 } |
| 5735 } | 5736 } |
| 5736 | 5737 |
| 5737 | 5738 |
| 5738 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { | 5739 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { |
| 5739 TRACE_PARSER("OpenAsyncFunction"); | 5740 TRACE_PARSER("OpenAsyncFunction"); |
| 5741 AddAsyncClosureVariables(); |
| 5742 Function& closure = Function::Handle(I); |
| 5743 bool is_new_closure = false; |
| 5740 | 5744 |
| 5741 AddAsyncClosureVariables(); | 5745 // Check whether a function for the asynchronous function body of |
| 5742 | 5746 // this async function has already been created by a previous |
| 5743 // Create the closure containing the old body of this function. | 5747 // compilation of this function. |
| 5744 Class& sig_cls = Class::ZoneHandle(I); | 5748 const Function& found_func = Function::Handle( |
| 5745 Type& sig_type = Type::ZoneHandle(I); | 5749 I, current_class().LookupClosureFunction(formal_param_pos)); |
| 5746 Function& closure = Function::ZoneHandle(I); | 5750 if (!found_func.IsNull() && |
| 5747 String& sig = String::ZoneHandle(I); | 5751 (found_func.token_pos() == formal_param_pos) && |
| 5752 (found_func.script() == innermost_function().script()) && |
| 5753 (found_func.parent_function() == innermost_function().raw())) { |
| 5754 ASSERT(found_func.is_async_closure()); |
| 5755 closure = found_func.raw(); |
| 5756 } else { |
| 5757 // Create the closure containing the body of this async function. |
| 5758 const String& async_func_name = |
| 5759 String::Handle(I, innermost_function().name()); |
| 5760 String& closure_name = String::Handle(I, |
| 5761 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); |
| 5762 closure = Function::NewClosureFunction( |
| 5763 String::Handle(I, Symbols::New(closure_name)), |
| 5764 innermost_function(), |
| 5765 formal_param_pos); |
| 5766 closure.set_is_async_closure(true); |
| 5767 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); |
| 5768 is_new_closure = true; |
| 5769 } |
| 5770 // Create the parameter list for the async body closure. |
| 5748 ParamList closure_params; | 5771 ParamList closure_params; |
| 5749 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); | 5772 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); |
| 5750 closure_params.AddFinalParameter( | 5773 closure_params.AddFinalParameter( |
| 5751 formal_param_pos, &Symbols::ClosureParameter(), &dynamic_type); | 5774 formal_param_pos, &Symbols::ClosureParameter(), &dynamic_type); |
| 5752 ParamDesc result_param; | 5775 ParamDesc result_param; |
| 5753 result_param.name = &Symbols::AsyncOperationParam(); | 5776 result_param.name = &Symbols::AsyncOperationParam(); |
| 5754 result_param.default_value = &Object::null_instance(); | 5777 result_param.default_value = &Object::null_instance(); |
| 5755 result_param.type = &dynamic_type; | 5778 result_param.type = &dynamic_type; |
| 5779 closure_params.parameters->Add(result_param); |
| 5756 ParamDesc error_param; | 5780 ParamDesc error_param; |
| 5757 error_param.name = &Symbols::AsyncOperationErrorParam(); | 5781 error_param.name = &Symbols::AsyncOperationErrorParam(); |
| 5758 error_param.default_value = &Object::null_instance(); | 5782 error_param.default_value = &Object::null_instance(); |
| 5759 error_param.type = &dynamic_type; | 5783 error_param.type = &dynamic_type; |
| 5760 closure_params.parameters->Add(result_param); | |
| 5761 closure_params.parameters->Add(error_param); | 5784 closure_params.parameters->Add(error_param); |
| 5762 closure_params.has_optional_positional_parameters = true; | 5785 closure_params.has_optional_positional_parameters = true; |
| 5763 closure_params.num_optional_parameters += 2; | 5786 closure_params.num_optional_parameters += 2; |
| 5764 closure = Function::NewClosureFunction( | 5787 |
| 5765 Symbols::AnonymousClosure(), | 5788 if (is_new_closure) { |
| 5766 innermost_function(), | 5789 // Add the parameters to the newly created closure. |
| 5767 formal_param_pos); | 5790 AddFormalParamsToFunction(&closure_params, closure); |
| 5768 AddFormalParamsToFunction(&closure_params, closure); | 5791 |
| 5769 closure.set_is_async_closure(true); | 5792 // Create and set the signature class of the closure. |
| 5770 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | 5793 const String& sig = String::Handle(I, closure.Signature()); |
| 5771 sig = closure.Signature(); | 5794 Class& sig_cls = Class::Handle(I, library_.LookupLocalClass(sig)); |
| 5772 sig_cls = library_.LookupLocalClass(sig); | 5795 if (sig_cls.IsNull()) { |
| 5773 if (sig_cls.IsNull()) { | 5796 sig_cls = |
| 5774 sig_cls = Class::NewSignatureClass(sig, closure, script_, formal_param_pos); | 5797 Class::NewSignatureClass(sig, closure, script_, formal_param_pos); |
| 5775 library_.AddClass(sig_cls); | 5798 library_.AddClass(sig_cls); |
| 5799 } |
| 5800 closure.set_signature_class(sig_cls); |
| 5801 const Type& sig_type = Type::Handle(I, sig_cls.SignatureType()); |
| 5802 if (!sig_type.IsFinalized()) { |
| 5803 ClassFinalizer::FinalizeType( |
| 5804 sig_cls, sig_type, ClassFinalizer::kCanonicalize); |
| 5805 } |
| 5806 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); |
| 5807 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
| 5776 } | 5808 } |
| 5777 closure.set_signature_class(sig_cls); | |
| 5778 sig_type = sig_cls.SignatureType(); | |
| 5779 if (!sig_type.IsFinalized()) { | |
| 5780 ClassFinalizer::FinalizeType( | |
| 5781 sig_cls, sig_type, ClassFinalizer::kCanonicalize); | |
| 5782 } | |
| 5783 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); | |
| 5784 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | |
| 5785 OpenFunctionBlock(closure); | 5809 OpenFunctionBlock(closure); |
| 5786 AddFormalParamsToScope(&closure_params, current_block_->scope); | 5810 AddFormalParamsToScope(&closure_params, current_block_->scope); |
| 5787 OpenBlock(); | 5811 OpenBlock(); |
| 5788 | |
| 5789 async_temp_scope_ = current_block_->scope; | 5812 async_temp_scope_ = current_block_->scope; |
| 5790 | |
| 5791 return closure.raw(); | 5813 return closure.raw(); |
| 5792 } | 5814 } |
| 5793 | 5815 |
| 5794 | 5816 |
| 5795 void Parser::AddAsyncClosureVariables() { | 5817 void Parser::AddAsyncClosureVariables() { |
| 5796 // Add to AST: | 5818 // Add to AST: |
| 5797 // var :await_jump_var; | 5819 // var :await_jump_var; |
| 5798 // var :await_ctx_var; | 5820 // var :await_ctx_var; |
| 5799 // var :async_op; | 5821 // var :async_op; |
| 5800 // var :async_completer; | 5822 // var :async_completer; |
| (...skipping 5985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11786 void Parser::SkipQualIdent() { | 11808 void Parser::SkipQualIdent() { |
| 11787 ASSERT(IsIdentifier()); | 11809 ASSERT(IsIdentifier()); |
| 11788 ConsumeToken(); | 11810 ConsumeToken(); |
| 11789 if (CurrentToken() == Token::kPERIOD) { | 11811 if (CurrentToken() == Token::kPERIOD) { |
| 11790 ConsumeToken(); // Consume the kPERIOD token. | 11812 ConsumeToken(); // Consume the kPERIOD token. |
| 11791 ExpectIdentifier("identifier expected after '.'"); | 11813 ExpectIdentifier("identifier expected after '.'"); |
| 11792 } | 11814 } |
| 11793 } | 11815 } |
| 11794 | 11816 |
| 11795 } // namespace dart | 11817 } // namespace dart |
| OLD | NEW |