OLD | NEW |
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 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 scope = Scope::DeserializeScopeChain(info, scope); | 724 scope = Scope::DeserializeScopeChain(info, scope); |
725 } | 725 } |
726 LexicalScope lexical_scope(this, scope, isolate()); | 726 LexicalScope lexical_scope(this, scope, isolate()); |
727 | 727 |
728 if (shared_info->strict_mode()) { | 728 if (shared_info->strict_mode()) { |
729 top_scope_->EnableStrictMode(); | 729 top_scope_->EnableStrictMode(); |
730 } | 730 } |
731 | 731 |
732 FunctionLiteralType type = | 732 FunctionLiteralType type = |
733 shared_info->is_expression() ? EXPRESSION : DECLARATION; | 733 shared_info->is_expression() ? EXPRESSION : DECLARATION; |
| 734 Handle<String> function_name = |
| 735 shared_info->is_anonymous() ? Handle<String>::null() : name; |
734 bool ok = true; | 736 bool ok = true; |
735 result = ParseFunctionLiteral(name, | 737 result = ParseFunctionLiteral(function_name, |
736 false, // Strict mode name already checked. | 738 false, // Strict mode name already checked. |
737 RelocInfo::kNoPosition, type, &ok); | 739 RelocInfo::kNoPosition, |
| 740 type, |
| 741 &ok); |
738 // Make sure the results agree. | 742 // Make sure the results agree. |
739 ASSERT(ok == (result != NULL)); | 743 ASSERT(ok == (result != NULL)); |
740 } | 744 } |
741 | 745 |
742 // Make sure the target stack is empty. | 746 // Make sure the target stack is empty. |
743 ASSERT(target_stack_ == NULL); | 747 ASSERT(target_stack_ == NULL); |
744 | 748 |
745 // If there was a stack overflow we have to get rid of AST and it is | 749 // If there was a stack overflow we have to get rid of AST and it is |
746 // not safe to do before scope has been deleted. | 750 // not safe to do before scope has been deleted. |
747 if (result == NULL) { | 751 if (result == NULL) { |
(...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2835 Expression* result = NULL; | 2839 Expression* result = NULL; |
2836 if (peek() == Token::FUNCTION) { | 2840 if (peek() == Token::FUNCTION) { |
2837 Expect(Token::FUNCTION, CHECK_OK); | 2841 Expect(Token::FUNCTION, CHECK_OK); |
2838 int function_token_position = scanner().location().beg_pos; | 2842 int function_token_position = scanner().location().beg_pos; |
2839 Handle<String> name; | 2843 Handle<String> name; |
2840 bool is_strict_reserved_name = false; | 2844 bool is_strict_reserved_name = false; |
2841 if (peek_any_identifier()) { | 2845 if (peek_any_identifier()) { |
2842 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 2846 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
2843 CHECK_OK); | 2847 CHECK_OK); |
2844 } | 2848 } |
2845 result = ParseFunctionLiteral(name, is_strict_reserved_name, | 2849 result = ParseFunctionLiteral(name, |
2846 function_token_position, NESTED, CHECK_OK); | 2850 is_strict_reserved_name, |
| 2851 function_token_position, |
| 2852 EXPRESSION, |
| 2853 CHECK_OK); |
2847 } else { | 2854 } else { |
2848 result = ParsePrimaryExpression(CHECK_OK); | 2855 result = ParsePrimaryExpression(CHECK_OK); |
2849 } | 2856 } |
2850 | 2857 |
2851 while (true) { | 2858 while (true) { |
2852 switch (peek()) { | 2859 switch (peek()) { |
2853 case Token::LBRACK: { | 2860 case Token::LBRACK: { |
2854 Consume(Token::LBRACK); | 2861 Consume(Token::LBRACK); |
2855 int pos = scanner().location().beg_pos; | 2862 int pos = scanner().location().beg_pos; |
2856 Expression* index = ParseExpression(true, CHECK_OK); | 2863 Expression* index = ParseExpression(true, CHECK_OK); |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3405 Handle<String> name; | 3412 Handle<String> name; |
3406 if (is_keyword) { | 3413 if (is_keyword) { |
3407 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); | 3414 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); |
3408 } else { | 3415 } else { |
3409 name = GetSymbol(CHECK_OK); | 3416 name = GetSymbol(CHECK_OK); |
3410 } | 3417 } |
3411 FunctionLiteral* value = | 3418 FunctionLiteral* value = |
3412 ParseFunctionLiteral(name, | 3419 ParseFunctionLiteral(name, |
3413 false, // reserved words are allowed here | 3420 false, // reserved words are allowed here |
3414 RelocInfo::kNoPosition, | 3421 RelocInfo::kNoPosition, |
3415 DECLARATION, | 3422 EXPRESSION, |
3416 CHECK_OK); | 3423 CHECK_OK); |
3417 // Allow any number of parameters for compatiabilty with JSC. | 3424 // Allow any number of parameters for compatiabilty with JSC. |
3418 // Specification only allows zero parameters for get and one for set. | 3425 // Specification only allows zero parameters for get and one for set. |
3419 ObjectLiteral::Property* property = | 3426 ObjectLiteral::Property* property = |
3420 new(zone()) ObjectLiteral::Property(is_getter, value); | 3427 new(zone()) ObjectLiteral::Property(is_getter, value); |
3421 return property; | 3428 return property; |
3422 } else { | 3429 } else { |
3423 ReportUnexpectedToken(next); | 3430 ReportUnexpectedToken(next); |
3424 *ok = false; | 3431 *ok = false; |
3425 return NULL; | 3432 return NULL; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3612 return NULL; | 3619 return NULL; |
3613 } | 3620 } |
3614 done = (peek() == Token::RPAREN); | 3621 done = (peek() == Token::RPAREN); |
3615 if (!done) Expect(Token::COMMA, CHECK_OK); | 3622 if (!done) Expect(Token::COMMA, CHECK_OK); |
3616 } | 3623 } |
3617 Expect(Token::RPAREN, CHECK_OK); | 3624 Expect(Token::RPAREN, CHECK_OK); |
3618 return result; | 3625 return result; |
3619 } | 3626 } |
3620 | 3627 |
3621 | 3628 |
3622 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, | 3629 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
3623 bool name_is_strict_reserved, | 3630 bool name_is_strict_reserved, |
3624 int function_token_position, | 3631 int function_token_position, |
3625 FunctionLiteralType type, | 3632 FunctionLiteralType type, |
3626 bool* ok) { | 3633 bool* ok) { |
3627 // Function :: | 3634 // Function :: |
3628 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3635 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
3629 bool is_named = !var_name.is_null(); | |
3630 | 3636 |
3631 // The name associated with this function. If it's a function expression, | 3637 // Anonymous functions were passed either the empty symbol or a null |
3632 // this is the actual function name, otherwise this is the name of the | 3638 // handle as the function name. Remember if we were passed a non-empty |
3633 // variable declared and initialized with the function (expression). In | 3639 // handle to decide whether to invoke function name inference. |
3634 // that case, we don't have a function name (it's empty). | 3640 bool should_infer_name = function_name.is_null(); |
3635 Handle<String> name = | 3641 |
3636 is_named ? var_name : isolate()->factory()->empty_symbol(); | 3642 // We want a non-null handle as the function name. |
3637 // The function name, if any. | 3643 if (should_infer_name) { |
3638 Handle<String> function_name = isolate()->factory()->empty_symbol(); | 3644 function_name = isolate()->factory()->empty_symbol(); |
3639 if (is_named && (type == EXPRESSION || type == NESTED)) { | |
3640 function_name = name; | |
3641 } | 3645 } |
3642 | 3646 |
3643 int num_parameters = 0; | 3647 int num_parameters = 0; |
3644 // Function declarations are hoisted. | 3648 // Function declarations are hoisted. |
3645 Scope* scope = (type == DECLARATION) | 3649 Scope* scope = (type == DECLARATION) |
3646 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) | 3650 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) |
3647 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3651 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
3648 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); | 3652 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
3649 int materialized_literal_count; | 3653 int materialized_literal_count; |
3650 int expected_property_count; | 3654 int expected_property_count; |
3651 int start_pos; | 3655 int start_pos; |
3652 int end_pos; | 3656 int end_pos; |
3653 bool only_simple_this_property_assignments; | 3657 bool only_simple_this_property_assignments; |
3654 Handle<FixedArray> this_property_assignments; | 3658 Handle<FixedArray> this_property_assignments; |
3655 bool has_duplicate_parameters = false; | 3659 bool has_duplicate_parameters = false; |
3656 // Parse function body. | 3660 // Parse function body. |
3657 { LexicalScope lexical_scope(this, scope, isolate()); | 3661 { LexicalScope lexical_scope(this, scope, isolate()); |
3658 top_scope_->SetScopeName(name); | 3662 top_scope_->SetScopeName(function_name); |
3659 | 3663 |
3660 // FormalParameterList :: | 3664 // FormalParameterList :: |
3661 // '(' (Identifier)*[','] ')' | 3665 // '(' (Identifier)*[','] ')' |
3662 Expect(Token::LPAREN, CHECK_OK); | 3666 Expect(Token::LPAREN, CHECK_OK); |
3663 start_pos = scanner().location().beg_pos; | 3667 start_pos = scanner().location().beg_pos; |
3664 Scanner::Location name_loc = Scanner::Location::invalid(); | 3668 Scanner::Location name_loc = Scanner::Location::invalid(); |
3665 Scanner::Location dupe_loc = Scanner::Location::invalid(); | 3669 Scanner::Location dupe_loc = Scanner::Location::invalid(); |
3666 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 3670 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
3667 | 3671 |
3668 bool done = (peek() == Token::RPAREN); | 3672 bool done = (peek() == Token::RPAREN); |
(...skipping 29 matching lines...) Expand all Loading... |
3698 Expect(Token::RPAREN, CHECK_OK); | 3702 Expect(Token::RPAREN, CHECK_OK); |
3699 | 3703 |
3700 Expect(Token::LBRACE, CHECK_OK); | 3704 Expect(Token::LBRACE, CHECK_OK); |
3701 | 3705 |
3702 // If we have a named function expression, we add a local variable | 3706 // If we have a named function expression, we add a local variable |
3703 // declaration to the body of the function with the name of the | 3707 // declaration to the body of the function with the name of the |
3704 // function and let it refer to the function itself (closure). | 3708 // function and let it refer to the function itself (closure). |
3705 // NOTE: We create a proxy and resolve it here so that in the | 3709 // NOTE: We create a proxy and resolve it here so that in the |
3706 // future we can change the AST to only refer to VariableProxies | 3710 // future we can change the AST to only refer to VariableProxies |
3707 // instead of Variables and Proxis as is the case now. | 3711 // instead of Variables and Proxis as is the case now. |
3708 if (!function_name.is_null() && function_name->length() > 0) { | 3712 if (type == EXPRESSION && function_name->length() > 0) { |
3709 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); | 3713 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); |
3710 VariableProxy* fproxy = | 3714 VariableProxy* fproxy = |
3711 top_scope_->NewUnresolved(function_name, inside_with()); | 3715 top_scope_->NewUnresolved(function_name, inside_with()); |
3712 fproxy->BindTo(fvar); | 3716 fproxy->BindTo(fvar); |
3713 body->Add(new(zone()) ExpressionStatement( | 3717 body->Add(new(zone()) ExpressionStatement( |
3714 new(zone()) Assignment(isolate(), | 3718 new(zone()) Assignment(isolate(), |
3715 Token::INIT_CONST, | 3719 Token::INIT_CONST, |
3716 fproxy, | 3720 fproxy, |
3717 new(zone()) ThisFunction(isolate()), | 3721 new(zone()) ThisFunction(isolate()), |
3718 RelocInfo::kNoPosition))); | 3722 RelocInfo::kNoPosition))); |
(...skipping 13 matching lines...) Expand all Loading... |
3732 int function_block_pos = scanner().location().beg_pos; | 3736 int function_block_pos = scanner().location().beg_pos; |
3733 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); | 3737 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); |
3734 if (!entry.is_valid()) { | 3738 if (!entry.is_valid()) { |
3735 // There is no preparser data for the function, we will not lazily | 3739 // There is no preparser data for the function, we will not lazily |
3736 // compile after all. | 3740 // compile after all. |
3737 is_lazily_compiled = false; | 3741 is_lazily_compiled = false; |
3738 } else { | 3742 } else { |
3739 end_pos = entry.end_pos(); | 3743 end_pos = entry.end_pos(); |
3740 if (end_pos <= function_block_pos) { | 3744 if (end_pos <= function_block_pos) { |
3741 // End position greater than end of stream is safe, and hard to check. | 3745 // End position greater than end of stream is safe, and hard to check. |
3742 ReportInvalidPreparseData(name, CHECK_OK); | 3746 ReportInvalidPreparseData(function_name, CHECK_OK); |
3743 } | 3747 } |
3744 isolate()->counters()->total_preparse_skipped()->Increment( | 3748 isolate()->counters()->total_preparse_skipped()->Increment( |
3745 end_pos - function_block_pos); | 3749 end_pos - function_block_pos); |
3746 // Seek to position just before terminal '}'. | 3750 // Seek to position just before terminal '}'. |
3747 scanner().SeekForward(end_pos - 1); | 3751 scanner().SeekForward(end_pos - 1); |
3748 materialized_literal_count = entry.literal_count(); | 3752 materialized_literal_count = entry.literal_count(); |
3749 expected_property_count = entry.property_count(); | 3753 expected_property_count = entry.property_count(); |
3750 if (entry.strict_mode()) top_scope_->EnableStrictMode(); | 3754 if (entry.strict_mode()) top_scope_->EnableStrictMode(); |
3751 only_simple_this_property_assignments = false; | 3755 only_simple_this_property_assignments = false; |
3752 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 3756 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
3753 Expect(Token::RBRACE, CHECK_OK); | 3757 Expect(Token::RBRACE, CHECK_OK); |
3754 } | 3758 } |
3755 } | 3759 } |
3756 | 3760 |
3757 if (!is_lazily_compiled) { | 3761 if (!is_lazily_compiled) { |
3758 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 3762 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
3759 | 3763 |
3760 materialized_literal_count = lexical_scope.materialized_literal_count(); | 3764 materialized_literal_count = lexical_scope.materialized_literal_count(); |
3761 expected_property_count = lexical_scope.expected_property_count(); | 3765 expected_property_count = lexical_scope.expected_property_count(); |
3762 only_simple_this_property_assignments = | 3766 only_simple_this_property_assignments = |
3763 lexical_scope.only_simple_this_property_assignments(); | 3767 lexical_scope.only_simple_this_property_assignments(); |
3764 this_property_assignments = lexical_scope.this_property_assignments(); | 3768 this_property_assignments = lexical_scope.this_property_assignments(); |
3765 | 3769 |
3766 Expect(Token::RBRACE, CHECK_OK); | 3770 Expect(Token::RBRACE, CHECK_OK); |
3767 end_pos = scanner().location().end_pos; | 3771 end_pos = scanner().location().end_pos; |
3768 } | 3772 } |
3769 | 3773 |
3770 // Validate strict mode. | 3774 // Validate strict mode. |
3771 if (top_scope_->is_strict_mode()) { | 3775 if (top_scope_->is_strict_mode()) { |
3772 if (IsEvalOrArguments(name)) { | 3776 if (IsEvalOrArguments(function_name)) { |
3773 int position = function_token_position != RelocInfo::kNoPosition | 3777 int position = function_token_position != RelocInfo::kNoPosition |
3774 ? function_token_position | 3778 ? function_token_position |
3775 : (start_pos > 0 ? start_pos - 1 : start_pos); | 3779 : (start_pos > 0 ? start_pos - 1 : start_pos); |
3776 Scanner::Location location = Scanner::Location(position, start_pos); | 3780 Scanner::Location location = Scanner::Location(position, start_pos); |
3777 ReportMessageAt(location, | 3781 ReportMessageAt(location, |
3778 "strict_function_name", Vector<const char*>::empty()); | 3782 "strict_function_name", Vector<const char*>::empty()); |
3779 *ok = false; | 3783 *ok = false; |
3780 return NULL; | 3784 return NULL; |
3781 } | 3785 } |
3782 if (name_loc.IsValid()) { | 3786 if (name_loc.IsValid()) { |
(...skipping 23 matching lines...) Expand all Loading... |
3806 Vector<const char*>::empty()); | 3810 Vector<const char*>::empty()); |
3807 *ok = false; | 3811 *ok = false; |
3808 return NULL; | 3812 return NULL; |
3809 } | 3813 } |
3810 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 3814 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); |
3811 } | 3815 } |
3812 } | 3816 } |
3813 | 3817 |
3814 FunctionLiteral* function_literal = | 3818 FunctionLiteral* function_literal = |
3815 new(zone()) FunctionLiteral(isolate(), | 3819 new(zone()) FunctionLiteral(isolate(), |
3816 name, | 3820 function_name, |
3817 scope, | 3821 scope, |
3818 body, | 3822 body, |
3819 materialized_literal_count, | 3823 materialized_literal_count, |
3820 expected_property_count, | 3824 expected_property_count, |
3821 only_simple_this_property_assignments, | 3825 only_simple_this_property_assignments, |
3822 this_property_assignments, | 3826 this_property_assignments, |
3823 num_parameters, | 3827 num_parameters, |
3824 start_pos, | 3828 start_pos, |
3825 end_pos, | 3829 end_pos, |
3826 (function_name->length() > 0), | 3830 type == EXPRESSION, |
3827 has_duplicate_parameters); | 3831 has_duplicate_parameters); |
3828 function_literal->set_function_token_position(function_token_position); | 3832 function_literal->set_function_token_position(function_token_position); |
3829 | 3833 |
3830 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3834 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
3831 return function_literal; | 3835 return function_literal; |
3832 } | 3836 } |
3833 | 3837 |
3834 | 3838 |
3835 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3839 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
3836 // CallRuntime :: | 3840 // CallRuntime :: |
3837 // '%' Identifier Arguments | 3841 // '%' Identifier Arguments |
3838 | 3842 |
3839 Expect(Token::MOD, CHECK_OK); | 3843 Expect(Token::MOD, CHECK_OK); |
3840 Handle<String> name = ParseIdentifier(CHECK_OK); | 3844 Handle<String> name = ParseIdentifier(CHECK_OK); |
(...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5121 info->is_global(), | 5125 info->is_global(), |
5122 info->StrictMode()); | 5126 info->StrictMode()); |
5123 } | 5127 } |
5124 } | 5128 } |
5125 | 5129 |
5126 info->SetFunction(result); | 5130 info->SetFunction(result); |
5127 return (result != NULL); | 5131 return (result != NULL); |
5128 } | 5132 } |
5129 | 5133 |
5130 } } // namespace v8::internal | 5134 } } // namespace v8::internal |
OLD | NEW |