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

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

Issue 447003003: Introduce await (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments Created 6 years, 4 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/symbols.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/bootstrap.h" 10 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 11 #include "vm/class_finalizer.h"
11 #include "vm/compiler.h" 12 #include "vm/compiler.h"
12 #include "vm/compiler_stats.h" 13 #include "vm/compiler_stats.h"
13 #include "vm/dart_api_impl.h" 14 #include "vm/dart_api_impl.h"
14 #include "vm/dart_entry.h" 15 #include "vm/dart_entry.h"
15 #include "vm/flags.h" 16 #include "vm/flags.h"
16 #include "vm/growable_array.h" 17 #include "vm/growable_array.h"
17 #include "vm/handles.h" 18 #include "vm/handles.h"
18 #include "vm/heap.h" 19 #include "vm/heap.h"
(...skipping 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after
2981 } 2982 }
2982 ASSERT((CurrentToken() == Token::kLPAREN) || 2983 ASSERT((CurrentToken() == Token::kLPAREN) ||
2983 func.IsGetterFunction() || 2984 func.IsGetterFunction() ||
2984 func.is_async_closure()); 2985 func.is_async_closure());
2985 const bool allow_explicit_default_values = true; 2986 const bool allow_explicit_default_values = true;
2986 if (func.IsGetterFunction()) { 2987 if (func.IsGetterFunction()) {
2987 // Populate function scope with the formal parameters. Since in this case 2988 // Populate function scope with the formal parameters. Since in this case
2988 // we are compiling a getter this will at most populate the receiver. 2989 // we are compiling a getter this will at most populate the receiver.
2989 AddFormalParamsToScope(&params, current_block_->scope); 2990 AddFormalParamsToScope(&params, current_block_->scope);
2990 } else if (func.is_async_closure()) { 2991 } else if (func.is_async_closure()) {
2992 // Async closures have one optional parameter for continuation results.
2993 ParamDesc result_param;
2994 result_param.name = &Symbols::AsyncOperationParam();
2995 result_param.default_value = &Object::null_instance();
2996 result_param.type = &Type::ZoneHandle(I, Type::DynamicType());
2997 params.parameters->Add(result_param);
2998 params.num_optional_parameters++;
2999 params.has_optional_positional_parameters = true;
3000 SetupDefaultsForOptionalParams(&params, default_parameter_values);
2991 AddFormalParamsToScope(&params, current_block_->scope); 3001 AddFormalParamsToScope(&params, current_block_->scope);
2992 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); 3002 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved());
2993 ASSERT(func.NumParameters() == params.parameters->length()); 3003 ASSERT(func.NumParameters() == params.parameters->length());
2994 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { 3004 if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
2995 // Parse away any formal parameters, as they are accessed as as context 3005 // Parse away any formal parameters, as they are accessed as as context
2996 // variables. 3006 // variables.
2997 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3007 ParamList parse_away;
3008 ParseFormalParameterList(allow_explicit_default_values,
3009 false,
3010 &parse_away);
2998 } 3011 }
2999 } else { 3012 } else {
3000 ParseFormalParameterList(allow_explicit_default_values, false, &params); 3013 ParseFormalParameterList(allow_explicit_default_values, false, &params);
3001 3014
3002 // The number of parameters and their type are not yet set in local 3015 // The number of parameters and their type are not yet set in local
3003 // functions, since they are not 'top-level' parsed. 3016 // functions, since they are not 'top-level' parsed.
3004 if (func.IsLocalFunction()) { 3017 if (func.IsLocalFunction()) {
3005 AddFormalParamsToFunction(&params, func); 3018 AddFormalParamsToFunction(&params, func);
3006 } 3019 }
3007 SetupDefaultsForOptionalParams(&params, default_parameter_values); 3020 SetupDefaultsForOptionalParams(&params, default_parameter_values);
(...skipping 29 matching lines...) Expand all
3037 } 3050 }
3038 3051
3039 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); 3052 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
3040 func.set_modifier(func_modifier); 3053 func.set_modifier(func_modifier);
3041 3054
3042 OpenBlock(); // Open a nested scope for the outermost function block. 3055 OpenBlock(); // Open a nested scope for the outermost function block.
3043 3056
3044 Function& async_closure = Function::ZoneHandle(I); 3057 Function& async_closure = Function::ZoneHandle(I);
3045 if (func.IsAsyncFunction() && !func.is_async_closure()) { 3058 if (func.IsAsyncFunction() && !func.is_async_closure()) {
3046 async_closure = OpenAsyncFunction(formal_params_pos); 3059 async_closure = OpenAsyncFunction(formal_params_pos);
3060 } else if (func.is_async_closure()) {
3061 OpenAsyncClosure();
3047 } 3062 }
3048 3063
3049 intptr_t end_token_pos = 0; 3064 intptr_t end_token_pos = 0;
3050 if (CurrentToken() == Token::kLBRACE) { 3065 if (CurrentToken() == Token::kLBRACE) {
3051 ConsumeToken(); 3066 ConsumeToken();
3052 if (String::Handle(I, func.name()).Equals( 3067 if (String::Handle(I, func.name()).Equals(
3053 Symbols::EqualOperator())) { 3068 Symbols::EqualOperator())) {
3054 const Class& owner = Class::Handle(I, func.Owner()); 3069 const Class& owner = Class::Handle(I, func.Owner());
3055 if (!owner.IsObjectClass()) { 3070 if (!owner.IsObjectClass()) {
3056 AddEqualityNullCheck(); 3071 AddEqualityNullCheck();
(...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after
5519 // We are parsing a nested function while compiling the enclosing function. 5534 // We are parsing a nested function while compiling the enclosing function.
5520 outer_scope = 5535 outer_scope =
5521 new(I) LocalScope(current_block_->scope, 5536 new(I) LocalScope(current_block_->scope,
5522 current_block_->scope->function_level() + 1, 5537 current_block_->scope->function_level() + 1,
5523 0); 5538 0);
5524 } 5539 }
5525 ChainNewBlock(outer_scope); 5540 ChainNewBlock(outer_scope);
5526 } 5541 }
5527 5542
5528 5543
5544 void Parser::OpenAsyncClosure() {
5545 TRACE_PARSER("OpenAsyncClosure");
5546 parsed_function()->set_await_temps_scope(current_block_->scope);
5547 // TODO(mlippautz): Set up explicit jump table for await continuations.
5548 }
5549
5550
5529 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { 5551 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) {
5552 TRACE_PARSER("OpenAsyncFunction");
5530 // Create the closure containing the old body of this function. 5553 // Create the closure containing the old body of this function.
5531 Class& sig_cls = Class::ZoneHandle(I); 5554 Class& sig_cls = Class::ZoneHandle(I);
5532 Type& sig_type = Type::ZoneHandle(I); 5555 Type& sig_type = Type::ZoneHandle(I);
5533 Function& closure = Function::ZoneHandle(I); 5556 Function& closure = Function::ZoneHandle(I);
5534 String& sig = String::ZoneHandle(I); 5557 String& sig = String::ZoneHandle(I);
5535 ParamList closure_params; 5558 ParamList closure_params;
5536 closure_params.AddFinalParameter( 5559 closure_params.AddFinalParameter(
5537 formal_param_pos, 5560 formal_param_pos,
5538 &Symbols::ClosureParameter(), 5561 &Symbols::ClosureParameter(),
5539 &Type::ZoneHandle(I, Type::DynamicType())); 5562 &Type::ZoneHandle(I, Type::DynamicType()));
5563 ParamDesc result_param;
5564 result_param.name = &Symbols::AsyncOperationParam();
5565 result_param.default_value = &Object::null_instance();
5566 result_param.type = &Type::ZoneHandle(I, Type::DynamicType());
5567 closure_params.parameters->Add(result_param);
5568 closure_params.has_optional_positional_parameters = true;
5569 closure_params.num_optional_parameters++;
5540 closure = Function::NewClosureFunction( 5570 closure = Function::NewClosureFunction(
5541 Symbols::AnonymousClosure(), 5571 Symbols::AnonymousClosure(),
5542 innermost_function(), 5572 innermost_function(),
5543 formal_param_pos); 5573 formal_param_pos);
5544 AddFormalParamsToFunction(&closure_params, closure); 5574 AddFormalParamsToFunction(&closure_params, closure);
5545 closure.set_is_async_closure(true); 5575 closure.set_is_async_closure(true);
5546 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); 5576 closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
5547 sig = closure.Signature(); 5577 sig = closure.Signature();
5548 sig_cls = library_.LookupLocalClass(sig); 5578 sig_cls = library_.LookupLocalClass(sig);
5549 if (sig_cls.IsNull()) { 5579 if (sig_cls.IsNull()) {
(...skipping 23 matching lines...) Expand all
5573 current_block_->scope->set_begin_token_pos(statements->token_pos()); 5603 current_block_->scope->set_begin_token_pos(statements->token_pos());
5574 current_block_->scope->set_end_token_pos(TokenPos()); 5604 current_block_->scope->set_end_token_pos(TokenPos());
5575 } 5605 }
5576 current_block_ = current_block_->parent; 5606 current_block_ = current_block_->parent;
5577 return statements; 5607 return statements;
5578 } 5608 }
5579 5609
5580 5610
5581 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, 5611 SequenceNode* Parser::CloseAsyncFunction(const Function& closure,
5582 SequenceNode* closure_body) { 5612 SequenceNode* closure_body) {
5613 TRACE_PARSER("CloseAsyncFunction");
5583 ASSERT(!closure.IsNull()); 5614 ASSERT(!closure.IsNull());
5584 ASSERT(closure_body != NULL); 5615 ASSERT(closure_body != NULL);
5585 // The block for the async closure body has already been closed. Close the 5616 // The block for the async closure body has already been closed. Close the
5586 // corresponding function block. 5617 // corresponding function block.
5587 CloseBlock(); 5618 CloseBlock();
5588 5619
5589 // Create and return a new future that executes a closure with the current 5620 // Create and return a new future that executes a closure with the current
5590 // body. 5621 // body.
5591 5622
5592 bool found = false; 5623 bool found = false;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
5669 new (I) LoadLocalNode( 5700 new (I) LoadLocalNode(
5670 Scanner::kNoSourcePos, 5701 Scanner::kNoSourcePos,
5671 async_completer), 5702 async_completer),
5672 Symbols::CompleterFuture())); 5703 Symbols::CompleterFuture()));
5673 current_block_->statements->Add(return_node); 5704 current_block_->statements->Add(return_node);
5674 return CloseBlock(); 5705 return CloseBlock();
5675 } 5706 }
5676 5707
5677 5708
5678 void Parser::CloseAsyncClosure(SequenceNode* body) { 5709 void Parser::CloseAsyncClosure(SequenceNode* body) {
5710 TRACE_PARSER("CloseAsyncClosure");
5679 // We need a temporary expression to store intermediate return values. 5711 // We need a temporary expression to store intermediate return values.
5680 parsed_function()->EnsureExpressionTemp(); 5712 parsed_function()->EnsureExpressionTemp();
5681 } 5713 }
5682 5714
5683 5715
5684 // Set up default values for all optional parameters to the function. 5716 // Set up default values for all optional parameters to the function.
5685 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, 5717 void Parser::SetupDefaultsForOptionalParams(const ParamList* params,
5686 Array* default_values) { 5718 Array* default_values) {
5687 if (params->num_optional_parameters > 0) { 5719 if (params->num_optional_parameters > 0) {
5688 // Build array of default parameter values. 5720 // Build array of default parameter values.
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
5871 const intptr_t ident_pos = TokenPos(); 5903 const intptr_t ident_pos = TokenPos();
5872 const String& ident = *CurrentLiteral(); 5904 const String& ident = *CurrentLiteral();
5873 LocalVariable* variable = new(I) LocalVariable( 5905 LocalVariable* variable = new(I) LocalVariable(
5874 ident_pos, ident, type); 5906 ident_pos, ident, type);
5875 ConsumeToken(); // Variable identifier. 5907 ConsumeToken(); // Variable identifier.
5876 AstNode* initialization = NULL; 5908 AstNode* initialization = NULL;
5877 if (CurrentToken() == Token::kASSIGN) { 5909 if (CurrentToken() == Token::kASSIGN) {
5878 // Variable initialization. 5910 // Variable initialization.
5879 const intptr_t assign_pos = TokenPos(); 5911 const intptr_t assign_pos = TokenPos();
5880 ConsumeToken(); 5912 ConsumeToken();
5881 AstNode* expr = ParseExpr(is_const, kConsumeCascades); 5913 AstNode* expr = ParseAwaitableExpr(is_const, kConsumeCascades);
5882 initialization = new(I) StoreLocalNode( 5914 initialization = new(I) StoreLocalNode(
5883 assign_pos, variable, expr); 5915 assign_pos, variable, expr);
5884 if (is_const) { 5916 if (is_const) {
5885 ASSERT(expr->IsLiteralNode()); 5917 ASSERT(expr->IsLiteralNode());
5886 variable->SetConstValue(expr->AsLiteralNode()->literal()); 5918 variable->SetConstValue(expr->AsLiteralNode()->literal());
5887 } 5919 }
5888 } else if (is_final || is_const) { 5920 } else if (is_final || is_const) {
5889 ReportError(ident_pos, 5921 ReportError(ident_pos,
5890 "missing initialization of 'final' or 'const' variable"); 5922 "missing initialization of 'final' or 'const' variable");
5891 } else { 5923 } else {
(...skipping 1852 matching lines...) Expand 10 before | Expand all | Expand 10 after
7744 scope->LocalLookupVariable(Symbols::ExceptionVar()); 7776 scope->LocalLookupVariable(Symbols::ExceptionVar());
7745 ASSERT(excp_var != NULL); 7777 ASSERT(excp_var != NULL);
7746 LocalVariable* trace_var = 7778 LocalVariable* trace_var =
7747 scope->LocalLookupVariable(Symbols::StackTraceVar()); 7779 scope->LocalLookupVariable(Symbols::StackTraceVar());
7748 ASSERT(trace_var != NULL); 7780 ASSERT(trace_var != NULL);
7749 statement = new(I) ThrowNode( 7781 statement = new(I) ThrowNode(
7750 statement_pos, 7782 statement_pos,
7751 new(I) LoadLocalNode(statement_pos, excp_var), 7783 new(I) LoadLocalNode(statement_pos, excp_var),
7752 new(I) LoadLocalNode(statement_pos, trace_var)); 7784 new(I) LoadLocalNode(statement_pos, trace_var));
7753 } else { 7785 } else {
7754 statement = ParseExpr(kAllowConst, kConsumeCascades); 7786 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades);
7755 ExpectSemicolon(); 7787 ExpectSemicolon();
7756 } 7788 }
7757 return statement; 7789 return statement;
7758 } 7790 }
7759 7791
7760 7792
7761 void Parser::ReportError(const Error& error) { 7793 void Parser::ReportError(const Error& error) {
7762 Report::LongJump(error); 7794 Report::LongJump(error);
7763 UNREACHABLE(); 7795 UNREACHABLE();
7764 } 7796 }
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
8400 ASSERT(field.value() != Object::sentinel().raw()); 8432 ASSERT(field.value() != Object::sentinel().raw());
8401 ASSERT(field.value() != Object::transition_sentinel().raw()); 8433 ASSERT(field.value() != Object::transition_sentinel().raw());
8402 return new(iso) LiteralNode(expr->token_pos(), 8434 return new(iso) LiteralNode(expr->token_pos(),
8403 Instance::ZoneHandle(iso, field.value())); 8435 Instance::ZoneHandle(iso, field.value()));
8404 } 8436 }
8405 } 8437 }
8406 return expr; 8438 return expr;
8407 } 8439 }
8408 8440
8409 8441
8442 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const,
8443 bool consume_cascades) {
8444 TRACE_PARSER("ParseAwaitableExpr");
8445 parsed_function()->reset_have_seen_await();
8446 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades);
8447 if (parsed_function()->have_seen_await()) {
8448 if (!current_block_->scope->LookupVariable(
8449 Symbols::AsyncOperation(), true)) {
8450 // Async operations are always encapsulated into a local function. We only
8451 // need to transform the expression when generating code for this inner
8452 // function.
8453 return expr;
8454 }
8455 SequenceNode* intermediates_block = new(I) SequenceNode(
8456 Scanner::kNoSourcePos, current_block_->scope);
8457 AwaitTransformer at(intermediates_block, library_, parsed_function());
8458 AstNode* result = at.Transform(expr);
8459 current_block_->statements->Add(intermediates_block);
8460 parsed_function()->reset_have_seen_await();
8461 return result;
8462 }
8463 return expr;
8464 }
8465
8466
8410 AstNode* Parser::ParseExpr(bool require_compiletime_const, 8467 AstNode* Parser::ParseExpr(bool require_compiletime_const,
8411 bool consume_cascades) { 8468 bool consume_cascades) {
8412 TRACE_PARSER("ParseExpr"); 8469 TRACE_PARSER("ParseExpr");
8413 String* expr_ident = 8470 String* expr_ident =
8414 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; 8471 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
8415 const intptr_t expr_pos = TokenPos(); 8472 const intptr_t expr_pos = TokenPos();
8416 8473
8417 if (CurrentToken() == Token::kTHROW) { 8474 if (CurrentToken() == Token::kTHROW) {
8418 ConsumeToken(); 8475 ConsumeToken();
8419 if (CurrentToken() == Token::kSEMICOLON) { 8476 if (CurrentToken() == Token::kSEMICOLON) {
(...skipping 2348 matching lines...) Expand 10 before | Expand all | Expand 10 after
10768 TRACE_PARSER("ParsePrimary"); 10825 TRACE_PARSER("ParsePrimary");
10769 ASSERT(!is_top_level_); 10826 ASSERT(!is_top_level_);
10770 AstNode* primary = NULL; 10827 AstNode* primary = NULL;
10771 const Token::Kind token = CurrentToken(); 10828 const Token::Kind token = CurrentToken();
10772 if (IsFunctionLiteral()) { 10829 if (IsFunctionLiteral()) {
10773 // The name of a literal function is visible from inside the function, but 10830 // The name of a literal function is visible from inside the function, but
10774 // must not collide with names in the scope declaring the literal. 10831 // must not collide with names in the scope declaring the literal.
10775 OpenBlock(); 10832 OpenBlock();
10776 primary = ParseFunctionStatement(true); 10833 primary = ParseFunctionStatement(true);
10777 CloseBlock(); 10834 CloseBlock();
10835 } else if (IsLiteral("await") &&
10836 (parsed_function()->function().IsAsyncFunction() ||
10837 parsed_function()->function().is_async_closure())) {
10838 // The body of an async function is parsed multiple times. The first time
10839 // when setting up an AsyncFunction() for generating relevant scope
10840 // information. The second time the body is parsed for actually generating
10841 // code.
10842 TRACE_PARSER("ParseAwaitExpr");
10843 ConsumeToken();
10844 parsed_function()->record_await();
10845 primary = new(I) AwaitNode(
10846 TokenPos(), ParseExpr(kAllowConst, kConsumeCascades));
10778 } else if (IsIdentifier()) { 10847 } else if (IsIdentifier()) {
10779 intptr_t qual_ident_pos = TokenPos(); 10848 intptr_t qual_ident_pos = TokenPos();
10780 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(I, ParsePrefix()); 10849 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(I, ParsePrefix());
10781 String& ident = *CurrentLiteral(); 10850 String& ident = *CurrentLiteral();
10782 ConsumeToken(); 10851 ConsumeToken();
10783 if (prefix.IsNull()) { 10852 if (prefix.IsNull()) {
10784 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { 10853 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) {
10785 // Check whether the identifier is a type parameter. 10854 // Check whether the identifier is a type parameter.
10786 if (!current_class().IsNull()) { 10855 if (!current_class().IsNull()) {
10787 TypeParameter& type_param = TypeParameter::ZoneHandle(I, 10856 TypeParameter& type_param = TypeParameter::ZoneHandle(I,
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
11308 void Parser::SkipQualIdent() { 11377 void Parser::SkipQualIdent() {
11309 ASSERT(IsIdentifier()); 11378 ASSERT(IsIdentifier());
11310 ConsumeToken(); 11379 ConsumeToken();
11311 if (CurrentToken() == Token::kPERIOD) { 11380 if (CurrentToken() == Token::kPERIOD) {
11312 ConsumeToken(); // Consume the kPERIOD token. 11381 ConsumeToken(); // Consume the kPERIOD token.
11313 ExpectIdentifier("identifier expected after '.'"); 11382 ExpectIdentifier("identifier expected after '.'");
11314 } 11383 }
11315 } 11384 }
11316 11385
11317 } // namespace dart 11386 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698