| 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 |