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 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 node_sequence = | 881 node_sequence = |
882 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); | 882 parser.ParseInvokeFieldDispatcher(func, &default_parameter_values); |
883 break; | 883 break; |
884 case RawFunction::kIrregexpFunction: | 884 case RawFunction::kIrregexpFunction: |
885 UNREACHABLE(); // Irregexp functions have their own parser. | 885 UNREACHABLE(); // Irregexp functions have their own parser. |
886 default: | 886 default: |
887 UNREACHABLE(); | 887 UNREACHABLE(); |
888 } | 888 } |
889 | 889 |
890 if (!HasReturnNode(node_sequence)) { | 890 if (!HasReturnNode(node_sequence)) { |
891 // Add implicit return node. | 891 // Add implicit return node. The implicit return value of synchronous |
892 node_sequence->Add(new ReturnNode(func.end_token_pos())); | 892 // generator closures is false, to indicate that there are no more |
| 893 // elements in the iterable. In other cases the implicit return value |
| 894 // is null. |
| 895 AstNode* return_value = func.IsSyncGenClosure() |
| 896 ? new LiteralNode(func.end_token_pos(), Bool::False()) |
| 897 : new LiteralNode(func.end_token_pos(), Instance::ZoneHandle()); |
| 898 node_sequence->Add(new ReturnNode(func.end_token_pos(), return_value)); |
893 } | 899 } |
894 if (parsed_function->has_expression_temp_var()) { | 900 if (parsed_function->has_expression_temp_var()) { |
895 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); | 901 node_sequence->scope()->AddVariable(parsed_function->expression_temp_var()); |
896 } | 902 } |
897 node_sequence->scope()->AddVariable( | 903 node_sequence->scope()->AddVariable( |
898 parsed_function->current_context_var()); | 904 parsed_function->current_context_var()); |
899 if (parsed_function->has_finally_return_temp_var()) { | 905 if (parsed_function->has_finally_return_temp_var()) { |
900 node_sequence->scope()->AddVariable( | 906 node_sequence->scope()->AddVariable( |
901 parsed_function->finally_return_temp_var()); | 907 parsed_function->finally_return_temp_var()); |
902 } | 908 } |
(...skipping 2150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3053 ASSERT(current_class().raw() == func.Owner()); | 3059 ASSERT(current_class().raw() == func.Owner()); |
3054 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 3060 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
3055 } else if (func.IsFactory()) { | 3061 } else if (func.IsFactory()) { |
3056 // The first parameter of a factory is the TypeArguments vector of | 3062 // The first parameter of a factory is the TypeArguments vector of |
3057 // the type of the instance to be allocated. | 3063 // the type of the instance to be allocated. |
3058 params.AddFinalParameter( | 3064 params.AddFinalParameter( |
3059 TokenPos(), | 3065 TokenPos(), |
3060 &Symbols::TypeArgumentsParameter(), | 3066 &Symbols::TypeArgumentsParameter(), |
3061 &Type::ZoneHandle(Z, Type::DynamicType())); | 3067 &Type::ZoneHandle(Z, Type::DynamicType())); |
3062 } | 3068 } |
| 3069 // Expect the parameter list unless this is a getter function, or the |
| 3070 // body closure of an async or generator getter function. |
3063 ASSERT((CurrentToken() == Token::kLPAREN) || | 3071 ASSERT((CurrentToken() == Token::kLPAREN) || |
3064 func.IsGetterFunction() || | 3072 func.IsGetterFunction() || |
3065 func.is_async_closure()); | 3073 (func.is_generated_body() && |
| 3074 Function::Handle(func.parent_function()).IsGetterFunction())); |
3066 const bool allow_explicit_default_values = true; | 3075 const bool allow_explicit_default_values = true; |
3067 if (func.IsGetterFunction()) { | 3076 if (func.IsGetterFunction()) { |
3068 // Populate function scope with the formal parameters. Since in this case | 3077 // Populate function scope with the formal parameters. Since in this case |
3069 // we are compiling a getter this will at most populate the receiver. | 3078 // we are compiling a getter this will at most populate the receiver. |
3070 AddFormalParamsToScope(¶ms, current_block_->scope); | 3079 AddFormalParamsToScope(¶ms, current_block_->scope); |
3071 } else if (func.is_async_closure()) { | 3080 } else if (func.IsAsyncClosure()) { |
3072 // Async closures have two optional parameters: | 3081 AddAsyncClosureParameters(¶ms); |
3073 // * A continuation result. | |
3074 // * A continuation error. | |
3075 // | |
3076 // If the error!=null we rethrow the error at the next await. | |
3077 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); | |
3078 ParamDesc result_param; | |
3079 result_param.name = &Symbols::AsyncOperationParam(); | |
3080 result_param.default_value = &Object::null_instance(); | |
3081 result_param.type = &dynamic_type; | |
3082 ParamDesc error_param; | |
3083 error_param.name = &Symbols::AsyncOperationErrorParam(); | |
3084 error_param.default_value = &Object::null_instance(); | |
3085 error_param.type = &dynamic_type; | |
3086 ParamDesc stack_trace_param; | |
3087 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | |
3088 stack_trace_param.default_value = &Object::null_instance(); | |
3089 stack_trace_param.type = &dynamic_type; | |
3090 params.parameters->Add(result_param); | |
3091 params.parameters->Add(error_param); | |
3092 params.parameters->Add(stack_trace_param); | |
3093 params.num_optional_parameters += 3; | |
3094 params.has_optional_positional_parameters = true; | |
3095 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3082 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
3096 AddFormalParamsToScope(¶ms, current_block_->scope); | 3083 AddFormalParamsToScope(¶ms, current_block_->scope); |
3097 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 3084 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
3098 ASSERT(func.NumParameters() == params.parameters->length()); | 3085 ASSERT(func.NumParameters() == params.parameters->length()); |
3099 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { | 3086 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { |
3100 // Parse and discard any formal parameters. They are accessed as | 3087 // Parse and discard any formal parameters. They are accessed as |
3101 // context variables. | 3088 // context variables. |
3102 ParamList parse_away; | 3089 ParamList discarded_params; |
3103 ParseFormalParameterList(allow_explicit_default_values, | 3090 ParseFormalParameterList(allow_explicit_default_values, |
3104 false, | 3091 false, |
3105 &parse_away); | 3092 &discarded_params); |
| 3093 } |
| 3094 } else if (func.IsSyncGenClosure()) { |
| 3095 AddSyncGenClosureParameters(¶ms); |
| 3096 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 3097 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 3098 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 3099 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { |
| 3100 // Parse and discard any formal parameters. They are accessed as |
| 3101 // context variables. |
| 3102 ParamList discarded_params; |
| 3103 ParseFormalParameterList(allow_explicit_default_values, |
| 3104 false, |
| 3105 &discarded_params); |
3106 } | 3106 } |
3107 } else { | 3107 } else { |
3108 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 3108 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
3109 | 3109 |
3110 // The number of parameters and their type are not yet set in local | 3110 // The number of parameters and their type are not yet set in local |
3111 // functions, since they are not 'top-level' parsed. | 3111 // functions, since they are not 'top-level' parsed. |
3112 if (func.IsLocalFunction()) { | 3112 if (func.IsLocalFunction()) { |
3113 AddFormalParamsToFunction(¶ms, func); | 3113 AddFormalParamsToFunction(¶ms, func); |
3114 } | 3114 } |
3115 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3115 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
(...skipping 21 matching lines...) Expand all Loading... |
3137 if (IsInstantiatorRequired()) { | 3137 if (IsInstantiatorRequired()) { |
3138 // Make sure that the receiver of the enclosing instance function | 3138 // Make sure that the receiver of the enclosing instance function |
3139 // (or implicit first parameter of an enclosing factory) is marked as | 3139 // (or implicit first parameter of an enclosing factory) is marked as |
3140 // captured if type checks are enabled, because they may access it to | 3140 // captured if type checks are enabled, because they may access it to |
3141 // instantiate types. | 3141 // instantiate types. |
3142 CaptureInstantiator(); | 3142 CaptureInstantiator(); |
3143 } | 3143 } |
3144 } | 3144 } |
3145 } | 3145 } |
3146 | 3146 |
| 3147 const intptr_t modifier_pos = TokenPos(); |
3147 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3148 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
3148 func.set_modifier(func_modifier); | 3149 if (!func.is_generated_body()) { |
| 3150 // Don't add a modifier to the closure representing the body of |
| 3151 // the asynchronous function or generator. |
| 3152 func.set_modifier(func_modifier); |
| 3153 } |
3149 | 3154 |
3150 OpenBlock(); // Open a nested scope for the outermost function block. | 3155 OpenBlock(); // Open a nested scope for the outermost function block. |
3151 | 3156 |
3152 Function& async_closure = Function::ZoneHandle(Z); | 3157 Function& generated_body_closure = Function::ZoneHandle(Z); |
3153 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3158 if (func.IsAsyncFunction()) { |
| 3159 ASSERT(!func.is_generated_body()); |
3154 // The code of an async function is synthesized. Disable debugging. | 3160 // The code of an async function is synthesized. Disable debugging. |
3155 func.set_is_debuggable(false); | 3161 func.set_is_debuggable(false); |
3156 async_closure = OpenAsyncFunction(func.token_pos()); | 3162 generated_body_closure = OpenAsyncFunction(func.token_pos()); |
3157 } else if (func.is_async_closure()) { | 3163 } else if (func.IsAsyncClosure()) { |
3158 // The closure containing the body of an async function is debuggable. | 3164 // The closure containing the body of an async function is debuggable. |
3159 ASSERT(func.is_debuggable()); | 3165 ASSERT(func.is_debuggable()); |
3160 OpenAsyncClosure(); | 3166 OpenAsyncClosure(); |
| 3167 } else if (func.IsSyncGenerator()) { |
| 3168 // The code of a sync generator is synthesized. Disable debugging. |
| 3169 func.set_is_debuggable(false); |
| 3170 generated_body_closure = OpenSyncGeneratorFunction(func.token_pos()); |
| 3171 } else if (func.IsSyncGenClosure()) { |
| 3172 // The closure containing the body of a sync generator is debuggable. |
| 3173 ASSERT(func.is_debuggable()); |
| 3174 // Nothing special to do. |
3161 } | 3175 } |
3162 | 3176 |
3163 BoolScope allow_await(&this->await_is_keyword_, | 3177 BoolScope allow_await(&this->await_is_keyword_, |
3164 func.IsAsyncFunction() || func.is_async_closure()); | 3178 func.IsAsyncOrGenerator() || func.is_generated_body()); |
3165 intptr_t end_token_pos = 0; | 3179 intptr_t end_token_pos = 0; |
3166 if (CurrentToken() == Token::kLBRACE) { | 3180 if (CurrentToken() == Token::kLBRACE) { |
3167 ConsumeToken(); | 3181 ConsumeToken(); |
3168 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { | 3182 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
3169 const Class& owner = Class::Handle(Z, func.Owner()); | 3183 const Class& owner = Class::Handle(Z, func.Owner()); |
3170 if (!owner.IsObjectClass()) { | 3184 if (!owner.IsObjectClass()) { |
3171 AddEqualityNullCheck(); | 3185 AddEqualityNullCheck(); |
3172 } | 3186 } |
3173 } | 3187 } |
3174 ParseStatementSequence(); | 3188 ParseStatementSequence(); |
3175 end_token_pos = TokenPos(); | 3189 end_token_pos = TokenPos(); |
3176 ExpectToken(Token::kRBRACE); | 3190 ExpectToken(Token::kRBRACE); |
3177 } else if (CurrentToken() == Token::kARROW) { | 3191 } else if (CurrentToken() == Token::kARROW) { |
| 3192 if (func.IsGenerator()) { |
| 3193 ReportError(modifier_pos, |
| 3194 "=> style function may not be sync* or async* generator"); |
| 3195 } |
3178 ConsumeToken(); | 3196 ConsumeToken(); |
3179 if (String::Handle(Z, func.name()).Equals( | 3197 if (String::Handle(Z, func.name()).Equals( |
3180 Symbols::EqualOperator())) { | 3198 Symbols::EqualOperator())) { |
3181 const Class& owner = Class::Handle(Z, func.Owner()); | 3199 const Class& owner = Class::Handle(Z, func.Owner()); |
3182 if (!owner.IsObjectClass()) { | 3200 if (!owner.IsObjectClass()) { |
3183 AddEqualityNullCheck(); | 3201 AddEqualityNullCheck(); |
3184 } | 3202 } |
3185 } | 3203 } |
3186 const intptr_t expr_pos = TokenPos(); | 3204 const intptr_t expr_pos = TokenPos(); |
3187 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3205 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
(...skipping 26 matching lines...) Expand all Loading... |
3214 &func)); // Unpatched external function. | 3232 &func)); // Unpatched external function. |
3215 end_token_pos = TokenPos(); | 3233 end_token_pos = TokenPos(); |
3216 } else { | 3234 } else { |
3217 UnexpectedToken(); | 3235 UnexpectedToken(); |
3218 } | 3236 } |
3219 | 3237 |
3220 ASSERT(func.end_token_pos() == func.token_pos() || | 3238 ASSERT(func.end_token_pos() == func.token_pos() || |
3221 func.end_token_pos() == end_token_pos); | 3239 func.end_token_pos() == end_token_pos); |
3222 func.set_end_token_pos(end_token_pos); | 3240 func.set_end_token_pos(end_token_pos); |
3223 SequenceNode* body = CloseBlock(); | 3241 SequenceNode* body = CloseBlock(); |
3224 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3242 if (func.IsAsyncFunction()) { |
3225 body = CloseAsyncFunction(async_closure, body); | 3243 body = CloseAsyncFunction(generated_body_closure, body); |
3226 async_closure.set_end_token_pos(end_token_pos); | 3244 generated_body_closure.set_end_token_pos(end_token_pos); |
3227 } else if (func.is_async_closure()) { | 3245 } else if (func.IsAsyncClosure()) { |
3228 body = CloseAsyncClosure(body); | 3246 body = CloseAsyncClosure(body); |
| 3247 } else if (func.IsSyncGenerator()) { |
| 3248 body = CloseSyncGenFunction(generated_body_closure, body); |
| 3249 generated_body_closure.set_end_token_pos(end_token_pos); |
| 3250 } else if (func.IsSyncGenClosure()) { |
| 3251 body->scope()->RecursivelyCaptureAllVariables(); |
3229 } | 3252 } |
3230 current_block_->statements->Add(body); | 3253 current_block_->statements->Add(body); |
3231 innermost_function_ = saved_innermost_function.raw(); | 3254 innermost_function_ = saved_innermost_function.raw(); |
3232 last_used_try_index_ = saved_try_index; | 3255 last_used_try_index_ = saved_try_index; |
3233 async_temp_scope_ = saved_async_temp_scope; | 3256 async_temp_scope_ = saved_async_temp_scope; |
3234 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); | 3257 parsed_function()->set_saved_try_ctx(saved_saved_try_ctx); |
3235 parsed_function()->set_async_saved_try_ctx_name( | 3258 parsed_function()->set_async_saved_try_ctx_name( |
3236 saved_async_saved_try_ctx_name); | 3259 saved_async_saved_try_ctx_name); |
3237 return CloseBlock(); | 3260 return CloseBlock(); |
3238 } | 3261 } |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3537 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3560 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
3538 | 3561 |
3539 if (method->IsConstructor() && | 3562 if (method->IsConstructor() && |
3540 method->has_external && | 3563 method->has_external && |
3541 method->params.has_field_initializer) { | 3564 method->params.has_field_initializer) { |
3542 ReportError(method->name_pos, | 3565 ReportError(method->name_pos, |
3543 "external constructor '%s' may not have field initializers", | 3566 "external constructor '%s' may not have field initializers", |
3544 method->name->ToCString()); | 3567 method->name->ToCString()); |
3545 } | 3568 } |
3546 | 3569 |
| 3570 const intptr_t modifier_pos = TokenPos(); |
3547 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 3571 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
3548 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && | 3572 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && |
3549 async_modifier != RawFunction::kNoModifier) { | 3573 (async_modifier != RawFunction::kNoModifier)) { |
3550 ReportError(method->name_pos, | 3574 ReportError(modifier_pos, |
3551 "%s '%s' may not be async", | 3575 "%s '%s' may not be async, async* or sync*", |
3552 (method->IsSetter()) ? "setter" : "constructor", | 3576 (method->IsSetter()) ? "setter" : "constructor", |
3553 method->name->ToCString()); | 3577 method->name->ToCString()); |
3554 } | 3578 } |
3555 | 3579 |
3556 intptr_t method_end_pos = TokenPos(); | 3580 intptr_t method_end_pos = TokenPos(); |
3557 if ((CurrentToken() == Token::kLBRACE) || | 3581 if ((CurrentToken() == Token::kLBRACE) || |
3558 (CurrentToken() == Token::kARROW)) { | 3582 (CurrentToken() == Token::kARROW)) { |
3559 if (method->has_abstract) { | 3583 if (method->has_abstract) { |
3560 ReportError(TokenPos(), | 3584 ReportError(TokenPos(), |
3561 "abstract method '%s' may not have a function body", | 3585 "abstract method '%s' may not have a function body", |
(...skipping 14 matching lines...) Expand all Loading... |
3576 } | 3600 } |
3577 if (method->redirect_name != NULL) { | 3601 if (method->redirect_name != NULL) { |
3578 ReportError(method->name_pos, | 3602 ReportError(method->name_pos, |
3579 "Constructor with redirection may not have a function body"); | 3603 "Constructor with redirection may not have a function body"); |
3580 } | 3604 } |
3581 if (CurrentToken() == Token::kLBRACE) { | 3605 if (CurrentToken() == Token::kLBRACE) { |
3582 SkipBlock(); | 3606 SkipBlock(); |
3583 method_end_pos = TokenPos(); | 3607 method_end_pos = TokenPos(); |
3584 ExpectToken(Token::kRBRACE); | 3608 ExpectToken(Token::kRBRACE); |
3585 } else { | 3609 } else { |
| 3610 if ((async_modifier & RawFunction::kGeneratorBit) != 0) { |
| 3611 ReportError(modifier_pos, |
| 3612 "=> style function may not be sync* or async* generator"); |
| 3613 } |
| 3614 |
3586 ConsumeToken(); | 3615 ConsumeToken(); |
3587 BoolScope allow_await(&this->await_is_keyword_, | 3616 BoolScope allow_await(&this->await_is_keyword_, |
3588 async_modifier != RawFunction::kNoModifier); | 3617 async_modifier != RawFunction::kNoModifier); |
3589 SkipExpr(); | 3618 SkipExpr(); |
3590 method_end_pos = TokenPos(); | 3619 method_end_pos = TokenPos(); |
3591 ExpectSemicolon(); | 3620 ExpectSemicolon(); |
3592 } | 3621 } |
3593 } else if (IsLiteral("native")) { | 3622 } else if (IsLiteral("native")) { |
3594 if (method->has_abstract) { | 3623 if (method->has_abstract) { |
3595 ReportError(method->name_pos, | 3624 ReportError(method->name_pos, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3639 if (must_have_semicolon) { | 3668 if (must_have_semicolon) { |
3640 ExpectSemicolon(); | 3669 ExpectSemicolon(); |
3641 } else { | 3670 } else { |
3642 ReportError(method->name_pos, | 3671 ReportError(method->name_pos, |
3643 "function body or semicolon expected for method '%s'", | 3672 "function body or semicolon expected for method '%s'", |
3644 method->name->ToCString()); | 3673 method->name->ToCString()); |
3645 } | 3674 } |
3646 } | 3675 } |
3647 } | 3676 } |
3648 | 3677 |
| 3678 if (method->has_abstract && (async_modifier != RawFunction::kNoModifier)) { |
| 3679 ReportError(modifier_pos, |
| 3680 "abstract function '%s' may not be async, async* or sync*", |
| 3681 method->name->ToCString()); |
| 3682 } |
| 3683 |
3649 RawFunction::Kind function_kind; | 3684 RawFunction::Kind function_kind; |
3650 if (method->IsFactoryOrConstructor()) { | 3685 if (method->IsFactoryOrConstructor()) { |
3651 function_kind = RawFunction::kConstructor; | 3686 function_kind = RawFunction::kConstructor; |
3652 } else if (method->IsGetter()) { | 3687 } else if (method->IsGetter()) { |
3653 function_kind = RawFunction::kGetterFunction; | 3688 function_kind = RawFunction::kGetterFunction; |
3654 } else if (method->IsSetter()) { | 3689 } else if (method->IsSetter()) { |
3655 function_kind = RawFunction::kSetterFunction; | 3690 function_kind = RawFunction::kSetterFunction; |
3656 } else { | 3691 } else { |
3657 function_kind = RawFunction::kRegularFunction; | 3692 function_kind = RawFunction::kRegularFunction; |
3658 } | 3693 } |
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5188 } else { | 5223 } else { |
5189 ExpectSemicolon(); // Reports error. | 5224 ExpectSemicolon(); // Reports error. |
5190 } | 5225 } |
5191 } | 5226 } |
5192 } | 5227 } |
5193 | 5228 |
5194 | 5229 |
5195 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { | 5230 RawFunction::AsyncModifier Parser::ParseFunctionModifier() { |
5196 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { | 5231 if (CurrentLiteral()->raw() == Symbols::Async().raw()) { |
5197 ConsumeToken(); | 5232 ConsumeToken(); |
5198 return RawFunction::kAsync; | 5233 if (CurrentToken() == Token::kMUL) { |
| 5234 ReportError("async* generator functions are not yet supported"); |
| 5235 ConsumeToken(); |
| 5236 return RawFunction::kAsyncGen; |
| 5237 } else { |
| 5238 return RawFunction::kAsync; |
| 5239 } |
| 5240 } else if ((CurrentLiteral()->raw() == Symbols::Sync().raw()) && |
| 5241 (LookaheadToken(1) == Token::kMUL)) { |
| 5242 const bool enableSyncStar = true; |
| 5243 if (!enableSyncStar) { |
| 5244 ReportError("sync* generator functions are not yet supported"); |
| 5245 } |
| 5246 ConsumeToken(); |
| 5247 ConsumeToken(); |
| 5248 return RawFunction::kSyncGen; |
5199 } | 5249 } |
5200 return RawFunction::kNoModifier; | 5250 return RawFunction::kNoModifier; |
5201 } | 5251 } |
5202 | 5252 |
5203 | 5253 |
5204 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5254 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
5205 intptr_t metadata_pos) { | 5255 intptr_t metadata_pos) { |
5206 TRACE_PARSER("ParseTopLevelFunction"); | 5256 TRACE_PARSER("ParseTopLevelFunction"); |
5207 const intptr_t decl_begin_pos = TokenPos(); | 5257 const intptr_t decl_begin_pos = TokenPos(); |
5208 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5258 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5247 } | 5297 } |
5248 // A setter named x= may co-exist with a function named x, thus we do | 5298 // A setter named x= may co-exist with a function named x, thus we do |
5249 // not need to check setters. | 5299 // not need to check setters. |
5250 | 5300 |
5251 CheckToken(Token::kLPAREN); | 5301 CheckToken(Token::kLPAREN); |
5252 const intptr_t function_pos = TokenPos(); | 5302 const intptr_t function_pos = TokenPos(); |
5253 ParamList params; | 5303 ParamList params; |
5254 const bool allow_explicit_default_values = true; | 5304 const bool allow_explicit_default_values = true; |
5255 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5305 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
5256 | 5306 |
| 5307 const intptr_t modifier_pos = TokenPos(); |
5257 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5308 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
5258 | 5309 |
5259 intptr_t function_end_pos = function_pos; | 5310 intptr_t function_end_pos = function_pos; |
5260 bool is_native = false; | 5311 bool is_native = false; |
5261 if (is_external) { | 5312 if (is_external) { |
5262 function_end_pos = TokenPos(); | 5313 function_end_pos = TokenPos(); |
5263 ExpectSemicolon(); | 5314 ExpectSemicolon(); |
5264 } else if (CurrentToken() == Token::kLBRACE) { | 5315 } else if (CurrentToken() == Token::kLBRACE) { |
5265 SkipBlock(); | 5316 SkipBlock(); |
5266 function_end_pos = TokenPos(); | 5317 function_end_pos = TokenPos(); |
5267 ExpectToken(Token::kRBRACE); | 5318 ExpectToken(Token::kRBRACE); |
5268 } else if (CurrentToken() == Token::kARROW) { | 5319 } else if (CurrentToken() == Token::kARROW) { |
| 5320 if ((func_modifier & RawFunction::kGeneratorBit) != 0) { |
| 5321 ReportError(modifier_pos, |
| 5322 "=> style function may not be sync* or async* generator"); |
| 5323 } |
5269 ConsumeToken(); | 5324 ConsumeToken(); |
5270 BoolScope allow_await(&this->await_is_keyword_, | 5325 BoolScope allow_await(&this->await_is_keyword_, |
5271 func_modifier != RawFunction::kNoModifier); | 5326 func_modifier != RawFunction::kNoModifier); |
5272 SkipExpr(); | 5327 SkipExpr(); |
5273 function_end_pos = TokenPos(); | 5328 function_end_pos = TokenPos(); |
5274 ExpectSemicolon(); | 5329 ExpectSemicolon(); |
5275 } else if (IsLiteral("native")) { | 5330 } else if (IsLiteral("native")) { |
5276 ParseNativeDeclaration(); | 5331 ParseNativeDeclaration(); |
5277 function_end_pos = TokenPos(); | 5332 function_end_pos = TokenPos(); |
5278 ExpectSemicolon(); | 5333 ExpectSemicolon(); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5388 if (found && !is_patch) { | 5443 if (found && !is_patch) { |
5389 ReportError(name_pos, "%s for '%s' is already defined", | 5444 ReportError(name_pos, "%s for '%s' is already defined", |
5390 is_getter ? "getter" : "setter", | 5445 is_getter ? "getter" : "setter", |
5391 field_name->ToCString()); | 5446 field_name->ToCString()); |
5392 } else if (!found && is_patch) { | 5447 } else if (!found && is_patch) { |
5393 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5448 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
5394 is_getter ? "getter" : "setter", | 5449 is_getter ? "getter" : "setter", |
5395 field_name->ToCString()); | 5450 field_name->ToCString()); |
5396 } | 5451 } |
5397 | 5452 |
| 5453 const intptr_t modifier_pos = TokenPos(); |
5398 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5454 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 5455 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { |
| 5456 ReportError(modifier_pos, |
| 5457 "setter function cannot be async, async* or sync*"); |
| 5458 } |
5399 | 5459 |
5400 intptr_t accessor_end_pos = accessor_pos; | 5460 intptr_t accessor_end_pos = accessor_pos; |
5401 bool is_native = false; | 5461 bool is_native = false; |
5402 if (is_external) { | 5462 if (is_external) { |
5403 accessor_end_pos = TokenPos(); | 5463 accessor_end_pos = TokenPos(); |
5404 ExpectSemicolon(); | 5464 ExpectSemicolon(); |
5405 } else if (CurrentToken() == Token::kLBRACE) { | 5465 } else if (CurrentToken() == Token::kLBRACE) { |
5406 SkipBlock(); | 5466 SkipBlock(); |
5407 accessor_end_pos = TokenPos(); | 5467 accessor_end_pos = TokenPos(); |
5408 ExpectToken(Token::kRBRACE); | 5468 ExpectToken(Token::kRBRACE); |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5908 stack_trace_param.var, | 5968 stack_trace_param.var, |
5909 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 5969 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); |
5910 current_block_->statements->Add(new(Z) InstanceCallNode( | 5970 current_block_->statements->Add(new(Z) InstanceCallNode( |
5911 Scanner::kNoSourcePos, | 5971 Scanner::kNoSourcePos, |
5912 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var), | 5972 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var), |
5913 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 5973 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
5914 no_args)); | 5974 no_args)); |
5915 } | 5975 } |
5916 | 5976 |
5917 ASSERT(try_blocks_list_ != NULL); | 5977 ASSERT(try_blocks_list_ != NULL); |
5918 if (innermost_function().is_async_closure() || | 5978 if (innermost_function().IsAsyncClosure() || |
5919 innermost_function().IsAsyncFunction()) { | 5979 innermost_function().IsAsyncFunction()) { |
5920 if ((try_blocks_list_->outer_try_block() != NULL) && | 5980 if ((try_blocks_list_->outer_try_block() != NULL) && |
5921 (try_blocks_list_->outer_try_block()->try_block() | 5981 (try_blocks_list_->outer_try_block()->try_block() |
5922 ->scope->function_level() == | 5982 ->scope->function_level() == |
5923 current_block_->scope->function_level())) { | 5983 current_block_->scope->function_level())) { |
5924 // We need to unchain three scope levels: catch clause, catch | 5984 // We need to unchain three scope levels: catch clause, catch |
5925 // parameters, and the general try block. | 5985 // parameters, and the general try block. |
5926 RestoreSavedTryContext( | 5986 RestoreSavedTryContext( |
5927 current_block_->scope->parent()->parent()->parent(), | 5987 current_block_->scope->parent()->parent()->parent(), |
5928 try_blocks_list_->outer_try_block()->try_index(), | 5988 try_blocks_list_->outer_try_block()->try_index(), |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6013 TokenPos(), | 6073 TokenPos(), |
6014 Symbols::StackTraceVar(), | 6074 Symbols::StackTraceVar(), |
6015 Type::ZoneHandle(Z, Type::DynamicType())); | 6075 Type::ZoneHandle(Z, Type::DynamicType())); |
6016 current_block_->scope->AddVariable(stack_trace_var); | 6076 current_block_->scope->AddVariable(stack_trace_var); |
6017 } | 6077 } |
6018 | 6078 |
6019 // Open the try block. | 6079 // Open the try block. |
6020 OpenBlock(); | 6080 OpenBlock(); |
6021 PushTryBlock(current_block_); | 6081 PushTryBlock(current_block_); |
6022 | 6082 |
6023 if (innermost_function().is_async_closure() || | 6083 if (innermost_function().IsAsyncClosure() || |
6024 innermost_function().IsAsyncFunction()) { | 6084 innermost_function().IsAsyncFunction()) { |
6025 SetupSavedTryContext(context_var); | 6085 SetupSavedTryContext(context_var); |
6026 } | 6086 } |
6027 } | 6087 } |
6028 | 6088 |
6029 | 6089 |
| 6090 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
| 6091 // Create the parameter list for the body closure of a sync generator: |
| 6092 // 1) Implicit closure parameter; |
| 6093 // 2) Iterator |
| 6094 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 6095 // Add implicit closure parameter if not already present. |
| 6096 if (params->parameters->length() == 0) { |
| 6097 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); |
| 6098 } |
| 6099 ParamDesc iterator_param; |
| 6100 iterator_param.name = &Symbols::IteratorParameter(); |
| 6101 iterator_param.type = &dynamic_type; |
| 6102 params->parameters->Add(iterator_param); |
| 6103 params->num_fixed_parameters++; |
| 6104 } |
| 6105 |
| 6106 |
| 6107 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { |
| 6108 Function& body = Function::Handle(Z); |
| 6109 String& body_closure_name = String::Handle(Z); |
| 6110 bool is_new_closure = false; |
| 6111 |
| 6112 AddContinuationVariables(); |
| 6113 |
| 6114 // Check whether a function for the body of this generator |
| 6115 // function has already been created by a previous |
| 6116 // compilation. |
| 6117 const Function& found_func = Function::Handle( |
| 6118 Z, current_class().LookupClosureFunction(func_pos)); |
| 6119 if (!found_func.IsNull() && |
| 6120 (found_func.token_pos() == func_pos) && |
| 6121 (found_func.script() == innermost_function().script()) && |
| 6122 (found_func.parent_function() == innermost_function().raw())) { |
| 6123 ASSERT(found_func.IsSyncGenClosure()); |
| 6124 body = found_func.raw(); |
| 6125 body_closure_name = body.name(); |
| 6126 } else { |
| 6127 // Create the closure containing the body of this generator function. |
| 6128 String& generator_name = String::Handle(Z, innermost_function().name()); |
| 6129 body_closure_name = |
| 6130 String::NewFormatted("<%s_sync_body>", generator_name.ToCString()); |
| 6131 body_closure_name = Symbols::New(body_closure_name); |
| 6132 body = Function::NewClosureFunction(body_closure_name, |
| 6133 innermost_function(), |
| 6134 func_pos); |
| 6135 body.set_is_generated_body(true); |
| 6136 body.set_result_type(AbstractType::Handle(Type::DynamicType())); |
| 6137 is_new_closure = true; |
| 6138 } |
| 6139 |
| 6140 ParamList closure_params; |
| 6141 AddSyncGenClosureParameters(&closure_params); |
| 6142 |
| 6143 if (is_new_closure) { |
| 6144 // Add the parameters to the newly created closure. |
| 6145 AddFormalParamsToFunction(&closure_params, body); |
| 6146 |
| 6147 // Create and set the signature class of the closure. |
| 6148 const String& sig = String::Handle(Z, body.Signature()); |
| 6149 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig)); |
| 6150 if (sig_cls.IsNull()) { |
| 6151 sig_cls = Class::NewSignatureClass(sig, body, script_, body.token_pos()); |
| 6152 library_.AddClass(sig_cls); |
| 6153 } |
| 6154 body.set_signature_class(sig_cls); |
| 6155 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType()); |
| 6156 if (!sig_type.IsFinalized()) { |
| 6157 ClassFinalizer::FinalizeType( |
| 6158 sig_cls, sig_type, ClassFinalizer::kCanonicalize); |
| 6159 } |
| 6160 ASSERT(AbstractType::Handle(Z, body.result_type()).IsResolved()); |
| 6161 ASSERT(body.NumParameters() == closure_params.parameters->length()); |
| 6162 } |
| 6163 |
| 6164 OpenFunctionBlock(body); |
| 6165 AddFormalParamsToScope(&closure_params, current_block_->scope); |
| 6166 OpenBlock(); |
| 6167 |
| 6168 /* |
| 6169 async_temp_scope_ = current_block_->scope; // Is this needed? |
| 6170 */ |
| 6171 return body.raw(); |
| 6172 } |
| 6173 |
| 6174 SequenceNode* Parser::CloseSyncGenFunction(const Function& closure, |
| 6175 SequenceNode* closure_body) { |
| 6176 // The block for the closure body has already been closed. Close the |
| 6177 // corresponding function block. |
| 6178 CloseBlock(); |
| 6179 |
| 6180 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6181 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
| 6182 |
| 6183 // :await_jump_var = -1; |
| 6184 LocalVariable* jump_var = |
| 6185 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6186 LiteralNode* init_value = |
| 6187 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); |
| 6188 current_block_->statements->Add( |
| 6189 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); |
| 6190 |
| 6191 // return new SyncIterable(body_closure); |
| 6192 const Class& iterable_class = |
| 6193 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); |
| 6194 ASSERT(!iterable_class.IsNull()); |
| 6195 const Function& iterable_constructor = Function::ZoneHandle(Z, |
| 6196 iterable_class.LookupConstructorAllowPrivate( |
| 6197 Symbols::_SyncIterableConstructor())); |
| 6198 ASSERT(!iterable_constructor.IsNull()); |
| 6199 |
| 6200 const String& closure_name = String::Handle(Z, closure.name()); |
| 6201 ASSERT(closure_name.IsSymbol()); |
| 6202 |
| 6203 ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 6204 ClosureNode* closure_obj = new(Z) ClosureNode( |
| 6205 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); |
| 6206 arguments->Add(closure_obj); |
| 6207 ConstructorCallNode* new_iterable = |
| 6208 new(Z) ConstructorCallNode(Scanner::kNoSourcePos, |
| 6209 TypeArguments::ZoneHandle(Z), |
| 6210 iterable_constructor, |
| 6211 arguments); |
| 6212 ReturnNode* return_node = |
| 6213 new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable); |
| 6214 current_block_->statements->Add(return_node); |
| 6215 return CloseBlock(); |
| 6216 } |
| 6217 |
| 6218 |
| 6219 void Parser::AddAsyncClosureParameters(ParamList* params) { |
| 6220 // Async closures have two optional parameters: |
| 6221 // * A continuation result. |
| 6222 // * A continuation error. |
| 6223 // * A continuation stack trace. |
| 6224 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 6225 // Add implicit closure parameter if not yet present. |
| 6226 if (params->parameters->length() == 0) { |
| 6227 params->AddFinalParameter(0, &Symbols::ClosureParameter(), &dynamic_type); |
| 6228 } |
| 6229 ParamDesc result_param; |
| 6230 result_param.name = &Symbols::AsyncOperationParam(); |
| 6231 result_param.default_value = &Object::null_instance(); |
| 6232 result_param.type = &dynamic_type; |
| 6233 params->parameters->Add(result_param); |
| 6234 ParamDesc error_param; |
| 6235 error_param.name = &Symbols::AsyncOperationErrorParam(); |
| 6236 error_param.default_value = &Object::null_instance(); |
| 6237 error_param.type = &dynamic_type; |
| 6238 params->parameters->Add(error_param); |
| 6239 ParamDesc stack_trace_param; |
| 6240 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); |
| 6241 stack_trace_param.default_value = &Object::null_instance(); |
| 6242 stack_trace_param.type = &dynamic_type; |
| 6243 params->parameters->Add(stack_trace_param); |
| 6244 params->has_optional_positional_parameters = true; |
| 6245 params->num_optional_parameters += 3; |
| 6246 } |
| 6247 |
| 6248 |
6030 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { | 6249 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { |
6031 TRACE_PARSER("OpenAsyncFunction"); | 6250 TRACE_PARSER("OpenAsyncFunction"); |
| 6251 AddContinuationVariables(); |
6032 AddAsyncClosureVariables(); | 6252 AddAsyncClosureVariables(); |
6033 Function& closure = Function::Handle(Z); | 6253 Function& closure = Function::Handle(Z); |
6034 bool is_new_closure = false; | 6254 bool is_new_closure = false; |
6035 | 6255 |
6036 // Check whether a function for the asynchronous function body of | 6256 // Check whether a function for the asynchronous function body of |
6037 // this async function has already been created by a previous | 6257 // this async function has already been created by a previous |
6038 // compilation of this function. | 6258 // compilation of this function. |
6039 const Function& found_func = Function::Handle( | 6259 const Function& found_func = Function::Handle( |
6040 Z, current_class().LookupClosureFunction(async_func_pos)); | 6260 Z, current_class().LookupClosureFunction(async_func_pos)); |
6041 if (!found_func.IsNull() && | 6261 if (!found_func.IsNull() && |
6042 (found_func.token_pos() == async_func_pos) && | 6262 (found_func.token_pos() == async_func_pos) && |
6043 (found_func.script() == innermost_function().script()) && | 6263 (found_func.script() == innermost_function().script()) && |
6044 (found_func.parent_function() == innermost_function().raw())) { | 6264 (found_func.parent_function() == innermost_function().raw())) { |
6045 ASSERT(found_func.is_async_closure()); | 6265 ASSERT(found_func.IsAsyncClosure()); |
6046 closure = found_func.raw(); | 6266 closure = found_func.raw(); |
6047 } else { | 6267 } else { |
6048 // Create the closure containing the body of this async function. | 6268 // Create the closure containing the body of this async function. |
6049 const String& async_func_name = | 6269 const String& async_func_name = |
6050 String::Handle(Z, innermost_function().name()); | 6270 String::Handle(Z, innermost_function().name()); |
6051 String& closure_name = String::Handle(Z, | 6271 String& closure_name = String::Handle(Z, |
6052 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); | 6272 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); |
6053 closure = Function::NewClosureFunction( | 6273 closure = Function::NewClosureFunction( |
6054 String::Handle(Z, Symbols::New(closure_name)), | 6274 String::Handle(Z, Symbols::New(closure_name)), |
6055 innermost_function(), | 6275 innermost_function(), |
6056 async_func_pos); | 6276 async_func_pos); |
6057 closure.set_is_async_closure(true); | 6277 closure.set_is_generated_body(true); |
6058 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | 6278 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); |
6059 is_new_closure = true; | 6279 is_new_closure = true; |
6060 } | 6280 } |
6061 // Create the parameter list for the async body closure. | 6281 // Create the parameter list for the async body closure. |
6062 ParamList closure_params; | 6282 ParamList closure_params; |
6063 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); | 6283 AddAsyncClosureParameters(&closure_params); |
6064 closure_params.AddFinalParameter( | |
6065 async_func_pos, &Symbols::ClosureParameter(), &dynamic_type); | |
6066 ParamDesc result_param; | |
6067 result_param.name = &Symbols::AsyncOperationParam(); | |
6068 result_param.default_value = &Object::null_instance(); | |
6069 result_param.type = &dynamic_type; | |
6070 closure_params.parameters->Add(result_param); | |
6071 ParamDesc error_param; | |
6072 error_param.name = &Symbols::AsyncOperationErrorParam(); | |
6073 error_param.default_value = &Object::null_instance(); | |
6074 error_param.type = &dynamic_type; | |
6075 closure_params.parameters->Add(error_param); | |
6076 ParamDesc stack_trace_param; | |
6077 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | |
6078 stack_trace_param.default_value = &Object::null_instance(); | |
6079 stack_trace_param.type = &dynamic_type; | |
6080 closure_params.parameters->Add(stack_trace_param); | |
6081 closure_params.has_optional_positional_parameters = true; | |
6082 closure_params.num_optional_parameters += 3; | |
6083 | |
6084 if (is_new_closure) { | 6284 if (is_new_closure) { |
6085 // Add the parameters to the newly created closure. | 6285 // Add the parameters to the newly created closure. |
6086 AddFormalParamsToFunction(&closure_params, closure); | 6286 AddFormalParamsToFunction(&closure_params, closure); |
6087 | 6287 |
6088 // Create and set the signature class of the closure. | 6288 // Create and set the signature class of the closure. |
6089 const String& sig = String::Handle(Z, closure.Signature()); | 6289 const String& sig = String::Handle(Z, closure.Signature()); |
6090 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig)); | 6290 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig)); |
6091 if (sig_cls.IsNull()) { | 6291 if (sig_cls.IsNull()) { |
6092 sig_cls = | 6292 sig_cls = |
6093 Class::NewSignatureClass(sig, closure, script_, closure.token_pos()); | 6293 Class::NewSignatureClass(sig, closure, script_, closure.token_pos()); |
6094 library_.AddClass(sig_cls); | 6294 library_.AddClass(sig_cls); |
6095 } | 6295 } |
6096 closure.set_signature_class(sig_cls); | 6296 closure.set_signature_class(sig_cls); |
6097 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType()); | 6297 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType()); |
6098 if (!sig_type.IsFinalized()) { | 6298 if (!sig_type.IsFinalized()) { |
6099 ClassFinalizer::FinalizeType( | 6299 ClassFinalizer::FinalizeType( |
6100 sig_cls, sig_type, ClassFinalizer::kCanonicalize); | 6300 sig_cls, sig_type, ClassFinalizer::kCanonicalize); |
6101 } | 6301 } |
6102 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); | 6302 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); |
6103 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 6303 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
6104 } | 6304 } |
6105 OpenFunctionBlock(closure); | 6305 OpenFunctionBlock(closure); |
6106 AddFormalParamsToScope(&closure_params, current_block_->scope); | 6306 AddFormalParamsToScope(&closure_params, current_block_->scope); |
6107 OpenBlock(); | 6307 OpenBlock(); |
6108 async_temp_scope_ = current_block_->scope; | 6308 async_temp_scope_ = current_block_->scope; |
6109 return closure.raw(); | 6309 return closure.raw(); |
6110 } | 6310 } |
6111 | 6311 |
6112 | 6312 |
6113 void Parser::AddAsyncClosureVariables() { | 6313 void Parser::AddContinuationVariables() { |
6114 // Add to AST: | 6314 // Add to current block's scope: |
6115 // var :await_jump_var; | 6315 // var :await_jump_var; |
6116 // var :await_ctx_var; | 6316 // var :await_ctx_var; |
6117 // var :async_op; | |
6118 // var :async_completer; | |
6119 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); | 6317 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
6120 LocalVariable* await_jump_var = new (Z) LocalVariable( | 6318 LocalVariable* await_jump_var = new (Z) LocalVariable( |
6121 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type); | 6319 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type); |
6122 current_block_->scope->AddVariable(await_jump_var); | 6320 current_block_->scope->AddVariable(await_jump_var); |
6123 current_block_->scope->CaptureVariable(Symbols::AwaitJumpVar()); | 6321 current_block_->scope->CaptureVariable(Symbols::AwaitJumpVar()); |
6124 await_jump_var->set_is_captured(); | 6322 await_jump_var->set_is_captured(); |
6125 LocalVariable* await_ctx_var = new (Z) LocalVariable( | 6323 LocalVariable* await_ctx_var = new (Z) LocalVariable( |
6126 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type); | 6324 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type); |
6127 current_block_->scope->AddVariable(await_ctx_var); | 6325 current_block_->scope->AddVariable(await_ctx_var); |
6128 current_block_->scope->CaptureVariable(Symbols::AwaitContextVar()); | 6326 current_block_->scope->CaptureVariable(Symbols::AwaitContextVar()); |
6129 await_ctx_var->set_is_captured(); | 6327 await_ctx_var->set_is_captured(); |
6130 LocalVariable* async_op_var = new (Z) LocalVariable( | 6328 } |
| 6329 |
| 6330 |
| 6331 void Parser::AddAsyncClosureVariables() { |
| 6332 // Add to current block's scope: |
| 6333 // var :async_op; |
| 6334 // var :async_completer; |
| 6335 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 6336 LocalVariable* async_op_var = new(Z) LocalVariable( |
6131 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); | 6337 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); |
6132 current_block_->scope->AddVariable(async_op_var); | 6338 current_block_->scope->AddVariable(async_op_var); |
6133 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); | 6339 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); |
6134 async_op_var->set_is_captured(); | 6340 async_op_var->set_is_captured(); |
6135 LocalVariable* async_completer = new (Z) LocalVariable( | 6341 LocalVariable* async_completer = new(Z) LocalVariable( |
6136 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); | 6342 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); |
6137 current_block_->scope->AddVariable(async_completer); | 6343 current_block_->scope->AddVariable(async_completer); |
6138 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); | 6344 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); |
6139 async_completer->set_is_captured(); | 6345 async_completer->set_is_captured(); |
6140 } | 6346 } |
6141 | 6347 |
6142 | 6348 |
6143 SequenceNode* Parser::CloseBlock() { | 6349 SequenceNode* Parser::CloseBlock() { |
6144 SequenceNode* statements = current_block_->statements; | 6350 SequenceNode* statements = current_block_->statements; |
6145 if (current_block_->scope != NULL) { | 6351 if (current_block_->scope != NULL) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6207 TypeArguments::ZoneHandle(Z), | 6413 TypeArguments::ZoneHandle(Z), |
6208 completer_constructor, | 6414 completer_constructor, |
6209 empty_args); | 6415 empty_args); |
6210 StoreLocalNode* store_completer = new (Z) StoreLocalNode( | 6416 StoreLocalNode* store_completer = new (Z) StoreLocalNode( |
6211 Scanner::kNoSourcePos, | 6417 Scanner::kNoSourcePos, |
6212 async_completer, | 6418 async_completer, |
6213 completer_constructor_node); | 6419 completer_constructor_node); |
6214 current_block_->statements->Add(store_completer); | 6420 current_block_->statements->Add(store_completer); |
6215 | 6421 |
6216 // :await_jump_var = -1; | 6422 // :await_jump_var = -1; |
6217 LocalVariable* jump_var = current_block_->scope->LookupVariable( | 6423 LocalVariable* jump_var = |
6218 Symbols::AwaitJumpVar(), false); | 6424 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
6219 LiteralNode* init_value = | 6425 LiteralNode* init_value = |
6220 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6426 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); |
6221 current_block_->statements->Add( | 6427 current_block_->statements->Add( |
6222 new (Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); | 6428 new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); |
6223 | 6429 |
6224 // Add to AST: | 6430 // Add to AST: |
6225 // :async_op = <closure>; (containing the original body) | 6431 // :async_op = <closure>; (containing the original body) |
6226 LocalVariable* async_op_var = current_block_->scope->LookupVariable( | 6432 LocalVariable* async_op_var = current_block_->scope->LookupVariable( |
6227 Symbols::AsyncOperation(), false); | 6433 Symbols::AsyncOperation(), false); |
6228 ClosureNode* cn = new(Z) ClosureNode( | 6434 ClosureNode* cn = new(Z) ClosureNode( |
6229 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); | 6435 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); |
6230 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 6436 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
6231 Scanner::kNoSourcePos, | 6437 Scanner::kNoSourcePos, |
6232 async_op_var, | 6438 async_op_var, |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6469 assign_pos, variable, expr); | 6675 assign_pos, variable, expr); |
6470 if (is_const) { | 6676 if (is_const) { |
6471 ASSERT(expr->IsLiteralNode()); | 6677 ASSERT(expr->IsLiteralNode()); |
6472 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 6678 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
6473 } | 6679 } |
6474 } else if (is_final || is_const) { | 6680 } else if (is_final || is_const) { |
6475 ReportError(ident_pos, | 6681 ReportError(ident_pos, |
6476 "missing initialization of 'final' or 'const' variable"); | 6682 "missing initialization of 'final' or 'const' variable"); |
6477 } else { | 6683 } else { |
6478 // Initialize variable with null. | 6684 // Initialize variable with null. |
6479 AstNode* null_expr = new(Z) LiteralNode( | 6685 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Instance::ZoneHandle(Z)); |
6480 ident_pos, Instance::ZoneHandle(Z)); | |
6481 initialization = new(Z) StoreLocalNode( | 6686 initialization = new(Z) StoreLocalNode( |
6482 ident_pos, variable, null_expr); | 6687 ident_pos, variable, null_expr); |
6483 } | 6688 } |
6484 | 6689 |
6485 ASSERT(current_block_ != NULL); | 6690 ASSERT(current_block_ != NULL); |
6486 const intptr_t previous_pos = | 6691 const intptr_t previous_pos = |
6487 current_block_->scope->PreviousReferencePos(ident); | 6692 current_block_->scope->PreviousReferencePos(ident); |
6488 if (previous_pos >= 0) { | 6693 if (previous_pos >= 0) { |
6489 ASSERT(!script_.IsNull()); | 6694 ASSERT(!script_.IsNull()); |
6490 if (previous_pos > ident_pos) { | 6695 if (previous_pos > ident_pos) { |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6900 } else if (CurrentToken() == Token::kFALSE) { | 7105 } else if (CurrentToken() == Token::kFALSE) { |
6901 *value = Bool::False().raw(); | 7106 *value = Bool::False().raw(); |
6902 return true; | 7107 return true; |
6903 } | 7108 } |
6904 return false; | 7109 return false; |
6905 } | 7110 } |
6906 | 7111 |
6907 | 7112 |
6908 // Returns true if the current token is kIDENT or a pseudo-keyword. | 7113 // Returns true if the current token is kIDENT or a pseudo-keyword. |
6909 bool Parser::IsIdentifier() { | 7114 bool Parser::IsIdentifier() { |
6910 return Token::IsIdentifier(CurrentToken()) && !IsAwaitKeyword(); | 7115 return Token::IsIdentifier(CurrentToken()) && |
| 7116 !(await_is_keyword_ && |
| 7117 ((CurrentLiteral()->raw() == Symbols::Await().raw()) || |
| 7118 (CurrentLiteral()->raw() == Symbols::Async().raw()) || |
| 7119 (CurrentLiteral()->raw() == Symbols::Yield().raw()))); |
6911 } | 7120 } |
6912 | 7121 |
6913 | 7122 |
6914 // Returns true if the next tokens can be parsed as a an optionally | 7123 // Returns true if the next tokens can be parsed as a an optionally |
6915 // qualified identifier: [ident '.'] ident. | 7124 // qualified identifier: [ident '.'] ident. |
6916 // Current token position is not restored. | 7125 // Current token position is not restored. |
6917 bool Parser::TryParseQualIdent() { | 7126 bool Parser::TryParseQualIdent() { |
6918 if (CurrentToken() != Token::kIDENT) { | 7127 if (CurrentToken() != Token::kIDENT) { |
6919 return false; | 7128 return false; |
6920 } | 7129 } |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7049 SetPosition(saved_pos); | 7258 SetPosition(saved_pos); |
7050 return false; | 7259 return false; |
7051 } | 7260 } |
7052 // Check parameter list and the following token. | 7261 // Check parameter list and the following token. |
7053 if (CurrentToken() == Token::kLPAREN) { | 7262 if (CurrentToken() == Token::kLPAREN) { |
7054 SkipToMatchingParenthesis(); | 7263 SkipToMatchingParenthesis(); |
7055 if ((CurrentToken() == Token::kLBRACE) || | 7264 if ((CurrentToken() == Token::kLBRACE) || |
7056 (CurrentToken() == Token::kARROW) || | 7265 (CurrentToken() == Token::kARROW) || |
7057 (is_top_level_ && IsLiteral("native")) || | 7266 (is_top_level_ && IsLiteral("native")) || |
7058 is_external || | 7267 is_external || |
7059 (CurrentLiteral()->raw() == Symbols::Async().raw())) { | 7268 (CurrentLiteral()->raw() == Symbols::Async().raw()) || |
| 7269 (CurrentLiteral()->raw() == Symbols::Sync().raw())) { |
7060 SetPosition(saved_pos); | 7270 SetPosition(saved_pos); |
7061 return true; | 7271 return true; |
7062 } | 7272 } |
7063 } | 7273 } |
7064 SetPosition(saved_pos); | 7274 SetPosition(saved_pos); |
7065 return false; | 7275 return false; |
7066 } | 7276 } |
7067 | 7277 |
7068 | 7278 |
7069 bool Parser::IsTopLevelAccessor() { | 7279 bool Parser::IsTopLevelAccessor() { |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7539 | 7749 |
7540 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 7750 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
7541 TRACE_PARSER("ParseAwaitForStatement"); | 7751 TRACE_PARSER("ParseAwaitForStatement"); |
7542 ASSERT(IsAwaitKeyword()); | 7752 ASSERT(IsAwaitKeyword()); |
7543 const intptr_t await_for_pos = TokenPos(); | 7753 const intptr_t await_for_pos = TokenPos(); |
7544 ConsumeToken(); // await. | 7754 ConsumeToken(); // await. |
7545 ASSERT(CurrentToken() == Token::kFOR); | 7755 ASSERT(CurrentToken() == Token::kFOR); |
7546 ConsumeToken(); // for. | 7756 ConsumeToken(); // for. |
7547 ExpectToken(Token::kLPAREN); | 7757 ExpectToken(Token::kLPAREN); |
7548 | 7758 |
| 7759 if (!innermost_function().IsAsyncFunction() && |
| 7760 !innermost_function().IsAsyncClosure()) { |
| 7761 ReportError(await_for_pos, |
| 7762 "await for loop is only allowed in async function"); |
| 7763 } |
| 7764 |
7549 // Parse loop variable. | 7765 // Parse loop variable. |
7550 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 7766 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
7551 if (CurrentToken() == Token::kCONST) { | 7767 if (CurrentToken() == Token::kCONST) { |
7552 ReportError("Loop variable cannot be 'const'"); | 7768 ReportError("Loop variable cannot be 'const'"); |
7553 } | 7769 } |
7554 bool new_loop_var = false; | 7770 bool new_loop_var = false; |
7555 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 7771 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
7556 if (LookaheadToken(1) != Token::kIN) { | 7772 if (LookaheadToken(1) != Token::kIN) { |
7557 // Declaration of a new loop variable. | 7773 // Declaration of a new loop variable. |
7558 // Delay creation of the local variable until we know its actual | 7774 // Delay creation of the local variable until we know its actual |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7721 // It is better to leave the iterator untyped and postpone the type error | 7937 // It is better to leave the iterator untyped and postpone the type error |
7722 // until the loop variable is assigned to. | 7938 // until the loop variable is assigned to. |
7723 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); | 7939 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); |
7724 LocalVariable* iterator_var = new(Z) LocalVariable( | 7940 LocalVariable* iterator_var = new(Z) LocalVariable( |
7725 collection_pos, Symbols::ForInIter(), iterator_type); | 7941 collection_pos, Symbols::ForInIter(), iterator_type); |
7726 current_block_->scope->AddVariable(iterator_var); | 7942 current_block_->scope->AddVariable(iterator_var); |
7727 | 7943 |
7728 // Generate initialization of iterator variable. | 7944 // Generate initialization of iterator variable. |
7729 ArgumentListNode* no_args = new(Z) ArgumentListNode(collection_pos); | 7945 ArgumentListNode* no_args = new(Z) ArgumentListNode(collection_pos); |
7730 AstNode* get_iterator = new(Z) InstanceGetterNode( | 7946 AstNode* get_iterator = new(Z) InstanceGetterNode( |
7731 collection_pos, collection_expr, Symbols::GetIterator()); | 7947 collection_pos, collection_expr, Symbols::iterator()); |
7732 AstNode* iterator_init = | 7948 AstNode* iterator_init = |
7733 new(Z) StoreLocalNode(collection_pos, iterator_var, get_iterator); | 7949 new(Z) StoreLocalNode(collection_pos, iterator_var, get_iterator); |
7734 current_block_->statements->Add(iterator_init); | 7950 current_block_->statements->Add(iterator_init); |
7735 | 7951 |
7736 // Generate while loop condition. | 7952 // Generate while loop condition. |
7737 AstNode* iterator_moveNext = new(Z) InstanceCallNode( | 7953 AstNode* iterator_moveNext = new(Z) InstanceCallNode( |
7738 collection_pos, | 7954 collection_pos, |
7739 new(Z) LoadLocalNode(collection_pos, iterator_var), | 7955 new(Z) LoadLocalNode(collection_pos, iterator_var), |
7740 Symbols::MoveNext(), | 7956 Symbols::MoveNext(), |
7741 no_args); | 7957 no_args); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7972 | 8188 |
7973 | 8189 |
7974 SequenceNode* Parser::ParseFinallyBlock() { | 8190 SequenceNode* Parser::ParseFinallyBlock() { |
7975 TRACE_PARSER("ParseFinallyBlock"); | 8191 TRACE_PARSER("ParseFinallyBlock"); |
7976 OpenBlock(); | 8192 OpenBlock(); |
7977 ExpectToken(Token::kLBRACE); | 8193 ExpectToken(Token::kLBRACE); |
7978 | 8194 |
7979 // In case of async closures we need to restore the saved try index of an | 8195 // In case of async closures we need to restore the saved try index of an |
7980 // outer try block (if it exists). The current try block has already been | 8196 // outer try block (if it exists). The current try block has already been |
7981 // removed from the stack of try blocks. | 8197 // removed from the stack of try blocks. |
7982 if ((innermost_function().is_async_closure() || | 8198 if ((innermost_function().IsAsyncClosure() || |
7983 innermost_function().IsAsyncFunction()) && | 8199 innermost_function().IsAsyncFunction()) && |
7984 (try_blocks_list_ != NULL)) { | 8200 (try_blocks_list_ != NULL)) { |
7985 // We need two unchain two scopes: finally clause, and the try block level. | 8201 // We need two unchain two scopes: finally clause, and the try block level. |
7986 RestoreSavedTryContext(current_block_->scope->parent()->parent(), | 8202 RestoreSavedTryContext(current_block_->scope->parent()->parent(), |
7987 try_blocks_list_->try_index(), | 8203 try_blocks_list_->try_index(), |
7988 current_block_->statements); | 8204 current_block_->statements); |
7989 } else { | 8205 } else { |
7990 parsed_function()->reset_saved_try_ctx_vars(); | 8206 parsed_function()->reset_saved_try_ctx_vars(); |
7991 } | 8207 } |
7992 | 8208 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8132 no_args)); | 8348 no_args)); |
8133 } | 8349 } |
8134 | 8350 |
8135 // Add nested block with user-defined code. This blocks allows | 8351 // Add nested block with user-defined code. This blocks allows |
8136 // declarations in the body to shadow the catch parameters. | 8352 // declarations in the body to shadow the catch parameters. |
8137 CheckToken(Token::kLBRACE); | 8353 CheckToken(Token::kLBRACE); |
8138 | 8354 |
8139 // In case of async closures we need to restore the saved try index of an | 8355 // In case of async closures we need to restore the saved try index of an |
8140 // outer try block (if it exists). | 8356 // outer try block (if it exists). |
8141 ASSERT(try_blocks_list_ != NULL); | 8357 ASSERT(try_blocks_list_ != NULL); |
8142 if (innermost_function().is_async_closure() || | 8358 if (innermost_function().IsAsyncClosure() || |
8143 innermost_function().IsAsyncFunction()) { | 8359 innermost_function().IsAsyncFunction()) { |
8144 if ((try_blocks_list_->outer_try_block() != NULL) && | 8360 if ((try_blocks_list_->outer_try_block() != NULL) && |
8145 (try_blocks_list_->outer_try_block()->try_block() | 8361 (try_blocks_list_->outer_try_block()->try_block() |
8146 ->scope->function_level() == | 8362 ->scope->function_level() == |
8147 current_block_->scope->function_level())) { | 8363 current_block_->scope->function_level())) { |
8148 // We need to unchain three scope levels: catch clause, catch | 8364 // We need to unchain three scope levels: catch clause, catch |
8149 // parameters, and the general try block. | 8365 // parameters, and the general try block. |
8150 RestoreSavedTryContext( | 8366 RestoreSavedTryContext( |
8151 current_block_->scope->parent()->parent()->parent(), | 8367 current_block_->scope->parent()->parent()->parent(), |
8152 try_blocks_list_->outer_try_block()->try_index(), | 8368 try_blocks_list_->outer_try_block()->try_index(), |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8240 // If the last body was entered conditionally and there is no need to add | 8456 // If the last body was entered conditionally and there is no need to add |
8241 // a rethrow, use an empty else body (current = NULL above). | 8457 // a rethrow, use an empty else body (current = NULL above). |
8242 | 8458 |
8243 while (!type_tests.is_empty()) { | 8459 while (!type_tests.is_empty()) { |
8244 AstNode* type_test = type_tests.RemoveLast(); | 8460 AstNode* type_test = type_tests.RemoveLast(); |
8245 SequenceNode* catch_block = catch_blocks.RemoveLast(); | 8461 SequenceNode* catch_block = catch_blocks.RemoveLast(); |
8246 | 8462 |
8247 // In case of async closures we need to restore the saved try index of an | 8463 // In case of async closures we need to restore the saved try index of an |
8248 // outer try block (if it exists). | 8464 // outer try block (if it exists). |
8249 ASSERT(try_blocks_list_ != NULL); | 8465 ASSERT(try_blocks_list_ != NULL); |
8250 if (innermost_function().is_async_closure() || | 8466 if (innermost_function().IsAsyncClosure() || |
8251 innermost_function().IsAsyncFunction()) { | 8467 innermost_function().IsAsyncFunction()) { |
8252 if ((try_blocks_list_->outer_try_block() != NULL) && | 8468 if ((try_blocks_list_->outer_try_block() != NULL) && |
8253 (try_blocks_list_->outer_try_block()->try_block() | 8469 (try_blocks_list_->outer_try_block()->try_block() |
8254 ->scope->function_level() == | 8470 ->scope->function_level() == |
8255 current_block_->scope->function_level())) { | 8471 current_block_->scope->function_level())) { |
8256 // We need to unchain three scope levels: catch clause, catch | 8472 // We need to unchain three scope levels: catch clause, catch |
8257 // parameters, and the general try block. | 8473 // parameters, and the general try block. |
8258 RestoreSavedTryContext( | 8474 RestoreSavedTryContext( |
8259 current_block_->scope->parent()->parent(), | 8475 current_block_->scope->parent()->parent(), |
8260 try_blocks_list_->outer_try_block()->try_index(), | 8476 try_blocks_list_->outer_try_block()->try_index(), |
(...skipping 17 matching lines...) Expand all Loading... |
8278 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 8494 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
8279 Scanner::kNoSourcePos, | 8495 Scanner::kNoSourcePos, |
8280 async_saved_try_ctx_name, | 8496 async_saved_try_ctx_name, |
8281 Type::ZoneHandle(Z, Type::DynamicType())); | 8497 Type::ZoneHandle(Z, Type::DynamicType())); |
8282 async_temp_scope_->AddVariable(async_saved_try_ctx); | 8498 async_temp_scope_->AddVariable(async_saved_try_ctx); |
8283 async_saved_try_ctx->set_is_captured(); | 8499 async_saved_try_ctx->set_is_captured(); |
8284 async_saved_try_ctx = current_block_->scope->LookupVariable( | 8500 async_saved_try_ctx = current_block_->scope->LookupVariable( |
8285 async_saved_try_ctx_name, false); | 8501 async_saved_try_ctx_name, false); |
8286 ASSERT(async_saved_try_ctx != NULL); | 8502 ASSERT(async_saved_try_ctx != NULL); |
8287 ASSERT(saved_try_context != NULL); | 8503 ASSERT(saved_try_context != NULL); |
8288 current_block_->statements->Add(new (Z) StoreLocalNode( | 8504 current_block_->statements->Add(new(Z) StoreLocalNode( |
8289 Scanner::kNoSourcePos, async_saved_try_ctx, new (Z) LoadLocalNode( | 8505 Scanner::kNoSourcePos, |
8290 Scanner::kNoSourcePos, saved_try_context))); | 8506 async_saved_try_ctx, |
| 8507 new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context))); |
8291 parsed_function()->set_saved_try_ctx(saved_try_context); | 8508 parsed_function()->set_saved_try_ctx(saved_try_context); |
8292 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); | 8509 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); |
8293 } | 8510 } |
8294 | 8511 |
8295 | 8512 |
8296 // Set up the currently relevant :saved_try_context_var on the stack: | 8513 // Restore the currently relevant :saved_try_context_var on the stack |
| 8514 // from the captured :async_saved_try_cts_var. |
8297 // * Try blocks: Set the context variable for this try block. | 8515 // * Try blocks: Set the context variable for this try block. |
8298 // * Catch/finally blocks: Set the context variable for any outer try block (if | 8516 // * Catch/finally blocks: Set the context variable for any outer try block (if |
8299 // existent). | 8517 // existent). |
8300 // | 8518 // |
8301 // Also save the captured variable and the stack variable to be able to set | 8519 // Also save the captured variable and the stack variable to be able to set |
8302 // it after a function continues execution (await). | 8520 // it after a function continues execution (await). |
8303 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, | 8521 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, |
8304 int16_t try_index, | 8522 int16_t try_index, |
8305 SequenceNode* target) { | 8523 SequenceNode* target) { |
8306 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( | 8524 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8374 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 8592 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
8375 OpenBlock(); | 8593 OpenBlock(); |
8376 current_block_->scope->AddLabel(try_label); | 8594 current_block_->scope->AddLabel(try_label); |
8377 } | 8595 } |
8378 | 8596 |
8379 // Now parse the 'try' block. | 8597 // Now parse the 'try' block. |
8380 OpenBlock(); | 8598 OpenBlock(); |
8381 PushTryBlock(current_block_); | 8599 PushTryBlock(current_block_); |
8382 ExpectToken(Token::kLBRACE); | 8600 ExpectToken(Token::kLBRACE); |
8383 | 8601 |
8384 if (innermost_function().is_async_closure() || | 8602 if (innermost_function().IsAsyncClosure() || |
8385 innermost_function().IsAsyncFunction()) { | 8603 innermost_function().IsAsyncFunction()) { |
8386 SetupSavedTryContext(context_var); | 8604 SetupSavedTryContext(context_var); |
8387 } | 8605 } |
8388 | 8606 |
8389 ParseStatementSequence(); | 8607 ParseStatementSequence(); |
8390 ExpectToken(Token::kRBRACE); | 8608 ExpectToken(Token::kRBRACE); |
8391 SequenceNode* try_block = CloseBlock(); | 8609 SequenceNode* try_block = CloseBlock(); |
8392 | 8610 |
8393 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | 8611 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && |
8394 (CurrentToken() != Token::kFINALLY)) { | 8612 (CurrentToken() != Token::kFINALLY)) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8553 } else if (token == Token::kDO) { | 8771 } else if (token == Token::kDO) { |
8554 statement = ParseDoWhileStatement(label_name); | 8772 statement = ParseDoWhileStatement(label_name); |
8555 } else if (token == Token::kSWITCH) { | 8773 } else if (token == Token::kSWITCH) { |
8556 statement = ParseSwitchStatement(label_name); | 8774 statement = ParseSwitchStatement(label_name); |
8557 } else if (token == Token::kTRY) { | 8775 } else if (token == Token::kTRY) { |
8558 statement = ParseTryStatement(label_name); | 8776 statement = ParseTryStatement(label_name); |
8559 } else if (token == Token::kRETURN) { | 8777 } else if (token == Token::kRETURN) { |
8560 const intptr_t return_pos = TokenPos(); | 8778 const intptr_t return_pos = TokenPos(); |
8561 ConsumeToken(); | 8779 ConsumeToken(); |
8562 if (CurrentToken() != Token::kSEMICOLON) { | 8780 if (CurrentToken() != Token::kSEMICOLON) { |
| 8781 const intptr_t expr_pos = TokenPos(); |
8563 if (current_function().IsConstructor() && | 8782 if (current_function().IsConstructor() && |
8564 (current_block_->scope->function_level() == 0)) { | 8783 (current_block_->scope->function_level() == 0)) { |
8565 ReportError(return_pos, | 8784 ReportError(expr_pos, |
8566 "return of a value not allowed in constructors"); | 8785 "return of a value is not allowed in constructors"); |
| 8786 } else if (current_function().IsGenerator()) { |
| 8787 ReportError(expr_pos, "generator functions may not return a value"); |
8567 } | 8788 } |
8568 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8789 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
8569 statement = new(Z) ReturnNode(statement_pos, expr); | 8790 statement = new(Z) ReturnNode(statement_pos, expr); |
8570 } else { | 8791 } else { |
8571 statement = new(Z) ReturnNode(statement_pos); | 8792 if (current_function().IsSyncGenClosure() && |
| 8793 (current_block_->scope->function_level() == 0)) { |
| 8794 // In a synchronous generator, return without an expression |
| 8795 // returns false, signaling that the iterator terminates and |
| 8796 // did not yield a value. |
| 8797 statement = new(Z) ReturnNode(statement_pos, |
| 8798 new(Z) LiteralNode(return_pos, Bool::False())); |
| 8799 } else { |
| 8800 statement = new(Z) ReturnNode(statement_pos); |
| 8801 } |
8572 } | 8802 } |
8573 AddNodeForFinallyInlining(statement); | 8803 AddNodeForFinallyInlining(statement); |
8574 ExpectSemicolon(); | 8804 ExpectSemicolon(); |
| 8805 } else if (IsYieldKeyword()) { |
| 8806 bool is_yield_each = false; |
| 8807 ConsumeToken(); |
| 8808 ASSERT(innermost_function().IsGenerator() || |
| 8809 innermost_function().IsSyncGenClosure()); |
| 8810 if (CurrentToken() == Token::kMUL) { |
| 8811 is_yield_each = true; |
| 8812 ConsumeToken(); |
| 8813 } |
| 8814 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8815 LocalVariable* iterator_param = |
| 8816 LookupLocalScope(Symbols::IteratorParameter()); |
| 8817 ASSERT(iterator_param != NULL); |
| 8818 // Generate :iterator.current = expr; |
| 8819 AstNode* iterator = |
| 8820 new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param); |
| 8821 AstNode* store_current = |
| 8822 new(Z) InstanceSetterNode(Scanner::kNoSourcePos, |
| 8823 iterator, |
| 8824 String::ZoneHandle(Symbols::Current().raw()), |
| 8825 expr); |
| 8826 LetNode* yield = new(Z) LetNode(statement_pos); |
| 8827 yield->AddNode(store_current); |
| 8828 if (is_yield_each) { |
| 8829 // Generate :iterator.isYieldEach = true; |
| 8830 AstNode* set_is_yield_each = |
| 8831 new(Z) InstanceSetterNode(Scanner::kNoSourcePos, |
| 8832 iterator, |
| 8833 String::ZoneHandle(Symbols::IsYieldEach().raw()), |
| 8834 new(Z) LiteralNode(TokenPos(), Bool::True())); |
| 8835 yield->AddNode(set_is_yield_each); |
| 8836 } |
| 8837 AwaitMarkerNode* await_marker = new(Z) AwaitMarkerNode(); |
| 8838 await_marker->set_scope(current_block_->scope); |
| 8839 yield->AddNode(await_marker); |
| 8840 // Return true to indicate that a value has been generated. |
| 8841 ReturnNode* return_true = new(Z) ReturnNode(statement_pos, |
| 8842 new(Z) LiteralNode(TokenPos(), Bool::True())); |
| 8843 return_true->set_return_type(ReturnNode::kContinuationTarget); |
| 8844 yield->AddNode(return_true); |
| 8845 statement = yield; |
| 8846 ExpectSemicolon(); |
8575 } else if (token == Token::kIF) { | 8847 } else if (token == Token::kIF) { |
8576 statement = ParseIfStatement(label_name); | 8848 statement = ParseIfStatement(label_name); |
8577 } else if (token == Token::kASSERT) { | 8849 } else if (token == Token::kASSERT) { |
8578 statement = ParseAssertStatement(); | 8850 statement = ParseAssertStatement(); |
8579 ExpectSemicolon(); | 8851 ExpectSemicolon(); |
8580 } else if (IsVariableDeclaration()) { | 8852 } else if (IsVariableDeclaration()) { |
8581 statement = ParseVariableDeclarationList(); | 8853 statement = ParseVariableDeclarationList(); |
8582 ExpectSemicolon(); | 8854 ExpectSemicolon(); |
8583 } else if (IsFunctionDeclaration()) { | 8855 } else if (IsFunctionDeclaration()) { |
8584 statement = ParseFunctionStatement(false); | 8856 statement = ParseFunctionStatement(false); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8750 return IsIdentifier() && CurrentLiteral()->Equals(literal); | 9022 return IsIdentifier() && CurrentLiteral()->Equals(literal); |
8751 } | 9023 } |
8752 | 9024 |
8753 | 9025 |
8754 bool Parser::IsAwaitKeyword() { | 9026 bool Parser::IsAwaitKeyword() { |
8755 return await_is_keyword_ && | 9027 return await_is_keyword_ && |
8756 (CurrentLiteral()->raw() == Symbols::Await().raw()); | 9028 (CurrentLiteral()->raw() == Symbols::Await().raw()); |
8757 } | 9029 } |
8758 | 9030 |
8759 | 9031 |
| 9032 bool Parser::IsYieldKeyword() { |
| 9033 return await_is_keyword_ && |
| 9034 (CurrentLiteral()->raw() == Symbols::Yield().raw()); |
| 9035 } |
| 9036 |
| 9037 |
8760 static bool IsIncrementOperator(Token::Kind token) { | 9038 static bool IsIncrementOperator(Token::Kind token) { |
8761 return token == Token::kINCR || token == Token::kDECR; | 9039 return token == Token::kINCR || token == Token::kDECR; |
8762 } | 9040 } |
8763 | 9041 |
8764 | 9042 |
8765 static bool IsPrefixOperator(Token::Kind token) { | 9043 static bool IsPrefixOperator(Token::Kind token) { |
8766 return (token == Token::kSUB) || | 9044 return (token == Token::kSUB) || |
8767 (token == Token::kNOT) || | 9045 (token == Token::kNOT) || |
8768 (token == Token::kBIT_NOT); | 9046 (token == Token::kBIT_NOT); |
8769 } | 9047 } |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9407 return expr; | 9685 return expr; |
9408 } | 9686 } |
9409 | 9687 |
9410 | 9688 |
9411 AstNode* Parser::ParseUnaryExpr() { | 9689 AstNode* Parser::ParseUnaryExpr() { |
9412 TRACE_PARSER("ParseUnaryExpr"); | 9690 TRACE_PARSER("ParseUnaryExpr"); |
9413 AstNode* expr = NULL; | 9691 AstNode* expr = NULL; |
9414 const intptr_t op_pos = TokenPos(); | 9692 const intptr_t op_pos = TokenPos(); |
9415 if (IsAwaitKeyword()) { | 9693 if (IsAwaitKeyword()) { |
9416 TRACE_PARSER("ParseAwaitExpr"); | 9694 TRACE_PARSER("ParseAwaitExpr"); |
| 9695 if (!innermost_function().IsAsyncFunction() && |
| 9696 !innermost_function().IsAsyncClosure()) { |
| 9697 ReportError("await operator is only allowed in async function"); |
| 9698 } |
9417 ConsumeToken(); | 9699 ConsumeToken(); |
9418 parsed_function()->record_await(); | 9700 parsed_function()->record_await(); |
9419 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr()); | 9701 expr = new (Z) AwaitNode(op_pos, ParseUnaryExpr()); |
9420 } else if (IsPrefixOperator(CurrentToken())) { | 9702 } else if (IsPrefixOperator(CurrentToken())) { |
9421 Token::Kind unary_op = CurrentToken(); | 9703 Token::Kind unary_op = CurrentToken(); |
9422 if (unary_op == Token::kSUB) { | 9704 if (unary_op == Token::kSUB) { |
9423 unary_op = Token::kNEGATE; | 9705 unary_op = Token::kNEGATE; |
9424 } | 9706 } |
9425 ConsumeToken(); | 9707 ConsumeToken(); |
9426 expr = ParseUnaryExpr(); | 9708 expr = ParseUnaryExpr(); |
(...skipping 2815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12242 void Parser::SkipQualIdent() { | 12524 void Parser::SkipQualIdent() { |
12243 ASSERT(IsIdentifier()); | 12525 ASSERT(IsIdentifier()); |
12244 ConsumeToken(); | 12526 ConsumeToken(); |
12245 if (CurrentToken() == Token::kPERIOD) { | 12527 if (CurrentToken() == Token::kPERIOD) { |
12246 ConsumeToken(); // Consume the kPERIOD token. | 12528 ConsumeToken(); // Consume the kPERIOD token. |
12247 ExpectIdentifier("identifier expected after '.'"); | 12529 ExpectIdentifier("identifier expected after '.'"); |
12248 } | 12530 } |
12249 } | 12531 } |
12250 | 12532 |
12251 } // namespace dart | 12533 } // namespace dart |
OLD | NEW |