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

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

Issue 888463004: Add support for sync* and yield (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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(&params, current_block_->scope); 3079 AddFormalParamsToScope(&params, current_block_->scope);
3071 } else if (func.is_async_closure()) { 3080 } else if (func.IsAsyncClosure()) {
3072 // Async closures have two optional parameters: 3081 AddAsyncClosureParameters(&params);
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(&params, default_parameter_values); 3082 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3096 AddFormalParamsToScope(&params, current_block_->scope); 3083 AddFormalParamsToScope(&params, 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(&params);
3096 SetupDefaultsForOptionalParams(&params, default_parameter_values);
3097 AddFormalParamsToScope(&params, 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, &params); 3108 ParseFormalParameterList(allow_explicit_default_values, false, &params);
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(&params, func); 3113 AddFormalParamsToFunction(&params, func);
3114 } 3114 }
3115 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3115 SetupDefaultsForOptionalParams(&params, default_parameter_values);
(...skipping 21 matching lines...) Expand all
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
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
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
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
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
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
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, &params); 5305 ParseFormalParameterList(allow_explicit_default_values, false, &params);
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698