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

Side by Side Diff: src/parser.cc

Issue 7584005: Revert "Fix a bug in scope analysis." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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 | « src/parser.h ('k') | src/runtime.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2824 matching lines...) Expand 10 before | Expand all | Expand 10 after
2835 Expression* result = NULL; 2835 Expression* result = NULL;
2836 if (peek() == Token::FUNCTION) { 2836 if (peek() == Token::FUNCTION) {
2837 Expect(Token::FUNCTION, CHECK_OK); 2837 Expect(Token::FUNCTION, CHECK_OK);
2838 int function_token_position = scanner().location().beg_pos; 2838 int function_token_position = scanner().location().beg_pos;
2839 Handle<String> name; 2839 Handle<String> name;
2840 bool is_strict_reserved_name = false; 2840 bool is_strict_reserved_name = false;
2841 if (peek_any_identifier()) { 2841 if (peek_any_identifier()) {
2842 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, 2842 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
2843 CHECK_OK); 2843 CHECK_OK);
2844 } 2844 }
2845 result = ParseFunctionLiteral(name, 2845 result = ParseFunctionLiteral(name, is_strict_reserved_name,
2846 is_strict_reserved_name, 2846 function_token_position, NESTED, CHECK_OK);
2847 function_token_position,
2848 EXPRESSION,
2849 CHECK_OK);
2850 } else { 2847 } else {
2851 result = ParsePrimaryExpression(CHECK_OK); 2848 result = ParsePrimaryExpression(CHECK_OK);
2852 } 2849 }
2853 2850
2854 while (true) { 2851 while (true) {
2855 switch (peek()) { 2852 switch (peek()) {
2856 case Token::LBRACK: { 2853 case Token::LBRACK: {
2857 Consume(Token::LBRACK); 2854 Consume(Token::LBRACK);
2858 int pos = scanner().location().beg_pos; 2855 int pos = scanner().location().beg_pos;
2859 Expression* index = ParseExpression(true, CHECK_OK); 2856 Expression* index = ParseExpression(true, CHECK_OK);
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
3408 Handle<String> name; 3405 Handle<String> name;
3409 if (is_keyword) { 3406 if (is_keyword) {
3410 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); 3407 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
3411 } else { 3408 } else {
3412 name = GetSymbol(CHECK_OK); 3409 name = GetSymbol(CHECK_OK);
3413 } 3410 }
3414 FunctionLiteral* value = 3411 FunctionLiteral* value =
3415 ParseFunctionLiteral(name, 3412 ParseFunctionLiteral(name,
3416 false, // reserved words are allowed here 3413 false, // reserved words are allowed here
3417 RelocInfo::kNoPosition, 3414 RelocInfo::kNoPosition,
3418 EXPRESSION, 3415 DECLARATION,
3419 CHECK_OK); 3416 CHECK_OK);
3420 // Allow any number of parameters for compatiabilty with JSC. 3417 // Allow any number of parameters for compatiabilty with JSC.
3421 // Specification only allows zero parameters for get and one for set. 3418 // Specification only allows zero parameters for get and one for set.
3422 ObjectLiteral::Property* property = 3419 ObjectLiteral::Property* property =
3423 new(zone()) ObjectLiteral::Property(is_getter, value); 3420 new(zone()) ObjectLiteral::Property(is_getter, value);
3424 return property; 3421 return property;
3425 } else { 3422 } else {
3426 ReportUnexpectedToken(next); 3423 ReportUnexpectedToken(next);
3427 *ok = false; 3424 *ok = false;
3428 return NULL; 3425 return NULL;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
3615 return NULL; 3612 return NULL;
3616 } 3613 }
3617 done = (peek() == Token::RPAREN); 3614 done = (peek() == Token::RPAREN);
3618 if (!done) Expect(Token::COMMA, CHECK_OK); 3615 if (!done) Expect(Token::COMMA, CHECK_OK);
3619 } 3616 }
3620 Expect(Token::RPAREN, CHECK_OK); 3617 Expect(Token::RPAREN, CHECK_OK);
3621 return result; 3618 return result;
3622 } 3619 }
3623 3620
3624 3621
3625 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, 3622 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3626 bool name_is_strict_reserved, 3623 bool name_is_strict_reserved,
3627 int function_token_position, 3624 int function_token_position,
3628 FunctionLiteralType type, 3625 FunctionLiteralType type,
3629 bool* ok) { 3626 bool* ok) {
3630 // Function :: 3627 // Function ::
3631 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3628 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3632 bool has_name = !function_name.is_null(); 3629 bool is_named = !var_name.is_null();
3633 // The function's name, empty if the function is anonymous.
3634 if (!has_name) {
3635 function_name = isolate()->factory()->empty_symbol();
3636 }
3637 3630
3638 // The name of a named function expression, otherwise an empty handle. 3631 // The name associated with this function. If it's a function expression,
3639 Handle<String> self_name; 3632 // this is the actual function name, otherwise this is the name of the
3640 if (type == EXPRESSION && function_name->length() > 0) { 3633 // variable declared and initialized with the function (expression). In
3641 self_name = function_name; 3634 // that case, we don't have a function name (it's empty).
3635 Handle<String> name =
3636 is_named ? var_name : isolate()->factory()->empty_symbol();
3637 // The function name, if any.
3638 Handle<String> function_name = isolate()->factory()->empty_symbol();
3639 if (is_named && (type == EXPRESSION || type == NESTED)) {
3640 function_name = name;
3642 } 3641 }
3643 3642
3644 int num_parameters = 0; 3643 int num_parameters = 0;
3645 // Function declarations are hoisted. 3644 // Function declarations are hoisted.
3646 Scope* scope = (type == DECLARATION) 3645 Scope* scope = (type == DECLARATION)
3647 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) 3646 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false)
3648 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3647 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
3649 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); 3648 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
3650 int materialized_literal_count; 3649 int materialized_literal_count;
3651 int expected_property_count; 3650 int expected_property_count;
3652 int start_pos; 3651 int start_pos;
3653 int end_pos; 3652 int end_pos;
3654 bool only_simple_this_property_assignments; 3653 bool only_simple_this_property_assignments;
3655 Handle<FixedArray> this_property_assignments; 3654 Handle<FixedArray> this_property_assignments;
3656 bool has_duplicate_parameters = false; 3655 bool has_duplicate_parameters = false;
3657 // Parse function body. 3656 // Parse function body.
3658 { LexicalScope lexical_scope(this, scope, isolate()); 3657 { LexicalScope lexical_scope(this, scope, isolate());
3659 top_scope_->SetScopeName(function_name); 3658 top_scope_->SetScopeName(name);
3660 3659
3661 // FormalParameterList :: 3660 // FormalParameterList ::
3662 // '(' (Identifier)*[','] ')' 3661 // '(' (Identifier)*[','] ')'
3663 Expect(Token::LPAREN, CHECK_OK); 3662 Expect(Token::LPAREN, CHECK_OK);
3664 start_pos = scanner().location().beg_pos; 3663 start_pos = scanner().location().beg_pos;
3665 Scanner::Location name_loc = Scanner::Location::invalid(); 3664 Scanner::Location name_loc = Scanner::Location::invalid();
3666 Scanner::Location dupe_loc = Scanner::Location::invalid(); 3665 Scanner::Location dupe_loc = Scanner::Location::invalid();
3667 Scanner::Location reserved_loc = Scanner::Location::invalid(); 3666 Scanner::Location reserved_loc = Scanner::Location::invalid();
3668 3667
3669 bool done = (peek() == Token::RPAREN); 3668 bool done = (peek() == Token::RPAREN);
(...skipping 29 matching lines...) Expand all
3699 Expect(Token::RPAREN, CHECK_OK); 3698 Expect(Token::RPAREN, CHECK_OK);
3700 3699
3701 Expect(Token::LBRACE, CHECK_OK); 3700 Expect(Token::LBRACE, CHECK_OK);
3702 3701
3703 // If we have a named function expression, we add a local variable 3702 // If we have a named function expression, we add a local variable
3704 // declaration to the body of the function with the name of the 3703 // declaration to the body of the function with the name of the
3705 // function and let it refer to the function itself (closure). 3704 // function and let it refer to the function itself (closure).
3706 // NOTE: We create a proxy and resolve it here so that in the 3705 // NOTE: We create a proxy and resolve it here so that in the
3707 // future we can change the AST to only refer to VariableProxies 3706 // future we can change the AST to only refer to VariableProxies
3708 // instead of Variables and Proxis as is the case now. 3707 // instead of Variables and Proxis as is the case now.
3709 if (!self_name.is_null()) { 3708 if (!function_name.is_null() && function_name->length() > 0) {
3710 Variable* fvar = top_scope_->DeclareFunctionVar(self_name); 3709 Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
3711 VariableProxy* fproxy = 3710 VariableProxy* fproxy =
3712 top_scope_->NewUnresolved(self_name, inside_with()); 3711 top_scope_->NewUnresolved(function_name, inside_with());
3713 fproxy->BindTo(fvar); 3712 fproxy->BindTo(fvar);
3714 body->Add(new(zone()) ExpressionStatement( 3713 body->Add(new(zone()) ExpressionStatement(
3715 new(zone()) Assignment(isolate(), 3714 new(zone()) Assignment(isolate(),
3716 Token::INIT_CONST, 3715 Token::INIT_CONST,
3717 fproxy, 3716 fproxy,
3718 new(zone()) ThisFunction(isolate()), 3717 new(zone()) ThisFunction(isolate()),
3719 RelocInfo::kNoPosition))); 3718 RelocInfo::kNoPosition)));
3720 } 3719 }
3721 3720
3722 // Determine if the function will be lazily compiled. The mode can only 3721 // Determine if the function will be lazily compiled. The mode can only
(...skipping 10 matching lines...) Expand all
3733 int function_block_pos = scanner().location().beg_pos; 3732 int function_block_pos = scanner().location().beg_pos;
3734 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 3733 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
3735 if (!entry.is_valid()) { 3734 if (!entry.is_valid()) {
3736 // There is no preparser data for the function, we will not lazily 3735 // There is no preparser data for the function, we will not lazily
3737 // compile after all. 3736 // compile after all.
3738 is_lazily_compiled = false; 3737 is_lazily_compiled = false;
3739 } else { 3738 } else {
3740 end_pos = entry.end_pos(); 3739 end_pos = entry.end_pos();
3741 if (end_pos <= function_block_pos) { 3740 if (end_pos <= function_block_pos) {
3742 // End position greater than end of stream is safe, and hard to check. 3741 // End position greater than end of stream is safe, and hard to check.
3743 ReportInvalidPreparseData(function_name, CHECK_OK); 3742 ReportInvalidPreparseData(name, CHECK_OK);
3744 } 3743 }
3745 isolate()->counters()->total_preparse_skipped()->Increment( 3744 isolate()->counters()->total_preparse_skipped()->Increment(
3746 end_pos - function_block_pos); 3745 end_pos - function_block_pos);
3747 // Seek to position just before terminal '}'. 3746 // Seek to position just before terminal '}'.
3748 scanner().SeekForward(end_pos - 1); 3747 scanner().SeekForward(end_pos - 1);
3749 materialized_literal_count = entry.literal_count(); 3748 materialized_literal_count = entry.literal_count();
3750 expected_property_count = entry.property_count(); 3749 expected_property_count = entry.property_count();
3751 if (entry.strict_mode()) top_scope_->EnableStrictMode(); 3750 if (entry.strict_mode()) top_scope_->EnableStrictMode();
3752 only_simple_this_property_assignments = false; 3751 only_simple_this_property_assignments = false;
3753 this_property_assignments = isolate()->factory()->empty_fixed_array(); 3752 this_property_assignments = isolate()->factory()->empty_fixed_array();
3754 Expect(Token::RBRACE, CHECK_OK); 3753 Expect(Token::RBRACE, CHECK_OK);
3755 } 3754 }
3756 } 3755 }
3757 3756
3758 if (!is_lazily_compiled) { 3757 if (!is_lazily_compiled) {
3759 ParseSourceElements(body, Token::RBRACE, CHECK_OK); 3758 ParseSourceElements(body, Token::RBRACE, CHECK_OK);
3760 3759
3761 materialized_literal_count = lexical_scope.materialized_literal_count(); 3760 materialized_literal_count = lexical_scope.materialized_literal_count();
3762 expected_property_count = lexical_scope.expected_property_count(); 3761 expected_property_count = lexical_scope.expected_property_count();
3763 only_simple_this_property_assignments = 3762 only_simple_this_property_assignments =
3764 lexical_scope.only_simple_this_property_assignments(); 3763 lexical_scope.only_simple_this_property_assignments();
3765 this_property_assignments = lexical_scope.this_property_assignments(); 3764 this_property_assignments = lexical_scope.this_property_assignments();
3766 3765
3767 Expect(Token::RBRACE, CHECK_OK); 3766 Expect(Token::RBRACE, CHECK_OK);
3768 end_pos = scanner().location().end_pos; 3767 end_pos = scanner().location().end_pos;
3769 } 3768 }
3770 3769
3771 // Validate strict mode. 3770 // Validate strict mode.
3772 if (top_scope_->is_strict_mode()) { 3771 if (top_scope_->is_strict_mode()) {
3773 if (IsEvalOrArguments(function_name)) { 3772 if (IsEvalOrArguments(name)) {
3774 int position = function_token_position != RelocInfo::kNoPosition 3773 int position = function_token_position != RelocInfo::kNoPosition
3775 ? function_token_position 3774 ? function_token_position
3776 : (start_pos > 0 ? start_pos - 1 : start_pos); 3775 : (start_pos > 0 ? start_pos - 1 : start_pos);
3777 Scanner::Location location = Scanner::Location(position, start_pos); 3776 Scanner::Location location = Scanner::Location(position, start_pos);
3778 ReportMessageAt(location, 3777 ReportMessageAt(location,
3779 "strict_function_name", Vector<const char*>::empty()); 3778 "strict_function_name", Vector<const char*>::empty());
3780 *ok = false; 3779 *ok = false;
3781 return NULL; 3780 return NULL;
3782 } 3781 }
3783 if (name_loc.IsValid()) { 3782 if (name_loc.IsValid()) {
(...skipping 23 matching lines...) Expand all
3807 Vector<const char*>::empty()); 3806 Vector<const char*>::empty());
3808 *ok = false; 3807 *ok = false;
3809 return NULL; 3808 return NULL;
3810 } 3809 }
3811 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); 3810 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3812 } 3811 }
3813 } 3812 }
3814 3813
3815 FunctionLiteral* function_literal = 3814 FunctionLiteral* function_literal =
3816 new(zone()) FunctionLiteral(isolate(), 3815 new(zone()) FunctionLiteral(isolate(),
3817 function_name, 3816 name,
3818 scope, 3817 scope,
3819 body, 3818 body,
3820 materialized_literal_count, 3819 materialized_literal_count,
3821 expected_property_count, 3820 expected_property_count,
3822 only_simple_this_property_assignments, 3821 only_simple_this_property_assignments,
3823 this_property_assignments, 3822 this_property_assignments,
3824 num_parameters, 3823 num_parameters,
3825 start_pos, 3824 start_pos,
3826 end_pos, 3825 end_pos,
3827 type == EXPRESSION, 3826 (function_name->length() > 0),
3828 has_duplicate_parameters); 3827 has_duplicate_parameters);
3829 function_literal->set_function_token_position(function_token_position); 3828 function_literal->set_function_token_position(function_token_position);
3830 3829
3831 if (fni_ != NULL && !has_name) fni_->AddFunction(function_literal); 3830 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
3832 return function_literal; 3831 return function_literal;
3833 } 3832 }
3834 3833
3835 3834
3836 Expression* Parser::ParseV8Intrinsic(bool* ok) { 3835 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3837 // CallRuntime :: 3836 // CallRuntime ::
3838 // '%' Identifier Arguments 3837 // '%' Identifier Arguments
3839 3838
3840 Expect(Token::MOD, CHECK_OK); 3839 Expect(Token::MOD, CHECK_OK);
3841 Handle<String> name = ParseIdentifier(CHECK_OK); 3840 Handle<String> name = ParseIdentifier(CHECK_OK);
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after
5122 info->is_global(), 5121 info->is_global(),
5123 info->StrictMode()); 5122 info->StrictMode());
5124 } 5123 }
5125 } 5124 }
5126 5125
5127 info->SetFunction(result); 5126 info->SetFunction(result);
5128 return (result != NULL); 5127 return (result != NULL);
5129 } 5128 }
5130 5129
5131 } } // namespace v8::internal 5130 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698