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

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

Issue 2013233003: Remove an unnecessary (empty) scope, streamline the function parsing code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « no previous file | no next file » | 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 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 7579 matching lines...) Expand 10 before | Expand all | Expand 10 after
7590 sequence->Add(declaration); 7590 sequence->Add(declaration);
7591 initializers = sequence; 7591 initializers = sequence;
7592 } 7592 }
7593 return initializers; 7593 return initializers;
7594 } 7594 }
7595 7595
7596 7596
7597 AstNode* Parser::ParseFunctionStatement(bool is_literal) { 7597 AstNode* Parser::ParseFunctionStatement(bool is_literal) {
7598 TRACE_PARSER("ParseFunctionStatement"); 7598 TRACE_PARSER("ParseFunctionStatement");
7599 AbstractType& result_type = AbstractType::Handle(Z); 7599 AbstractType& result_type = AbstractType::Handle(Z);
7600 const String* variable_name = NULL;
Kevin Millikin (Google) 2016/05/27 14:07:36 If is_literal, variable_name is always NULL. If !
7601 const String* function_name = NULL; 7600 const String* function_name = NULL;
7602 7601
7603 result_type = Type::DynamicType(); 7602 result_type = Type::DynamicType();
7604 7603
7605 const TokenPosition function_pos = TokenPos(); 7604 const TokenPosition function_pos = TokenPos();
7606 TokenPosition metadata_pos = TokenPosition::kNoSource; 7605 TokenPosition metadata_pos = TokenPosition::kNoSource;
7607 if (is_literal) { 7606 if (is_literal) {
7608 ASSERT(CurrentToken() == Token::kLPAREN); 7607 ASSERT(CurrentToken() == Token::kLPAREN);
7609 function_name = &Symbols::AnonymousClosure(); 7608 function_name = &Symbols::AnonymousClosure();
7610 } else { 7609 } else {
7611 metadata_pos = SkipMetadata(); 7610 metadata_pos = SkipMetadata();
7612 if (CurrentToken() == Token::kVOID) { 7611 if (CurrentToken() == Token::kVOID) {
7613 ConsumeToken(); 7612 ConsumeToken();
7614 result_type = Type::VoidType(); 7613 result_type = Type::VoidType();
7615 } else if ((CurrentToken() == Token::kIDENT) && 7614 } else if ((CurrentToken() == Token::kIDENT) &&
7616 (LookaheadToken(1) != Token::kLPAREN)) { 7615 (LookaheadToken(1) != Token::kLPAREN)) {
7617 result_type = ParseType(ClassFinalizer::kCanonicalize); 7616 result_type = ParseType(ClassFinalizer::kCanonicalize);
7618 } 7617 }
7619 const TokenPosition name_pos = TokenPos(); 7618 const TokenPosition name_pos = TokenPos();
7620 variable_name = ExpectIdentifier("function name expected"); 7619 function_name = ExpectIdentifier("function name expected");
7621 function_name = variable_name;
7622 7620
7623 // Check that the function name has not been referenced 7621 // Check that the function name has not been referenced
7624 // before this declaration. 7622 // before this declaration.
7625 ASSERT(current_block_ != NULL); 7623 ASSERT(current_block_ != NULL);
7626 const TokenPosition previous_pos = 7624 const TokenPosition previous_pos =
7627 current_block_->scope->PreviousReferencePos(*function_name); 7625 current_block_->scope->PreviousReferencePos(*function_name);
7628 if (previous_pos.IsReal()) { 7626 if (previous_pos.IsReal()) {
7629 ASSERT(!script_.IsNull()); 7627 ASSERT(!script_.IsNull());
7630 intptr_t line_number; 7628 intptr_t line_number;
7631 script_.GetTokenLocation(previous_pos, &line_number, NULL); 7629 script_.GetTokenLocation(previous_pos, &line_number, NULL);
(...skipping 27 matching lines...) Expand all
7659 library_.AddFunctionMetadata(function, metadata_pos); 7657 library_.AddFunctionMetadata(function, metadata_pos);
7660 } 7658 }
7661 } 7659 }
7662 7660
7663 // The function type needs to be finalized at compile time, since the closure 7661 // The function type needs to be finalized at compile time, since the closure
7664 // may be type checked at run time when assigned to a function variable, 7662 // may be type checked at run time when assigned to a function variable,
7665 // passed as a function argument, or returned as a function result. 7663 // passed as a function argument, or returned as a function result.
7666 7664
7667 LocalVariable* function_variable = NULL; 7665 LocalVariable* function_variable = NULL;
7668 Type& function_type = Type::ZoneHandle(Z); 7666 Type& function_type = Type::ZoneHandle(Z);
7669 if (variable_name != NULL) { 7667 if (!is_literal) {
7670 // Since the function type depends on the signature of the closure function, 7668 // Since the function type depends on the signature of the closure function,
7671 // it cannot be determined before the formal parameter list of the closure 7669 // it cannot be determined before the formal parameter list of the closure
7672 // function is parsed. Therefore, we set the function type to a new 7670 // function is parsed. Therefore, we set the function type to a new
7673 // function type to be patched after the actual type is known. 7671 // function type to be patched after the actual type is known.
7674 // We temporarily use the Closure class as scope class. 7672 // We temporarily use the Closure class as scope class.
7675 const Class& unknown_scope_class = Class::Handle(Z, 7673 const Class& unknown_scope_class = Class::Handle(Z,
7676 I->object_store()->closure_class()); 7674 I->object_store()->closure_class());
7677 function_type = Type::New(unknown_scope_class, 7675 function_type = Type::New(unknown_scope_class,
7678 TypeArguments::Handle(Z), 7676 TypeArguments::Handle(Z),
7679 function_pos); 7677 function_pos);
7680 function_type.set_signature(function); 7678 function_type.set_signature(function);
7681 function_type.SetIsFinalized(); // No finalization needed. 7679 function_type.SetIsFinalized(); // No finalization needed.
7682 7680
7683 // Add the function variable to the scope before parsing the function in 7681 // Add the function variable to the scope before parsing the function in
7684 // order to allow self reference from inside the function. 7682 // order to allow self reference from inside the function.
7685 function_variable = new(Z) LocalVariable(function_pos, 7683 function_variable = new(Z) LocalVariable(function_pos,
7686 *variable_name, 7684 *function_name,
7687 function_type); 7685 function_type);
7688 function_variable->set_is_final(); 7686 function_variable->set_is_final();
7689 ASSERT(current_block_ != NULL); 7687 ASSERT(current_block_ != NULL);
7690 ASSERT(current_block_->scope != NULL); 7688 ASSERT(current_block_->scope != NULL);
7691 if (!current_block_->scope->AddVariable(function_variable)) { 7689 if (!current_block_->scope->AddVariable(function_variable)) {
7692 LocalVariable* existing_var = 7690 LocalVariable* existing_var =
7693 current_block_->scope->LookupVariable(function_variable->name(), 7691 current_block_->scope->LookupVariable(function_variable->name(),
7694 true); 7692 true);
7695 ASSERT(existing_var != NULL); 7693 ASSERT(existing_var != NULL);
7696 // Use before define cases have already been detected and reported above. 7694 // Use before define cases have already been detected and reported above.
(...skipping 23 matching lines...) Expand all
7720 if ((current_block_->scope->function_level() > 0) && 7718 if ((current_block_->scope->function_level() > 0) &&
7721 Class::Handle(signature_type.type_class()).IsGeneric()) { 7719 Class::Handle(signature_type.type_class()).IsGeneric()) {
7722 CaptureInstantiator(); 7720 CaptureInstantiator();
7723 } 7721 }
7724 7722
7725 // A local signature type itself cannot be malformed or malbounded, only its 7723 // A local signature type itself cannot be malformed or malbounded, only its
7726 // signature function's result type or parameter types may be. 7724 // signature function's result type or parameter types may be.
7727 ASSERT(!signature_type.IsMalformed()); 7725 ASSERT(!signature_type.IsMalformed());
7728 ASSERT(!signature_type.IsMalbounded()); 7726 ASSERT(!signature_type.IsMalbounded());
7729 7727
7730 if (variable_name != NULL) { 7728 if (!is_literal) {
7731 // Patch the function type of the variable now that the signature is known. 7729 // Patch the function type of the variable now that the signature is known.
7732 function_type.set_type_class( 7730 function_type.set_type_class(
7733 Class::Handle(Z, signature_type.type_class())); 7731 Class::Handle(Z, signature_type.type_class()));
7734 function_type.set_arguments( 7732 function_type.set_arguments(
7735 TypeArguments::Handle(Z, signature_type.arguments())); 7733 TypeArguments::Handle(Z, signature_type.arguments()));
7736 ASSERT(function_type.signature() == function.raw()); 7734 ASSERT(function_type.signature() == function.raw());
7737 7735
7738 // The function type was initially marked as instantiated, but it may 7736 // The function type was initially marked as instantiated, but it may
7739 // actually be uninstantiated. 7737 // actually be uninstantiated.
7740 function_type.ResetIsFinalized(); 7738 function_type.ResetIsFinalized();
7741 7739
7742 // The function variable type should have been patched above. 7740 // The function variable type should have been patched above.
7743 ASSERT((function_variable == NULL) || 7741 ASSERT(function_variable->type().raw() == function_type.raw());
7744 (function_variable->type().raw() == function_type.raw()));
7745 } 7742 }
7746 7743
7747 // The code generator does not compile the closure function when visiting 7744 // The code generator does not compile the closure function when visiting
7748 // a ClosureNode. The generated code allocates a new Closure object containing 7745 // a ClosureNode. The generated code allocates a new Closure object containing
7749 // the current context. The type of the Closure object refers to the closure 7746 // the current context. The type of the Closure object refers to the closure
7750 // function, which will be compiled on first invocation of the closure object. 7747 // function, which will be compiled on first invocation of the closure object.
7751 // Therefore, we ignore the parsed default_parameter_values and the 7748 // Therefore, we ignore the parsed default_parameter_values and the
7752 // node_sequence representing the body of the closure function, which will be 7749 // node_sequence representing the body of the closure function, which will be
7753 // parsed again when compiled later. 7750 // parsed again when compiled later.
7754 // The only purpose of parsing the function now (besides reporting obvious 7751 // The only purpose of parsing the function now (besides reporting obvious
7755 // errors) is to mark referenced variables of the enclosing scopes as 7752 // errors) is to mark referenced variables of the enclosing scopes as
7756 // captured. The captured variables will be recorded along with their 7753 // captured. The captured variables will be recorded along with their
7757 // allocation information in a Scope object stored in the function object. 7754 // allocation information in a Scope object stored in the function object.
7758 // This Scope object is then provided to the compiler when compiling the local 7755 // This Scope object is then provided to the compiler when compiling the local
7759 // function. It would be too early to record the captured variables here, 7756 // function. It would be too early to record the captured variables here,
7760 // since further closure functions may capture more variables. 7757 // since further closure functions may capture more variables.
7761 // This Scope object is constructed after all variables have been allocated. 7758 // This Scope object is constructed after all variables have been allocated.
7762 // The local scope of the parsed function can be pruned, since contained 7759 // The local scope of the parsed function can be pruned, since contained
7763 // variables are not relevant for the compilation of the enclosing function. 7760 // variables are not relevant for the compilation of the enclosing function.
7764 // This pruning is done by omitting to hook the local scope in its parent 7761 // This pruning is done by omitting to hook the local scope in its parent
7765 // scope in the constructor of LocalScope. 7762 // scope in the constructor of LocalScope.
7766 AstNode* closure = new(Z) ClosureNode( 7763 AstNode* closure = new(Z) ClosureNode(
7767 function_pos, function, NULL, statements->scope()); 7764 function_pos, function, NULL, statements->scope());
7768 7765
7769 if (function_variable == NULL) { 7766 return is_literal
7770 ASSERT(is_literal); 7767 ? closure
7771 return closure; 7768 : new(Z) StoreLocalNode(function_pos, function_variable, closure);
7772 } else {
7773 AstNode* initialization = new(Z) StoreLocalNode(
7774 function_pos, function_variable, closure);
7775 return initialization;
7776 }
7777 } 7769 }
7778 7770
7779 7771
7780 // Returns true if the current and next tokens can be parsed as type 7772 // Returns true if the current and next tokens can be parsed as type
7781 // parameters. Current token position is not saved and restored. 7773 // parameters. Current token position is not saved and restored.
7782 bool Parser::TryParseTypeParameters() { 7774 bool Parser::TryParseTypeParameters() {
7783 if (CurrentToken() == Token::kLT) { 7775 if (CurrentToken() == Token::kLT) {
7784 // We are possibly looking at type parameters. Find closing ">". 7776 // We are possibly looking at type parameters. Find closing ">".
7785 int nesting_level = 0; 7777 int nesting_level = 0;
7786 do { 7778 do {
(...skipping 6057 matching lines...) Expand 10 before | Expand all | Expand 10 after
13844 return primary; 13836 return primary;
13845 } 13837 }
13846 13838
13847 13839
13848 AstNode* Parser::ParsePrimary() { 13840 AstNode* Parser::ParsePrimary() {
13849 TRACE_PARSER("ParsePrimary"); 13841 TRACE_PARSER("ParsePrimary");
13850 ASSERT(!is_top_level_); 13842 ASSERT(!is_top_level_);
13851 AstNode* primary = NULL; 13843 AstNode* primary = NULL;
13852 const Token::Kind token = CurrentToken(); 13844 const Token::Kind token = CurrentToken();
13853 if (IsFunctionLiteral()) { 13845 if (IsFunctionLiteral()) {
13854 // The name of a literal function is visible from inside the function, but
13855 // must not collide with names in the scope declaring the literal.
13856 OpenBlock();
13857 primary = ParseFunctionStatement(true); 13846 primary = ParseFunctionStatement(true);
13858 CloseBlock();
13859 } else if (IsIdentifier()) { 13847 } else if (IsIdentifier()) {
13860 TokenPosition qual_ident_pos = TokenPos(); 13848 TokenPosition qual_ident_pos = TokenPos();
13861 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); 13849 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix());
13862 if (!prefix.IsNull()) { 13850 if (!prefix.IsNull()) {
13863 if (CurrentToken() == Token::kHASH) { 13851 if (CurrentToken() == Token::kHASH) {
13864 // Closurization of top-level entity in prefix scope. 13852 // Closurization of top-level entity in prefix scope.
13865 return new(Z) LiteralNode(qual_ident_pos, prefix); 13853 return new(Z) LiteralNode(qual_ident_pos, prefix);
13866 } else { 13854 } else {
13867 ExpectToken(Token::kPERIOD); 13855 ExpectToken(Token::kPERIOD);
13868 } 13856 }
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
14537 const ArgumentListNode& function_args, 14525 const ArgumentListNode& function_args,
14538 const LocalVariable* temp_for_last_arg, 14526 const LocalVariable* temp_for_last_arg,
14539 bool is_super_invocation) { 14527 bool is_super_invocation) {
14540 UNREACHABLE(); 14528 UNREACHABLE();
14541 return NULL; 14529 return NULL;
14542 } 14530 }
14543 14531
14544 } // namespace dart 14532 } // namespace dart
14545 14533
14546 #endif // DART_PRECOMPILED_RUNTIME 14534 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698