OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
601 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 601 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
602 bool in_global_context) { | 602 bool in_global_context) { |
603 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 603 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
604 | 604 |
605 HistogramTimerScope timer(&Counters::parse); | 605 HistogramTimerScope timer(&Counters::parse); |
606 Counters::total_parse_size.Increment(source->length()); | 606 Counters::total_parse_size.Increment(source->length()); |
607 fni_ = new FuncNameInferrer(); | 607 fni_ = new FuncNameInferrer(); |
608 | 608 |
609 // Initialize parser state. | 609 // Initialize parser state. |
610 source->TryFlatten(); | 610 source->TryFlatten(); |
611 scanner_.Initialize(source); | 611 if (source->IsExternalTwoByteString()) { |
612 ExternalTwoByteStringUC16CharacterStream stream( | |
613 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | |
614 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); | |
615 return DoParseProgram(source, in_global_context, &zone_scope); | |
Erik Corry
2010/12/07 12:27:30
This last line is common between both branches and
Lasse Reichstein
2010/12/07 14:05:54
The current code is mandated by the destructor of
| |
616 } else { | |
617 GenericStringUC16CharacterStream stream(source, 0, source->length()); | |
618 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); | |
619 return DoParseProgram(source, in_global_context, &zone_scope); | |
620 } | |
621 } | |
622 | |
623 | |
624 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, | |
625 bool in_global_context, | |
626 ZoneScope* zone_scope) { | |
612 ASSERT(target_stack_ == NULL); | 627 ASSERT(target_stack_ == NULL); |
613 if (pre_data_ != NULL) pre_data_->Initialize(); | 628 if (pre_data_ != NULL) pre_data_->Initialize(); |
614 | 629 |
615 // Compute the parsing mode. | 630 // Compute the parsing mode. |
616 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 631 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
617 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 632 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
618 | 633 |
619 Scope::Type type = | 634 Scope::Type type = |
620 in_global_context | 635 in_global_context |
621 ? Scope::GLOBAL_SCOPE | 636 ? Scope::GLOBAL_SCOPE |
(...skipping 25 matching lines...) Expand all Loading... | |
647 } else if (stack_overflow_) { | 662 } else if (stack_overflow_) { |
648 Top::StackOverflow(); | 663 Top::StackOverflow(); |
649 } | 664 } |
650 } | 665 } |
651 | 666 |
652 // Make sure the target stack is empty. | 667 // Make sure the target stack is empty. |
653 ASSERT(target_stack_ == NULL); | 668 ASSERT(target_stack_ == NULL); |
654 | 669 |
655 // If there was a syntax error we have to get rid of the AST | 670 // If there was a syntax error we have to get rid of the AST |
656 // and it is not safe to do so before the scope has been deleted. | 671 // and it is not safe to do so before the scope has been deleted. |
657 if (result == NULL) zone_scope.DeleteOnExit(); | 672 if (result == NULL) zone_scope->DeleteOnExit(); |
658 return result; | 673 return result; |
659 } | 674 } |
660 | 675 |
661 | |
662 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { | 676 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { |
663 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 677 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
664 HistogramTimerScope timer(&Counters::parse_lazy); | 678 HistogramTimerScope timer(&Counters::parse_lazy); |
665 Handle<String> source(String::cast(script_->source())); | 679 Handle<String> source(String::cast(script_->source())); |
666 Counters::total_parse_size.Increment(source->length()); | 680 Counters::total_parse_size.Increment(source->length()); |
667 | 681 |
682 // Initialize parser state. | |
683 source->TryFlatten(); | |
684 if (source->IsExternalTwoByteString()) { | |
685 ExternalTwoByteStringUC16CharacterStream stream( | |
686 Handle<ExternalTwoByteString>::cast(source), | |
687 info->start_position(), | |
688 info->end_position()); | |
689 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | |
690 return result; | |
691 } else { | |
692 GenericStringUC16CharacterStream stream(source, | |
693 info->start_position(), | |
694 info->end_position()); | |
695 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | |
696 return result; | |
697 } | |
698 } | |
699 | |
Erik Corry
2010/12/07 12:27:30
Missing blank line
| |
700 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info, | |
701 UC16CharacterStream* source, | |
702 ZoneScope* zone_scope) { | |
703 scanner_.Initialize(source, JavaScriptScanner::kAllLiterals); | |
704 ASSERT(target_stack_ == NULL); | |
705 | |
668 Handle<String> name(String::cast(info->name())); | 706 Handle<String> name(String::cast(info->name())); |
669 fni_ = new FuncNameInferrer(); | 707 fni_ = new FuncNameInferrer(); |
670 fni_->PushEnclosingName(name); | 708 fni_->PushEnclosingName(name); |
671 | 709 |
672 // Initialize parser state. | |
673 source->TryFlatten(); | |
674 scanner_.Initialize(source, info->start_position(), info->end_position()); | |
675 ASSERT(target_stack_ == NULL); | |
676 mode_ = PARSE_EAGERLY; | 710 mode_ = PARSE_EAGERLY; |
677 | 711 |
678 // Place holder for the result. | 712 // Place holder for the result. |
679 FunctionLiteral* result = NULL; | 713 FunctionLiteral* result = NULL; |
680 | 714 |
681 { | 715 { |
682 // Parse the function literal. | 716 // Parse the function literal. |
683 Handle<String> no_name = Factory::empty_symbol(); | 717 Handle<String> no_name = Factory::empty_symbol(); |
684 Scope* scope = | 718 Scope* scope = |
685 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 719 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
(...skipping 11 matching lines...) Expand all Loading... | |
697 ASSERT(ok || stack_overflow_); | 731 ASSERT(ok || stack_overflow_); |
698 } | 732 } |
699 | 733 |
700 // Make sure the target stack is empty. | 734 // Make sure the target stack is empty. |
701 ASSERT(target_stack_ == NULL); | 735 ASSERT(target_stack_ == NULL); |
702 | 736 |
703 // If there was a stack overflow we have to get rid of AST and it is | 737 // If there was a stack overflow we have to get rid of AST and it is |
704 // not safe to do before scope has been deleted. | 738 // not safe to do before scope has been deleted. |
705 if (result == NULL) { | 739 if (result == NULL) { |
706 Top::StackOverflow(); | 740 Top::StackOverflow(); |
707 zone_scope.DeleteOnExit(); | 741 zone_scope->DeleteOnExit(); |
708 } | 742 } |
709 return result; | 743 return result; |
710 } | 744 } |
711 | 745 |
712 | 746 |
713 Handle<String> Parser::GetSymbol(bool* ok) { | 747 Handle<String> Parser::GetSymbol(bool* ok) { |
714 int symbol_id = -1; | 748 int symbol_id = -1; |
715 if (pre_data() != NULL) { | 749 if (pre_data() != NULL) { |
716 symbol_id = pre_data()->GetSymbolIdentifier(); | 750 symbol_id = pre_data()->GetSymbolIdentifier(); |
717 } | 751 } |
718 return LookupSymbol(symbol_id, scanner_.literal()); | 752 return LookupSymbol(symbol_id, scanner().literal()); |
719 } | 753 } |
720 | 754 |
721 | 755 |
722 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 756 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
723 Scanner::Location source_location = scanner_.location(); | 757 Scanner::Location source_location = scanner().location(); |
724 ReportMessageAt(source_location, type, args); | 758 ReportMessageAt(source_location, type, args); |
725 } | 759 } |
726 | 760 |
727 | 761 |
728 void Parser::ReportMessageAt(Scanner::Location source_location, | 762 void Parser::ReportMessageAt(Scanner::Location source_location, |
729 const char* type, | 763 const char* type, |
730 Vector<const char*> args) { | 764 Vector<const char*> args) { |
731 MessageLocation location(script_, | 765 MessageLocation location(script_, |
732 source_location.beg_pos, source_location.end_pos); | 766 source_location.beg_pos, source_location.end_pos); |
733 Handle<JSArray> array = Factory::NewJSArray(args.length()); | 767 Handle<JSArray> array = Factory::NewJSArray(args.length()); |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1630 } | 1664 } |
1631 | 1665 |
1632 | 1666 |
1633 Statement* Parser::ParseContinueStatement(bool* ok) { | 1667 Statement* Parser::ParseContinueStatement(bool* ok) { |
1634 // ContinueStatement :: | 1668 // ContinueStatement :: |
1635 // 'continue' Identifier? ';' | 1669 // 'continue' Identifier? ';' |
1636 | 1670 |
1637 Expect(Token::CONTINUE, CHECK_OK); | 1671 Expect(Token::CONTINUE, CHECK_OK); |
1638 Handle<String> label = Handle<String>::null(); | 1672 Handle<String> label = Handle<String>::null(); |
1639 Token::Value tok = peek(); | 1673 Token::Value tok = peek(); |
1640 if (!scanner_.has_line_terminator_before_next() && | 1674 if (!scanner().has_line_terminator_before_next() && |
1641 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1675 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
1642 label = ParseIdentifier(CHECK_OK); | 1676 label = ParseIdentifier(CHECK_OK); |
1643 } | 1677 } |
1644 IterationStatement* target = NULL; | 1678 IterationStatement* target = NULL; |
1645 target = LookupContinueTarget(label, CHECK_OK); | 1679 target = LookupContinueTarget(label, CHECK_OK); |
1646 if (target == NULL) { | 1680 if (target == NULL) { |
1647 // Illegal continue statement. To be consistent with KJS we delay | 1681 // Illegal continue statement. To be consistent with KJS we delay |
1648 // reporting of the syntax error until runtime. | 1682 // reporting of the syntax error until runtime. |
1649 Handle<String> error_type = Factory::illegal_continue_symbol(); | 1683 Handle<String> error_type = Factory::illegal_continue_symbol(); |
1650 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); | 1684 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); |
1651 Expression* throw_error = NewThrowSyntaxError(error_type, label); | 1685 Expression* throw_error = NewThrowSyntaxError(error_type, label); |
1652 return new ExpressionStatement(throw_error); | 1686 return new ExpressionStatement(throw_error); |
1653 } | 1687 } |
1654 ExpectSemicolon(CHECK_OK); | 1688 ExpectSemicolon(CHECK_OK); |
1655 return new ContinueStatement(target); | 1689 return new ContinueStatement(target); |
1656 } | 1690 } |
1657 | 1691 |
1658 | 1692 |
1659 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 1693 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
1660 // BreakStatement :: | 1694 // BreakStatement :: |
1661 // 'break' Identifier? ';' | 1695 // 'break' Identifier? ';' |
1662 | 1696 |
1663 Expect(Token::BREAK, CHECK_OK); | 1697 Expect(Token::BREAK, CHECK_OK); |
1664 Handle<String> label; | 1698 Handle<String> label; |
1665 Token::Value tok = peek(); | 1699 Token::Value tok = peek(); |
1666 if (!scanner_.has_line_terminator_before_next() && | 1700 if (!scanner().has_line_terminator_before_next() && |
1667 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1701 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
1668 label = ParseIdentifier(CHECK_OK); | 1702 label = ParseIdentifier(CHECK_OK); |
1669 } | 1703 } |
1670 // Parse labeled break statements that target themselves into | 1704 // Parse labeled break statements that target themselves into |
1671 // empty statements, e.g. 'l1: l2: l3: break l2;' | 1705 // empty statements, e.g. 'l1: l2: l3: break l2;' |
1672 if (!label.is_null() && ContainsLabel(labels, label)) { | 1706 if (!label.is_null() && ContainsLabel(labels, label)) { |
1673 return EmptyStatement(); | 1707 return EmptyStatement(); |
1674 } | 1708 } |
1675 BreakableStatement* target = NULL; | 1709 BreakableStatement* target = NULL; |
1676 target = LookupBreakTarget(label, CHECK_OK); | 1710 target = LookupBreakTarget(label, CHECK_OK); |
(...skipping 24 matching lines...) Expand all Loading... | |
1701 // function. See ECMA-262, section 12.9, page 67. | 1735 // function. See ECMA-262, section 12.9, page 67. |
1702 // | 1736 // |
1703 // To be consistent with KJS we report the syntax error at runtime. | 1737 // To be consistent with KJS we report the syntax error at runtime. |
1704 if (!top_scope_->is_function_scope()) { | 1738 if (!top_scope_->is_function_scope()) { |
1705 Handle<String> type = Factory::illegal_return_symbol(); | 1739 Handle<String> type = Factory::illegal_return_symbol(); |
1706 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); | 1740 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); |
1707 return new ExpressionStatement(throw_error); | 1741 return new ExpressionStatement(throw_error); |
1708 } | 1742 } |
1709 | 1743 |
1710 Token::Value tok = peek(); | 1744 Token::Value tok = peek(); |
1711 if (scanner_.has_line_terminator_before_next() || | 1745 if (scanner().has_line_terminator_before_next() || |
1712 tok == Token::SEMICOLON || | 1746 tok == Token::SEMICOLON || |
1713 tok == Token::RBRACE || | 1747 tok == Token::RBRACE || |
1714 tok == Token::EOS) { | 1748 tok == Token::EOS) { |
1715 ExpectSemicolon(CHECK_OK); | 1749 ExpectSemicolon(CHECK_OK); |
1716 return new ReturnStatement(GetLiteralUndefined()); | 1750 return new ReturnStatement(GetLiteralUndefined()); |
1717 } | 1751 } |
1718 | 1752 |
1719 Expression* expr = ParseExpression(true, CHECK_OK); | 1753 Expression* expr = ParseExpression(true, CHECK_OK); |
1720 ExpectSemicolon(CHECK_OK); | 1754 ExpectSemicolon(CHECK_OK); |
1721 return new ReturnStatement(expr); | 1755 return new ReturnStatement(expr); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1833 return statement; | 1867 return statement; |
1834 } | 1868 } |
1835 | 1869 |
1836 | 1870 |
1837 Statement* Parser::ParseThrowStatement(bool* ok) { | 1871 Statement* Parser::ParseThrowStatement(bool* ok) { |
1838 // ThrowStatement :: | 1872 // ThrowStatement :: |
1839 // 'throw' Expression ';' | 1873 // 'throw' Expression ';' |
1840 | 1874 |
1841 Expect(Token::THROW, CHECK_OK); | 1875 Expect(Token::THROW, CHECK_OK); |
1842 int pos = scanner().location().beg_pos; | 1876 int pos = scanner().location().beg_pos; |
1843 if (scanner_.has_line_terminator_before_next()) { | 1877 if (scanner().has_line_terminator_before_next()) { |
1844 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 1878 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
1845 *ok = false; | 1879 *ok = false; |
1846 return NULL; | 1880 return NULL; |
1847 } | 1881 } |
1848 Expression* exception = ParseExpression(true, CHECK_OK); | 1882 Expression* exception = ParseExpression(true, CHECK_OK); |
1849 ExpectSemicolon(CHECK_OK); | 1883 ExpectSemicolon(CHECK_OK); |
1850 | 1884 |
1851 return new ExpressionStatement(new Throw(exception, pos)); | 1885 return new ExpressionStatement(new Throw(exception, pos)); |
1852 } | 1886 } |
1853 | 1887 |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2394 return ParsePostfixExpression(ok); | 2428 return ParsePostfixExpression(ok); |
2395 } | 2429 } |
2396 } | 2430 } |
2397 | 2431 |
2398 | 2432 |
2399 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2433 Expression* Parser::ParsePostfixExpression(bool* ok) { |
2400 // PostfixExpression :: | 2434 // PostfixExpression :: |
2401 // LeftHandSideExpression ('++' | '--')? | 2435 // LeftHandSideExpression ('++' | '--')? |
2402 | 2436 |
2403 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 2437 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
2404 if (!scanner_.has_line_terminator_before_next() && Token::IsCountOp(peek())) { | 2438 if (!scanner().has_line_terminator_before_next() |
2439 && Token::IsCountOp(peek())) { | |
Erik Corry
2010/12/07 12:27:30
Everywhere else in this file seems to have the &&
Lasse Reichstein
2010/12/07 14:05:54
I prefer having them on the second line, but let's
Vitaly Repeshko
2010/12/07 14:15:50
Please don't :)
While http://google-styleguide.go
| |
2405 // Signal a reference error if the expression is an invalid | 2440 // Signal a reference error if the expression is an invalid |
2406 // left-hand side expression. We could report this as a syntax | 2441 // left-hand side expression. We could report this as a syntax |
2407 // error here but for compatibility with JSC we choose to report the | 2442 // error here but for compatibility with JSC we choose to report the |
2408 // error at runtime. | 2443 // error at runtime. |
2409 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2444 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2410 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); | 2445 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); |
2411 expression = NewThrowReferenceError(type); | 2446 expression = NewThrowReferenceError(type); |
2412 } | 2447 } |
2413 Token::Value next = Next(); | 2448 Token::Value next = Next(); |
2414 int position = scanner().location().beg_pos; | 2449 int position = scanner().location().beg_pos; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2663 case Token::IDENTIFIER: { | 2698 case Token::IDENTIFIER: { |
2664 Handle<String> name = ParseIdentifier(CHECK_OK); | 2699 Handle<String> name = ParseIdentifier(CHECK_OK); |
2665 if (fni_ != NULL) fni_->PushVariableName(name); | 2700 if (fni_ != NULL) fni_->PushVariableName(name); |
2666 result = top_scope_->NewUnresolved(name, inside_with()); | 2701 result = top_scope_->NewUnresolved(name, inside_with()); |
2667 break; | 2702 break; |
2668 } | 2703 } |
2669 | 2704 |
2670 case Token::NUMBER: { | 2705 case Token::NUMBER: { |
2671 Consume(Token::NUMBER); | 2706 Consume(Token::NUMBER); |
2672 double value = | 2707 double value = |
2673 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 2708 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); |
2674 result = NewNumberLiteral(value); | 2709 result = NewNumberLiteral(value); |
2675 break; | 2710 break; |
2676 } | 2711 } |
2677 | 2712 |
2678 case Token::STRING: { | 2713 case Token::STRING: { |
2679 Consume(Token::STRING); | 2714 Consume(Token::STRING); |
2680 Handle<String> symbol = GetSymbol(CHECK_OK); | 2715 Handle<String> symbol = GetSymbol(CHECK_OK); |
2681 result = new Literal(symbol); | 2716 result = new Literal(symbol); |
2682 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 2717 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
2683 break; | 2718 break; |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3013 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3048 if (!string.is_null() && string->AsArrayIndex(&index)) { |
3014 key = NewNumberLiteral(index); | 3049 key = NewNumberLiteral(index); |
3015 break; | 3050 break; |
3016 } | 3051 } |
3017 key = new Literal(string); | 3052 key = new Literal(string); |
3018 break; | 3053 break; |
3019 } | 3054 } |
3020 case Token::NUMBER: { | 3055 case Token::NUMBER: { |
3021 Consume(Token::NUMBER); | 3056 Consume(Token::NUMBER); |
3022 double value = | 3057 double value = |
3023 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 3058 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); |
3024 key = NewNumberLiteral(value); | 3059 key = NewNumberLiteral(value); |
3025 break; | 3060 break; |
3026 } | 3061 } |
3027 default: | 3062 default: |
3028 if (Token::IsKeyword(next)) { | 3063 if (Token::IsKeyword(next)) { |
3029 Consume(next); | 3064 Consume(next); |
3030 Handle<String> string = GetSymbol(CHECK_OK); | 3065 Handle<String> string = GetSymbol(CHECK_OK); |
3031 key = new Literal(string); | 3066 key = new Literal(string); |
3032 } else { | 3067 } else { |
3033 // Unexpected token. | 3068 // Unexpected token. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3074 return new ObjectLiteral(constant_properties, | 3109 return new ObjectLiteral(constant_properties, |
3075 properties, | 3110 properties, |
3076 literal_index, | 3111 literal_index, |
3077 is_simple, | 3112 is_simple, |
3078 fast_elements, | 3113 fast_elements, |
3079 depth); | 3114 depth); |
3080 } | 3115 } |
3081 | 3116 |
3082 | 3117 |
3083 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3118 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
3084 if (!scanner_.ScanRegExpPattern(seen_equal)) { | 3119 if (!scanner().ScanRegExpPattern(seen_equal)) { |
3085 Next(); | 3120 Next(); |
3086 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3121 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
3087 *ok = false; | 3122 *ok = false; |
3088 return NULL; | 3123 return NULL; |
3089 } | 3124 } |
3090 | 3125 |
3091 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3126 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
3092 | 3127 |
3093 Handle<String> js_pattern = | 3128 Handle<String> js_pattern = |
3094 Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); | 3129 Factory::NewStringFromUtf8(scanner().next_literal(), TENURED); |
3095 scanner_.ScanRegExpFlags(); | 3130 scanner().ScanRegExpFlags(); |
3096 Handle<String> js_flags = | 3131 Handle<String> js_flags = |
3097 Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); | 3132 Factory::NewStringFromUtf8(scanner().next_literal(), TENURED); |
3098 Next(); | 3133 Next(); |
3099 | 3134 |
3100 return new RegExpLiteral(js_pattern, js_flags, literal_index); | 3135 return new RegExpLiteral(js_pattern, js_flags, literal_index); |
3101 } | 3136 } |
3102 | 3137 |
3103 | 3138 |
3104 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3139 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
3105 // Arguments :: | 3140 // Arguments :: |
3106 // '(' (AssignmentExpression)*[','] ')' | 3141 // '(' (AssignmentExpression)*[','] ')' |
3107 | 3142 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3143 { Scope* scope = | 3178 { Scope* scope = |
3144 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3179 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
3145 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3180 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
3146 scope); | 3181 scope); |
3147 TemporaryScope temp_scope(&this->temp_scope_); | 3182 TemporaryScope temp_scope(&this->temp_scope_); |
3148 top_scope_->SetScopeName(name); | 3183 top_scope_->SetScopeName(name); |
3149 | 3184 |
3150 // FormalParameterList :: | 3185 // FormalParameterList :: |
3151 // '(' (Identifier)*[','] ')' | 3186 // '(' (Identifier)*[','] ')' |
3152 Expect(Token::LPAREN, CHECK_OK); | 3187 Expect(Token::LPAREN, CHECK_OK); |
3153 int start_pos = scanner_.location().beg_pos; | 3188 int start_pos = scanner().location().beg_pos; |
3154 bool done = (peek() == Token::RPAREN); | 3189 bool done = (peek() == Token::RPAREN); |
3155 while (!done) { | 3190 while (!done) { |
3156 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3191 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
3157 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, | 3192 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, |
3158 Variable::VAR)); | 3193 Variable::VAR)); |
3159 num_parameters++; | 3194 num_parameters++; |
3160 done = (peek() == Token::RPAREN); | 3195 done = (peek() == Token::RPAREN); |
3161 if (!done) Expect(Token::COMMA, CHECK_OK); | 3196 if (!done) Expect(Token::COMMA, CHECK_OK); |
3162 } | 3197 } |
3163 Expect(Token::RPAREN, CHECK_OK); | 3198 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 16 matching lines...) Expand all Loading... | |
3180 new Assignment(Token::INIT_CONST, fproxy, | 3215 new Assignment(Token::INIT_CONST, fproxy, |
3181 new ThisFunction(), | 3216 new ThisFunction(), |
3182 RelocInfo::kNoPosition))); | 3217 RelocInfo::kNoPosition))); |
3183 } | 3218 } |
3184 | 3219 |
3185 // Determine if the function will be lazily compiled. The mode can | 3220 // Determine if the function will be lazily compiled. The mode can |
3186 // only be PARSE_LAZILY if the --lazy flag is true. | 3221 // only be PARSE_LAZILY if the --lazy flag is true. |
3187 bool is_lazily_compiled = | 3222 bool is_lazily_compiled = |
3188 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); | 3223 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); |
3189 | 3224 |
3190 int function_block_pos = scanner_.location().beg_pos; | 3225 int function_block_pos = scanner().location().beg_pos; |
3191 int materialized_literal_count; | 3226 int materialized_literal_count; |
3192 int expected_property_count; | 3227 int expected_property_count; |
3193 int end_pos; | 3228 int end_pos; |
3194 bool only_simple_this_property_assignments; | 3229 bool only_simple_this_property_assignments; |
3195 Handle<FixedArray> this_property_assignments; | 3230 Handle<FixedArray> this_property_assignments; |
3196 if (is_lazily_compiled && pre_data() != NULL) { | 3231 if (is_lazily_compiled && pre_data() != NULL) { |
3197 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); | 3232 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); |
3198 if (!entry.is_valid()) { | 3233 if (!entry.is_valid()) { |
3199 ReportInvalidPreparseData(name, CHECK_OK); | 3234 ReportInvalidPreparseData(name, CHECK_OK); |
3200 } | 3235 } |
3201 end_pos = entry.end_pos(); | 3236 end_pos = entry.end_pos(); |
3202 if (end_pos <= function_block_pos) { | 3237 if (end_pos <= function_block_pos) { |
3203 // End position greater than end of stream is safe, and hard to check. | 3238 // End position greater than end of stream is safe, and hard to check. |
3204 ReportInvalidPreparseData(name, CHECK_OK); | 3239 ReportInvalidPreparseData(name, CHECK_OK); |
3205 } | 3240 } |
3206 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); | 3241 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); |
3207 scanner_.SeekForward(end_pos); | 3242 // Seek to position just before terminal '}'. |
3243 scanner().SeekForward(end_pos - 1); | |
3208 materialized_literal_count = entry.literal_count(); | 3244 materialized_literal_count = entry.literal_count(); |
3209 expected_property_count = entry.property_count(); | 3245 expected_property_count = entry.property_count(); |
3210 only_simple_this_property_assignments = false; | 3246 only_simple_this_property_assignments = false; |
3211 this_property_assignments = Factory::empty_fixed_array(); | 3247 this_property_assignments = Factory::empty_fixed_array(); |
3212 Expect(Token::RBRACE, CHECK_OK); | 3248 Expect(Token::RBRACE, CHECK_OK); |
3213 } else { | 3249 } else { |
3214 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 3250 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
3215 | 3251 |
3216 materialized_literal_count = temp_scope.materialized_literal_count(); | 3252 materialized_literal_count = temp_scope.materialized_literal_count(); |
3217 expected_property_count = temp_scope.expected_property_count(); | 3253 expected_property_count = temp_scope.expected_property_count(); |
3218 only_simple_this_property_assignments = | 3254 only_simple_this_property_assignments = |
3219 temp_scope.only_simple_this_property_assignments(); | 3255 temp_scope.only_simple_this_property_assignments(); |
3220 this_property_assignments = temp_scope.this_property_assignments(); | 3256 this_property_assignments = temp_scope.this_property_assignments(); |
3221 | 3257 |
3222 Expect(Token::RBRACE, CHECK_OK); | 3258 Expect(Token::RBRACE, CHECK_OK); |
3223 end_pos = scanner_.location().end_pos; | 3259 end_pos = scanner().location().end_pos; |
3224 } | 3260 } |
3225 | 3261 |
3226 FunctionLiteral* function_literal = | 3262 FunctionLiteral* function_literal = |
3227 new FunctionLiteral(name, | 3263 new FunctionLiteral(name, |
3228 top_scope_, | 3264 top_scope_, |
3229 body, | 3265 body, |
3230 materialized_literal_count, | 3266 materialized_literal_count, |
3231 expected_property_count, | 3267 expected_property_count, |
3232 only_simple_this_property_assignments, | 3268 only_simple_this_property_assignments, |
3233 this_property_assignments, | 3269 this_property_assignments, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3317 | 3353 |
3318 | 3354 |
3319 void Parser::ExpectSemicolon(bool* ok) { | 3355 void Parser::ExpectSemicolon(bool* ok) { |
3320 // Check for automatic semicolon insertion according to | 3356 // Check for automatic semicolon insertion according to |
3321 // the rules given in ECMA-262, section 7.9, page 21. | 3357 // the rules given in ECMA-262, section 7.9, page 21. |
3322 Token::Value tok = peek(); | 3358 Token::Value tok = peek(); |
3323 if (tok == Token::SEMICOLON) { | 3359 if (tok == Token::SEMICOLON) { |
3324 Next(); | 3360 Next(); |
3325 return; | 3361 return; |
3326 } | 3362 } |
3327 if (scanner_.has_line_terminator_before_next() || | 3363 if (scanner().has_line_terminator_before_next() || |
3328 tok == Token::RBRACE || | 3364 tok == Token::RBRACE || |
3329 tok == Token::EOS) { | 3365 tok == Token::EOS) { |
3330 return; | 3366 return; |
3331 } | 3367 } |
3332 Expect(Token::SEMICOLON, ok); | 3368 Expect(Token::SEMICOLON, ok); |
3333 } | 3369 } |
3334 | 3370 |
3335 | 3371 |
3336 Literal* Parser::GetLiteralUndefined() { | 3372 Literal* Parser::GetLiteralUndefined() { |
3337 return new Literal(Factory::undefined_value()); | 3373 return new Literal(Factory::undefined_value()); |
(...skipping 30 matching lines...) Expand all Loading... | |
3368 | 3404 |
3369 // This function reads an identifier and determines whether or not it | 3405 // This function reads an identifier and determines whether or not it |
3370 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 3406 // is 'get' or 'set'. The reason for not using ParseIdentifier and |
3371 // checking on the output is that this involves heap allocation which | 3407 // checking on the output is that this involves heap allocation which |
3372 // we can't do during preparsing. | 3408 // we can't do during preparsing. |
3373 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, | 3409 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, |
3374 bool* is_set, | 3410 bool* is_set, |
3375 bool* ok) { | 3411 bool* ok) { |
3376 Expect(Token::IDENTIFIER, ok); | 3412 Expect(Token::IDENTIFIER, ok); |
3377 if (!*ok) return Handle<String>(); | 3413 if (!*ok) return Handle<String>(); |
3378 if (scanner_.literal_length() == 3) { | 3414 if (scanner().literal_length() == 3) { |
3379 const char* token = scanner_.literal_string(); | 3415 const char* token = scanner().literal_string(); |
3380 *is_get = strcmp(token, "get") == 0; | 3416 *is_get = strcmp(token, "get") == 0; |
3381 *is_set = !*is_get && strcmp(token, "set") == 0; | 3417 *is_set = !*is_get && strcmp(token, "set") == 0; |
3382 } | 3418 } |
3383 return GetSymbol(ok); | 3419 return GetSymbol(ok); |
3384 } | 3420 } |
3385 | 3421 |
3386 | 3422 |
3387 // ---------------------------------------------------------------------------- | 3423 // ---------------------------------------------------------------------------- |
3388 // Parser support | 3424 // Parser support |
3389 | 3425 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3488 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); | 3524 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); |
3489 args->Add(new Literal(type)); | 3525 args->Add(new Literal(type)); |
3490 args->Add(new Literal(array)); | 3526 args->Add(new Literal(array)); |
3491 return new Throw(new CallRuntime(constructor, NULL, args), | 3527 return new Throw(new CallRuntime(constructor, NULL, args), |
3492 scanner().location().beg_pos); | 3528 scanner().location().beg_pos); |
3493 } | 3529 } |
3494 | 3530 |
3495 // ---------------------------------------------------------------------------- | 3531 // ---------------------------------------------------------------------------- |
3496 // JSON | 3532 // JSON |
3497 | 3533 |
3498 Handle<Object> JsonParser::ParseJson(Handle<String> source) { | 3534 Handle<Object> JsonParser::ParseJson(Handle<String> script, |
3499 source->TryFlatten(); | 3535 UC16CharacterStream* source) { |
3500 scanner_.Initialize(source); | 3536 scanner_.Initialize(source); |
3501 stack_overflow_ = false; | 3537 stack_overflow_ = false; |
3502 Handle<Object> result = ParseJsonValue(); | 3538 Handle<Object> result = ParseJsonValue(); |
3503 if (result.is_null() || scanner_.Next() != Token::EOS) { | 3539 if (result.is_null() || scanner_.Next() != Token::EOS) { |
3504 if (stack_overflow_) { | 3540 if (stack_overflow_) { |
3505 // Scanner failed. | 3541 // Scanner failed. |
3506 Top::StackOverflow(); | 3542 Top::StackOverflow(); |
3507 } else { | 3543 } else { |
3508 // Parse failed. Scanner's current token is the unexpected token. | 3544 // Parse failed. Scanner's current token is the unexpected token. |
3509 Token::Value token = scanner_.current_token(); | 3545 Token::Value token = scanner_.current_token(); |
(...skipping 15 matching lines...) Expand all Loading... | |
3525 message = "unexpected_token_identifier"; | 3561 message = "unexpected_token_identifier"; |
3526 break; | 3562 break; |
3527 default: | 3563 default: |
3528 message = "unexpected_token"; | 3564 message = "unexpected_token"; |
3529 name_opt = Token::String(token); | 3565 name_opt = Token::String(token); |
3530 ASSERT(name_opt != NULL); | 3566 ASSERT(name_opt != NULL); |
3531 break; | 3567 break; |
3532 } | 3568 } |
3533 | 3569 |
3534 Scanner::Location source_location = scanner_.location(); | 3570 Scanner::Location source_location = scanner_.location(); |
3535 MessageLocation location(Factory::NewScript(source), | 3571 MessageLocation location(Factory::NewScript(script), |
3536 source_location.beg_pos, | 3572 source_location.beg_pos, |
3537 source_location.end_pos); | 3573 source_location.end_pos); |
3538 int argc = (name_opt == NULL) ? 0 : 1; | 3574 int argc = (name_opt == NULL) ? 0 : 1; |
3539 Handle<JSArray> array = Factory::NewJSArray(argc); | 3575 Handle<JSArray> array = Factory::NewJSArray(argc); |
3540 if (name_opt != NULL) { | 3576 if (name_opt != NULL) { |
3541 SetElement(array, | 3577 SetElement(array, |
3542 0, | 3578 0, |
3543 Factory::NewStringFromUtf8(CStrVector(name_opt))); | 3579 Factory::NewStringFromUtf8(CStrVector(name_opt))); |
3544 } | 3580 } |
3545 Handle<Object> result = Factory::NewSyntaxError(message, array); | 3581 Handle<Object> result = Factory::NewSyntaxError(message, array); |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4540 input = *data; | 4576 input = *data; |
4541 result = (result << 7) | (input & 0x7f); | 4577 result = (result << 7) | (input & 0x7f); |
4542 data++; | 4578 data++; |
4543 } | 4579 } |
4544 *source = data; | 4580 *source = data; |
4545 return result; | 4581 return result; |
4546 } | 4582 } |
4547 | 4583 |
4548 | 4584 |
4549 // Create a Scanner for the preparser to use as input, and preparse the source. | 4585 // Create a Scanner for the preparser to use as input, and preparse the source. |
4550 static ScriptDataImpl* DoPreParse(Handle<String> source, | 4586 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, |
4551 unibrow::CharacterStream* stream, | |
4552 bool allow_lazy, | 4587 bool allow_lazy, |
4553 ParserRecorder* recorder, | 4588 ParserRecorder* recorder, |
4554 int literal_flags) { | 4589 int literal_flags) { |
4555 V8JavaScriptScanner scanner; | 4590 V8JavaScriptScanner scanner; |
4556 scanner.Initialize(source, stream, literal_flags); | 4591 scanner.Initialize(source, literal_flags); |
4557 intptr_t stack_limit = StackGuard::real_climit(); | 4592 intptr_t stack_limit = StackGuard::real_climit(); |
4558 if (!preparser::PreParser::PreParseProgram(&scanner, | 4593 if (!preparser::PreParser::PreParseProgram(&scanner, |
4559 recorder, | 4594 recorder, |
4560 allow_lazy, | 4595 allow_lazy, |
4561 stack_limit)) { | 4596 stack_limit)) { |
4562 Top::StackOverflow(); | 4597 Top::StackOverflow(); |
4563 return NULL; | 4598 return NULL; |
4564 } | 4599 } |
4565 | 4600 |
4566 // Extract the accumulated data from the recorder as a single | 4601 // Extract the accumulated data from the recorder as a single |
4567 // contiguous vector that we are responsible for disposing. | 4602 // contiguous vector that we are responsible for disposing. |
4568 Vector<unsigned> store = recorder->ExtractData(); | 4603 Vector<unsigned> store = recorder->ExtractData(); |
4569 return new ScriptDataImpl(store); | 4604 return new ScriptDataImpl(store); |
4570 } | 4605 } |
4571 | 4606 |
4572 | 4607 |
4573 // Preparse, but only collect data that is immediately useful, | 4608 // Preparse, but only collect data that is immediately useful, |
4574 // even if the preparser data is only used once. | 4609 // even if the preparser data is only used once. |
4575 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, | 4610 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, |
4576 unibrow::CharacterStream* stream, | |
4577 v8::Extension* extension) { | 4611 v8::Extension* extension) { |
4578 bool allow_lazy = FLAG_lazy && (extension == NULL); | 4612 bool allow_lazy = FLAG_lazy && (extension == NULL); |
4579 if (!allow_lazy) { | 4613 if (!allow_lazy) { |
4580 // Partial preparsing is only about lazily compiled functions. | 4614 // Partial preparsing is only about lazily compiled functions. |
4581 // If we don't allow lazy compilation, the log data will be empty. | 4615 // If we don't allow lazy compilation, the log data will be empty. |
4582 return NULL; | 4616 return NULL; |
4583 } | 4617 } |
4584 PartialParserRecorder recorder; | 4618 PartialParserRecorder recorder; |
4585 | 4619 return DoPreParse(source, allow_lazy, &recorder, |
4586 return DoPreParse(source, stream, allow_lazy, &recorder, | |
4587 JavaScriptScanner::kNoLiterals); | 4620 JavaScriptScanner::kNoLiterals); |
4588 } | 4621 } |
4589 | 4622 |
4590 | 4623 |
4591 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, | 4624 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, |
4592 unibrow::CharacterStream* stream, | |
4593 v8::Extension* extension) { | 4625 v8::Extension* extension) { |
4594 Handle<Script> no_script; | 4626 Handle<Script> no_script; |
4595 bool allow_lazy = FLAG_lazy && (extension == NULL); | 4627 bool allow_lazy = FLAG_lazy && (extension == NULL); |
4596 CompleteParserRecorder recorder; | 4628 CompleteParserRecorder recorder; |
4597 int kPreParseLiteralsFlags = | 4629 int kPreParseLiteralsFlags = |
4598 JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier; | 4630 JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier; |
4599 return DoPreParse(source, stream, allow_lazy, | 4631 return DoPreParse(source, allow_lazy, &recorder, kPreParseLiteralsFlags); |
4600 &recorder, kPreParseLiteralsFlags); | |
4601 } | 4632 } |
4602 | 4633 |
4603 | 4634 |
4604 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4635 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
4605 bool multiline, | 4636 bool multiline, |
4606 RegExpCompileData* result) { | 4637 RegExpCompileData* result) { |
4607 ASSERT(result != NULL); | 4638 ASSERT(result != NULL); |
4608 RegExpParser parser(input, &result->error, multiline); | 4639 RegExpParser parser(input, &result->error, multiline); |
4609 RegExpTree* tree = parser.ParsePattern(); | 4640 RegExpTree* tree = parser.ParsePattern(); |
4610 if (parser.failed()) { | 4641 if (parser.failed()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4650 Handle<String> source = Handle<String>(String::cast(script->source())); | 4681 Handle<String> source = Handle<String>(String::cast(script->source())); |
4651 result = parser.ParseProgram(source, info->is_global()); | 4682 result = parser.ParseProgram(source, info->is_global()); |
4652 } | 4683 } |
4653 } | 4684 } |
4654 | 4685 |
4655 info->SetFunction(result); | 4686 info->SetFunction(result); |
4656 return (result != NULL); | 4687 return (result != NULL); |
4657 } | 4688 } |
4658 | 4689 |
4659 } } // namespace v8::internal | 4690 } } // namespace v8::internal |
OLD | NEW |