| 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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 604 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 605 bool in_global_context) { | 605 bool in_global_context) { |
| 606 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 606 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 607 | 607 |
| 608 HistogramTimerScope timer(COUNTERS->parse()); | 608 HistogramTimerScope timer(COUNTERS->parse()); |
| 609 COUNTERS->total_parse_size()->Increment(source->length()); | 609 COUNTERS->total_parse_size()->Increment(source->length()); |
| 610 fni_ = new FuncNameInferrer(); | 610 fni_ = new FuncNameInferrer(); |
| 611 | 611 |
| 612 // Initialize parser state. | 612 // Initialize parser state. |
| 613 source->TryFlatten(); | 613 source->TryFlatten(); |
| 614 scanner_.Initialize(source); | 614 if (source->IsExternalTwoByteString()) { |
| 615 // Notice that the stream is destroyed at the end of the branch block. |
| 616 // The last line of the blocks can't be moved outside, even though they're |
| 617 // identical calls. |
| 618 ExternalTwoByteStringUC16CharacterStream stream( |
| 619 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 620 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); |
| 621 return DoParseProgram(source, in_global_context, &zone_scope); |
| 622 } else { |
| 623 GenericStringUC16CharacterStream stream(source, 0, source->length()); |
| 624 scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals); |
| 625 return DoParseProgram(source, in_global_context, &zone_scope); |
| 626 } |
| 627 } |
| 628 |
| 629 |
| 630 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
| 631 bool in_global_context, |
| 632 ZoneScope* zone_scope) { |
| 615 ASSERT(target_stack_ == NULL); | 633 ASSERT(target_stack_ == NULL); |
| 616 if (pre_data_ != NULL) pre_data_->Initialize(); | 634 if (pre_data_ != NULL) pre_data_->Initialize(); |
| 617 | 635 |
| 618 // Compute the parsing mode. | 636 // Compute the parsing mode. |
| 619 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 637 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
| 620 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 638 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 621 | 639 |
| 622 Scope::Type type = | 640 Scope::Type type = |
| 623 in_global_context | 641 in_global_context |
| 624 ? Scope::GLOBAL_SCOPE | 642 ? Scope::GLOBAL_SCOPE |
| (...skipping 25 matching lines...) Expand all Loading... |
| 650 } else if (stack_overflow_) { | 668 } else if (stack_overflow_) { |
| 651 isolate()->StackOverflow(); | 669 isolate()->StackOverflow(); |
| 652 } | 670 } |
| 653 } | 671 } |
| 654 | 672 |
| 655 // Make sure the target stack is empty. | 673 // Make sure the target stack is empty. |
| 656 ASSERT(target_stack_ == NULL); | 674 ASSERT(target_stack_ == NULL); |
| 657 | 675 |
| 658 // If there was a syntax error we have to get rid of the AST | 676 // If there was a syntax error we have to get rid of the AST |
| 659 // and it is not safe to do so before the scope has been deleted. | 677 // and it is not safe to do so before the scope has been deleted. |
| 660 if (result == NULL) zone_scope.DeleteOnExit(); | 678 if (result == NULL) zone_scope->DeleteOnExit(); |
| 661 return result; | 679 return result; |
| 662 } | 680 } |
| 663 | 681 |
| 664 | |
| 665 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { | 682 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { |
| 666 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 683 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 667 HistogramTimerScope timer(COUNTERS->parse_lazy()); | 684 HistogramTimerScope timer(COUNTERS->parse_lazy()); |
| 668 Handle<String> source(String::cast(script_->source())); | 685 Handle<String> source(String::cast(script_->source())); |
| 669 COUNTERS->total_parse_size()->Increment(source->length()); | 686 COUNTERS->total_parse_size()->Increment(source->length()); |
| 670 | 687 |
| 688 // Initialize parser state. |
| 689 source->TryFlatten(); |
| 690 if (source->IsExternalTwoByteString()) { |
| 691 ExternalTwoByteStringUC16CharacterStream stream( |
| 692 Handle<ExternalTwoByteString>::cast(source), |
| 693 info->start_position(), |
| 694 info->end_position()); |
| 695 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); |
| 696 return result; |
| 697 } else { |
| 698 GenericStringUC16CharacterStream stream(source, |
| 699 info->start_position(), |
| 700 info->end_position()); |
| 701 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); |
| 702 return result; |
| 703 } |
| 704 } |
| 705 |
| 706 |
| 707 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info, |
| 708 UC16CharacterStream* source, |
| 709 ZoneScope* zone_scope) { |
| 710 scanner_.Initialize(source, JavaScriptScanner::kAllLiterals); |
| 711 ASSERT(target_stack_ == NULL); |
| 712 |
| 671 Handle<String> name(String::cast(info->name())); | 713 Handle<String> name(String::cast(info->name())); |
| 672 fni_ = new FuncNameInferrer(); | 714 fni_ = new FuncNameInferrer(); |
| 673 fni_->PushEnclosingName(name); | 715 fni_->PushEnclosingName(name); |
| 674 | 716 |
| 675 // Initialize parser state. | |
| 676 source->TryFlatten(); | |
| 677 scanner_.Initialize(source, info->start_position(), info->end_position()); | |
| 678 ASSERT(target_stack_ == NULL); | |
| 679 mode_ = PARSE_EAGERLY; | 717 mode_ = PARSE_EAGERLY; |
| 680 | 718 |
| 681 // Place holder for the result. | 719 // Place holder for the result. |
| 682 FunctionLiteral* result = NULL; | 720 FunctionLiteral* result = NULL; |
| 683 | 721 |
| 684 { | 722 { |
| 685 // Parse the function literal. | 723 // Parse the function literal. |
| 686 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 724 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 687 Scope* scope = | 725 Scope* scope = |
| 688 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 726 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 700 ASSERT(ok || stack_overflow_); | 738 ASSERT(ok || stack_overflow_); |
| 701 } | 739 } |
| 702 | 740 |
| 703 // Make sure the target stack is empty. | 741 // Make sure the target stack is empty. |
| 704 ASSERT(target_stack_ == NULL); | 742 ASSERT(target_stack_ == NULL); |
| 705 | 743 |
| 706 // If there was a stack overflow we have to get rid of AST and it is | 744 // If there was a stack overflow we have to get rid of AST and it is |
| 707 // not safe to do before scope has been deleted. | 745 // not safe to do before scope has been deleted. |
| 708 if (result == NULL) { | 746 if (result == NULL) { |
| 709 isolate()->StackOverflow(); | 747 isolate()->StackOverflow(); |
| 710 zone_scope.DeleteOnExit(); | 748 zone_scope->DeleteOnExit(); |
| 711 } else { | 749 } else { |
| 712 Handle<String> inferred_name(info->inferred_name()); | 750 Handle<String> inferred_name(info->inferred_name()); |
| 713 result->set_inferred_name(inferred_name); | 751 result->set_inferred_name(inferred_name); |
| 714 } | 752 } |
| 715 return result; | 753 return result; |
| 716 } | 754 } |
| 717 | 755 |
| 718 | 756 |
| 719 Handle<String> Parser::GetSymbol(bool* ok) { | 757 Handle<String> Parser::GetSymbol(bool* ok) { |
| 720 int symbol_id = -1; | 758 int symbol_id = -1; |
| 721 if (pre_data() != NULL) { | 759 if (pre_data() != NULL) { |
| 722 symbol_id = pre_data()->GetSymbolIdentifier(); | 760 symbol_id = pre_data()->GetSymbolIdentifier(); |
| 723 } | 761 } |
| 724 return LookupSymbol(symbol_id, scanner_.literal()); | 762 return LookupSymbol(symbol_id, scanner().literal()); |
| 725 } | 763 } |
| 726 | 764 |
| 727 | 765 |
| 728 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 766 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
| 729 Scanner::Location source_location = scanner_.location(); | 767 Scanner::Location source_location = scanner().location(); |
| 730 ReportMessageAt(source_location, type, args); | 768 ReportMessageAt(source_location, type, args); |
| 731 } | 769 } |
| 732 | 770 |
| 733 | 771 |
| 734 void Parser::ReportMessageAt(Scanner::Location source_location, | 772 void Parser::ReportMessageAt(Scanner::Location source_location, |
| 735 const char* type, | 773 const char* type, |
| 736 Vector<const char*> args) { | 774 Vector<const char*> args) { |
| 737 MessageLocation location(script_, | 775 MessageLocation location(script_, |
| 738 source_location.beg_pos, source_location.end_pos); | 776 source_location.beg_pos, source_location.end_pos); |
| 739 Handle<JSArray> array = isolate()->factory()->NewJSArray(args.length()); | 777 Handle<JSArray> array = isolate()->factory()->NewJSArray(args.length()); |
| (...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1637 } | 1675 } |
| 1638 | 1676 |
| 1639 | 1677 |
| 1640 Statement* Parser::ParseContinueStatement(bool* ok) { | 1678 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 1641 // ContinueStatement :: | 1679 // ContinueStatement :: |
| 1642 // 'continue' Identifier? ';' | 1680 // 'continue' Identifier? ';' |
| 1643 | 1681 |
| 1644 Expect(Token::CONTINUE, CHECK_OK); | 1682 Expect(Token::CONTINUE, CHECK_OK); |
| 1645 Handle<String> label = Handle<String>::null(); | 1683 Handle<String> label = Handle<String>::null(); |
| 1646 Token::Value tok = peek(); | 1684 Token::Value tok = peek(); |
| 1647 if (!scanner_.has_line_terminator_before_next() && | 1685 if (!scanner().has_line_terminator_before_next() && |
| 1648 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1686 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 1649 label = ParseIdentifier(CHECK_OK); | 1687 label = ParseIdentifier(CHECK_OK); |
| 1650 } | 1688 } |
| 1651 IterationStatement* target = NULL; | 1689 IterationStatement* target = NULL; |
| 1652 target = LookupContinueTarget(label, CHECK_OK); | 1690 target = LookupContinueTarget(label, CHECK_OK); |
| 1653 if (target == NULL) { | 1691 if (target == NULL) { |
| 1654 // Illegal continue statement. To be consistent with KJS we delay | 1692 // Illegal continue statement. To be consistent with KJS we delay |
| 1655 // reporting of the syntax error until runtime. | 1693 // reporting of the syntax error until runtime. |
| 1656 Handle<String> error_type = isolate()->factory()->illegal_continue_symbol(); | 1694 Handle<String> error_type = isolate()->factory()->illegal_continue_symbol(); |
| 1657 if (!label.is_null()) { | 1695 if (!label.is_null()) { |
| 1658 error_type = isolate()->factory()->unknown_label_symbol(); | 1696 error_type = isolate()->factory()->unknown_label_symbol(); |
| 1659 } | 1697 } |
| 1660 Expression* throw_error = NewThrowSyntaxError(error_type, label); | 1698 Expression* throw_error = NewThrowSyntaxError(error_type, label); |
| 1661 return new ExpressionStatement(throw_error); | 1699 return new ExpressionStatement(throw_error); |
| 1662 } | 1700 } |
| 1663 ExpectSemicolon(CHECK_OK); | 1701 ExpectSemicolon(CHECK_OK); |
| 1664 return new ContinueStatement(target); | 1702 return new ContinueStatement(target); |
| 1665 } | 1703 } |
| 1666 | 1704 |
| 1667 | 1705 |
| 1668 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 1706 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 1669 // BreakStatement :: | 1707 // BreakStatement :: |
| 1670 // 'break' Identifier? ';' | 1708 // 'break' Identifier? ';' |
| 1671 | 1709 |
| 1672 Expect(Token::BREAK, CHECK_OK); | 1710 Expect(Token::BREAK, CHECK_OK); |
| 1673 Handle<String> label; | 1711 Handle<String> label; |
| 1674 Token::Value tok = peek(); | 1712 Token::Value tok = peek(); |
| 1675 if (!scanner_.has_line_terminator_before_next() && | 1713 if (!scanner().has_line_terminator_before_next() && |
| 1676 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1714 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 1677 label = ParseIdentifier(CHECK_OK); | 1715 label = ParseIdentifier(CHECK_OK); |
| 1678 } | 1716 } |
| 1679 // Parse labeled break statements that target themselves into | 1717 // Parse labeled break statements that target themselves into |
| 1680 // empty statements, e.g. 'l1: l2: l3: break l2;' | 1718 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 1681 if (!label.is_null() && ContainsLabel(labels, label)) { | 1719 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 1682 return EmptyStatement(); | 1720 return EmptyStatement(); |
| 1683 } | 1721 } |
| 1684 BreakableStatement* target = NULL; | 1722 BreakableStatement* target = NULL; |
| 1685 target = LookupBreakTarget(label, CHECK_OK); | 1723 target = LookupBreakTarget(label, CHECK_OK); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1712 // function. See ECMA-262, section 12.9, page 67. | 1750 // function. See ECMA-262, section 12.9, page 67. |
| 1713 // | 1751 // |
| 1714 // To be consistent with KJS we report the syntax error at runtime. | 1752 // To be consistent with KJS we report the syntax error at runtime. |
| 1715 if (!top_scope_->is_function_scope()) { | 1753 if (!top_scope_->is_function_scope()) { |
| 1716 Handle<String> type = isolate()->factory()->illegal_return_symbol(); | 1754 Handle<String> type = isolate()->factory()->illegal_return_symbol(); |
| 1717 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); | 1755 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); |
| 1718 return new ExpressionStatement(throw_error); | 1756 return new ExpressionStatement(throw_error); |
| 1719 } | 1757 } |
| 1720 | 1758 |
| 1721 Token::Value tok = peek(); | 1759 Token::Value tok = peek(); |
| 1722 if (scanner_.has_line_terminator_before_next() || | 1760 if (scanner().has_line_terminator_before_next() || |
| 1723 tok == Token::SEMICOLON || | 1761 tok == Token::SEMICOLON || |
| 1724 tok == Token::RBRACE || | 1762 tok == Token::RBRACE || |
| 1725 tok == Token::EOS) { | 1763 tok == Token::EOS) { |
| 1726 ExpectSemicolon(CHECK_OK); | 1764 ExpectSemicolon(CHECK_OK); |
| 1727 return new ReturnStatement(GetLiteralUndefined()); | 1765 return new ReturnStatement(GetLiteralUndefined()); |
| 1728 } | 1766 } |
| 1729 | 1767 |
| 1730 Expression* expr = ParseExpression(true, CHECK_OK); | 1768 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1731 ExpectSemicolon(CHECK_OK); | 1769 ExpectSemicolon(CHECK_OK); |
| 1732 return new ReturnStatement(expr); | 1770 return new ReturnStatement(expr); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 return statement; | 1882 return statement; |
| 1845 } | 1883 } |
| 1846 | 1884 |
| 1847 | 1885 |
| 1848 Statement* Parser::ParseThrowStatement(bool* ok) { | 1886 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 1849 // ThrowStatement :: | 1887 // ThrowStatement :: |
| 1850 // 'throw' Expression ';' | 1888 // 'throw' Expression ';' |
| 1851 | 1889 |
| 1852 Expect(Token::THROW, CHECK_OK); | 1890 Expect(Token::THROW, CHECK_OK); |
| 1853 int pos = scanner().location().beg_pos; | 1891 int pos = scanner().location().beg_pos; |
| 1854 if (scanner_.has_line_terminator_before_next()) { | 1892 if (scanner().has_line_terminator_before_next()) { |
| 1855 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 1893 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 1856 *ok = false; | 1894 *ok = false; |
| 1857 return NULL; | 1895 return NULL; |
| 1858 } | 1896 } |
| 1859 Expression* exception = ParseExpression(true, CHECK_OK); | 1897 Expression* exception = ParseExpression(true, CHECK_OK); |
| 1860 ExpectSemicolon(CHECK_OK); | 1898 ExpectSemicolon(CHECK_OK); |
| 1861 | 1899 |
| 1862 return new ExpressionStatement(new Throw(exception, pos)); | 1900 return new ExpressionStatement(new Throw(exception, pos)); |
| 1863 } | 1901 } |
| 1864 | 1902 |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2412 return ParsePostfixExpression(ok); | 2450 return ParsePostfixExpression(ok); |
| 2413 } | 2451 } |
| 2414 } | 2452 } |
| 2415 | 2453 |
| 2416 | 2454 |
| 2417 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2455 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 2418 // PostfixExpression :: | 2456 // PostfixExpression :: |
| 2419 // LeftHandSideExpression ('++' | '--')? | 2457 // LeftHandSideExpression ('++' | '--')? |
| 2420 | 2458 |
| 2421 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 2459 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 2422 if (!scanner_.has_line_terminator_before_next() && Token::IsCountOp(peek())) { | 2460 if (!scanner().has_line_terminator_before_next() && |
| 2461 Token::IsCountOp(peek())) { |
| 2423 // Signal a reference error if the expression is an invalid | 2462 // Signal a reference error if the expression is an invalid |
| 2424 // left-hand side expression. We could report this as a syntax | 2463 // left-hand side expression. We could report this as a syntax |
| 2425 // error here but for compatibility with JSC we choose to report the | 2464 // error here but for compatibility with JSC we choose to report the |
| 2426 // error at runtime. | 2465 // error at runtime. |
| 2427 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2466 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2428 Handle<String> type = | 2467 Handle<String> type = |
| 2429 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); | 2468 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); |
| 2430 expression = NewThrowReferenceError(type); | 2469 expression = NewThrowReferenceError(type); |
| 2431 } | 2470 } |
| 2432 Token::Value next = Next(); | 2471 Token::Value next = Next(); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2683 case Token::IDENTIFIER: { | 2722 case Token::IDENTIFIER: { |
| 2684 Handle<String> name = ParseIdentifier(CHECK_OK); | 2723 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2685 if (fni_ != NULL) fni_->PushVariableName(name); | 2724 if (fni_ != NULL) fni_->PushVariableName(name); |
| 2686 result = top_scope_->NewUnresolved(name, inside_with()); | 2725 result = top_scope_->NewUnresolved(name, inside_with()); |
| 2687 break; | 2726 break; |
| 2688 } | 2727 } |
| 2689 | 2728 |
| 2690 case Token::NUMBER: { | 2729 case Token::NUMBER: { |
| 2691 Consume(Token::NUMBER); | 2730 Consume(Token::NUMBER); |
| 2692 double value = | 2731 double value = |
| 2693 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 2732 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); |
| 2694 result = NewNumberLiteral(value); | 2733 result = NewNumberLiteral(value); |
| 2695 break; | 2734 break; |
| 2696 } | 2735 } |
| 2697 | 2736 |
| 2698 case Token::STRING: { | 2737 case Token::STRING: { |
| 2699 Consume(Token::STRING); | 2738 Consume(Token::STRING); |
| 2700 Handle<String> symbol = GetSymbol(CHECK_OK); | 2739 Handle<String> symbol = GetSymbol(CHECK_OK); |
| 2701 result = new Literal(symbol); | 2740 result = new Literal(symbol); |
| 2702 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 2741 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 2703 break; | 2742 break; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3034 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3073 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3035 key = NewNumberLiteral(index); | 3074 key = NewNumberLiteral(index); |
| 3036 break; | 3075 break; |
| 3037 } | 3076 } |
| 3038 key = new Literal(string); | 3077 key = new Literal(string); |
| 3039 break; | 3078 break; |
| 3040 } | 3079 } |
| 3041 case Token::NUMBER: { | 3080 case Token::NUMBER: { |
| 3042 Consume(Token::NUMBER); | 3081 Consume(Token::NUMBER); |
| 3043 double value = | 3082 double value = |
| 3044 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 3083 StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS); |
| 3045 key = NewNumberLiteral(value); | 3084 key = NewNumberLiteral(value); |
| 3046 break; | 3085 break; |
| 3047 } | 3086 } |
| 3048 default: | 3087 default: |
| 3049 if (Token::IsKeyword(next)) { | 3088 if (Token::IsKeyword(next)) { |
| 3050 Consume(next); | 3089 Consume(next); |
| 3051 Handle<String> string = GetSymbol(CHECK_OK); | 3090 Handle<String> string = GetSymbol(CHECK_OK); |
| 3052 key = new Literal(string); | 3091 key = new Literal(string); |
| 3053 } else { | 3092 } else { |
| 3054 // Unexpected token. | 3093 // Unexpected token. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3095 return new ObjectLiteral(constant_properties, | 3134 return new ObjectLiteral(constant_properties, |
| 3096 properties, | 3135 properties, |
| 3097 literal_index, | 3136 literal_index, |
| 3098 is_simple, | 3137 is_simple, |
| 3099 fast_elements, | 3138 fast_elements, |
| 3100 depth); | 3139 depth); |
| 3101 } | 3140 } |
| 3102 | 3141 |
| 3103 | 3142 |
| 3104 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3143 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3105 if (!scanner_.ScanRegExpPattern(seen_equal)) { | 3144 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 3106 Next(); | 3145 Next(); |
| 3107 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3146 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3108 *ok = false; | 3147 *ok = false; |
| 3109 return NULL; | 3148 return NULL; |
| 3110 } | 3149 } |
| 3111 | 3150 |
| 3112 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3151 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
| 3113 | 3152 |
| 3114 Handle<String> js_pattern = | 3153 Handle<String> js_pattern = |
| 3115 isolate()->factory()->NewStringFromUtf8(scanner_.next_literal(), TENURED); | 3154 isolate_->factory()->NewStringFromUtf8(scanner().next_literal(), TENURED); |
| 3116 scanner_.ScanRegExpFlags(); | 3155 scanner().ScanRegExpFlags(); |
| 3117 Handle<String> js_flags = | 3156 Handle<String> js_flags = |
| 3118 isolate()->factory()->NewStringFromUtf8(scanner_.next_literal(), TENURED); | 3157 isolate_->factory()->NewStringFromUtf8(scanner().next_literal(), TENURED); |
| 3119 Next(); | 3158 Next(); |
| 3120 | 3159 |
| 3121 return new RegExpLiteral(js_pattern, js_flags, literal_index); | 3160 return new RegExpLiteral(js_pattern, js_flags, literal_index); |
| 3122 } | 3161 } |
| 3123 | 3162 |
| 3124 | 3163 |
| 3125 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3164 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3126 // Arguments :: | 3165 // Arguments :: |
| 3127 // '(' (AssignmentExpression)*[','] ')' | 3166 // '(' (AssignmentExpression)*[','] ')' |
| 3128 | 3167 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3165 { Scope* scope = | 3204 { Scope* scope = |
| 3166 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3205 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3167 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3206 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 3168 scope); | 3207 scope); |
| 3169 TemporaryScope temp_scope(&this->temp_scope_); | 3208 TemporaryScope temp_scope(&this->temp_scope_); |
| 3170 top_scope_->SetScopeName(name); | 3209 top_scope_->SetScopeName(name); |
| 3171 | 3210 |
| 3172 // FormalParameterList :: | 3211 // FormalParameterList :: |
| 3173 // '(' (Identifier)*[','] ')' | 3212 // '(' (Identifier)*[','] ')' |
| 3174 Expect(Token::LPAREN, CHECK_OK); | 3213 Expect(Token::LPAREN, CHECK_OK); |
| 3175 int start_pos = scanner_.location().beg_pos; | 3214 int start_pos = scanner().location().beg_pos; |
| 3176 bool done = (peek() == Token::RPAREN); | 3215 bool done = (peek() == Token::RPAREN); |
| 3177 while (!done) { | 3216 while (!done) { |
| 3178 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3217 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
| 3179 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, | 3218 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, |
| 3180 Variable::VAR)); | 3219 Variable::VAR)); |
| 3181 num_parameters++; | 3220 num_parameters++; |
| 3182 done = (peek() == Token::RPAREN); | 3221 done = (peek() == Token::RPAREN); |
| 3183 if (!done) Expect(Token::COMMA, CHECK_OK); | 3222 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3184 } | 3223 } |
| 3185 Expect(Token::RPAREN, CHECK_OK); | 3224 Expect(Token::RPAREN, CHECK_OK); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3202 new Assignment(Token::INIT_CONST, fproxy, | 3241 new Assignment(Token::INIT_CONST, fproxy, |
| 3203 new ThisFunction(), | 3242 new ThisFunction(), |
| 3204 RelocInfo::kNoPosition))); | 3243 RelocInfo::kNoPosition))); |
| 3205 } | 3244 } |
| 3206 | 3245 |
| 3207 // Determine if the function will be lazily compiled. The mode can | 3246 // Determine if the function will be lazily compiled. The mode can |
| 3208 // only be PARSE_LAZILY if the --lazy flag is true. | 3247 // only be PARSE_LAZILY if the --lazy flag is true. |
| 3209 bool is_lazily_compiled = | 3248 bool is_lazily_compiled = |
| 3210 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); | 3249 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); |
| 3211 | 3250 |
| 3212 int function_block_pos = scanner_.location().beg_pos; | 3251 int function_block_pos = scanner().location().beg_pos; |
| 3213 int materialized_literal_count; | 3252 int materialized_literal_count; |
| 3214 int expected_property_count; | 3253 int expected_property_count; |
| 3215 int end_pos; | 3254 int end_pos; |
| 3216 bool only_simple_this_property_assignments; | 3255 bool only_simple_this_property_assignments; |
| 3217 Handle<FixedArray> this_property_assignments; | 3256 Handle<FixedArray> this_property_assignments; |
| 3218 if (is_lazily_compiled && pre_data() != NULL) { | 3257 if (is_lazily_compiled && pre_data() != NULL) { |
| 3219 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); | 3258 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); |
| 3220 if (!entry.is_valid()) { | 3259 if (!entry.is_valid()) { |
| 3221 ReportInvalidPreparseData(name, CHECK_OK); | 3260 ReportInvalidPreparseData(name, CHECK_OK); |
| 3222 } | 3261 } |
| 3223 end_pos = entry.end_pos(); | 3262 end_pos = entry.end_pos(); |
| 3224 if (end_pos <= function_block_pos) { | 3263 if (end_pos <= function_block_pos) { |
| 3225 // End position greater than end of stream is safe, and hard to check. | 3264 // End position greater than end of stream is safe, and hard to check. |
| 3226 ReportInvalidPreparseData(name, CHECK_OK); | 3265 ReportInvalidPreparseData(name, CHECK_OK); |
| 3227 } | 3266 } |
| 3228 COUNTERS->total_preparse_skipped()->Increment( | 3267 COUNTERS->total_preparse_skipped()->Increment( |
| 3229 end_pos - function_block_pos); | 3268 end_pos - function_block_pos); |
| 3230 scanner_.SeekForward(end_pos); | 3269 // Seek to position just before terminal '}'. |
| 3270 scanner().SeekForward(end_pos - 1); |
| 3231 materialized_literal_count = entry.literal_count(); | 3271 materialized_literal_count = entry.literal_count(); |
| 3232 expected_property_count = entry.property_count(); | 3272 expected_property_count = entry.property_count(); |
| 3233 only_simple_this_property_assignments = false; | 3273 only_simple_this_property_assignments = false; |
| 3234 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 3274 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| 3235 Expect(Token::RBRACE, CHECK_OK); | 3275 Expect(Token::RBRACE, CHECK_OK); |
| 3236 } else { | 3276 } else { |
| 3237 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 3277 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| 3238 | 3278 |
| 3239 materialized_literal_count = temp_scope.materialized_literal_count(); | 3279 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3240 expected_property_count = temp_scope.expected_property_count(); | 3280 expected_property_count = temp_scope.expected_property_count(); |
| 3241 only_simple_this_property_assignments = | 3281 only_simple_this_property_assignments = |
| 3242 temp_scope.only_simple_this_property_assignments(); | 3282 temp_scope.only_simple_this_property_assignments(); |
| 3243 this_property_assignments = temp_scope.this_property_assignments(); | 3283 this_property_assignments = temp_scope.this_property_assignments(); |
| 3244 | 3284 |
| 3245 Expect(Token::RBRACE, CHECK_OK); | 3285 Expect(Token::RBRACE, CHECK_OK); |
| 3246 end_pos = scanner_.location().end_pos; | 3286 end_pos = scanner().location().end_pos; |
| 3247 } | 3287 } |
| 3248 | 3288 |
| 3249 FunctionLiteral* function_literal = | 3289 FunctionLiteral* function_literal = |
| 3250 new FunctionLiteral(name, | 3290 new FunctionLiteral(name, |
| 3251 top_scope_, | 3291 top_scope_, |
| 3252 body, | 3292 body, |
| 3253 materialized_literal_count, | 3293 materialized_literal_count, |
| 3254 expected_property_count, | 3294 expected_property_count, |
| 3255 only_simple_this_property_assignments, | 3295 only_simple_this_property_assignments, |
| 3256 this_property_assignments, | 3296 this_property_assignments, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3340 | 3380 |
| 3341 | 3381 |
| 3342 void Parser::ExpectSemicolon(bool* ok) { | 3382 void Parser::ExpectSemicolon(bool* ok) { |
| 3343 // Check for automatic semicolon insertion according to | 3383 // Check for automatic semicolon insertion according to |
| 3344 // the rules given in ECMA-262, section 7.9, page 21. | 3384 // the rules given in ECMA-262, section 7.9, page 21. |
| 3345 Token::Value tok = peek(); | 3385 Token::Value tok = peek(); |
| 3346 if (tok == Token::SEMICOLON) { | 3386 if (tok == Token::SEMICOLON) { |
| 3347 Next(); | 3387 Next(); |
| 3348 return; | 3388 return; |
| 3349 } | 3389 } |
| 3350 if (scanner_.has_line_terminator_before_next() || | 3390 if (scanner().has_line_terminator_before_next() || |
| 3351 tok == Token::RBRACE || | 3391 tok == Token::RBRACE || |
| 3352 tok == Token::EOS) { | 3392 tok == Token::EOS) { |
| 3353 return; | 3393 return; |
| 3354 } | 3394 } |
| 3355 Expect(Token::SEMICOLON, ok); | 3395 Expect(Token::SEMICOLON, ok); |
| 3356 } | 3396 } |
| 3357 | 3397 |
| 3358 | 3398 |
| 3359 Literal* Parser::GetLiteralUndefined() { | 3399 Literal* Parser::GetLiteralUndefined() { |
| 3360 return new Literal(isolate()->factory()->undefined_value()); | 3400 return new Literal(isolate()->factory()->undefined_value()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3391 | 3431 |
| 3392 // This function reads an identifier and determines whether or not it | 3432 // This function reads an identifier and determines whether or not it |
| 3393 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 3433 // is 'get' or 'set'. The reason for not using ParseIdentifier and |
| 3394 // checking on the output is that this involves heap allocation which | 3434 // checking on the output is that this involves heap allocation which |
| 3395 // we can't do during preparsing. | 3435 // we can't do during preparsing. |
| 3396 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, | 3436 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, |
| 3397 bool* is_set, | 3437 bool* is_set, |
| 3398 bool* ok) { | 3438 bool* ok) { |
| 3399 Expect(Token::IDENTIFIER, ok); | 3439 Expect(Token::IDENTIFIER, ok); |
| 3400 if (!*ok) return Handle<String>(); | 3440 if (!*ok) return Handle<String>(); |
| 3401 if (scanner_.literal_length() == 3) { | 3441 if (scanner().literal_length() == 3) { |
| 3402 const char* token = scanner_.literal_string(); | 3442 const char* token = scanner().literal_string(); |
| 3403 *is_get = strcmp(token, "get") == 0; | 3443 *is_get = strcmp(token, "get") == 0; |
| 3404 *is_set = !*is_get && strcmp(token, "set") == 0; | 3444 *is_set = !*is_get && strcmp(token, "set") == 0; |
| 3405 } | 3445 } |
| 3406 return GetSymbol(ok); | 3446 return GetSymbol(ok); |
| 3407 } | 3447 } |
| 3408 | 3448 |
| 3409 | 3449 |
| 3410 // ---------------------------------------------------------------------------- | 3450 // ---------------------------------------------------------------------------- |
| 3411 // Parser support | 3451 // Parser support |
| 3412 | 3452 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3513 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); | 3553 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); |
| 3514 args->Add(new Literal(type)); | 3554 args->Add(new Literal(type)); |
| 3515 args->Add(new Literal(array)); | 3555 args->Add(new Literal(array)); |
| 3516 return new Throw(new CallRuntime(constructor, NULL, args), | 3556 return new Throw(new CallRuntime(constructor, NULL, args), |
| 3517 scanner().location().beg_pos); | 3557 scanner().location().beg_pos); |
| 3518 } | 3558 } |
| 3519 | 3559 |
| 3520 // ---------------------------------------------------------------------------- | 3560 // ---------------------------------------------------------------------------- |
| 3521 // JSON | 3561 // JSON |
| 3522 | 3562 |
| 3523 Handle<Object> JsonParser::ParseJson(Handle<String> source) { | 3563 Handle<Object> JsonParser::ParseJson(Handle<String> script, |
| 3524 source->TryFlatten(); | 3564 UC16CharacterStream* source) { |
| 3525 scanner_.Initialize(source); | 3565 scanner_.Initialize(source); |
| 3526 stack_overflow_ = false; | 3566 stack_overflow_ = false; |
| 3527 Handle<Object> result = ParseJsonValue(); | 3567 Handle<Object> result = ParseJsonValue(); |
| 3528 if (result.is_null() || scanner_.Next() != Token::EOS) { | 3568 if (result.is_null() || scanner_.Next() != Token::EOS) { |
| 3529 if (stack_overflow_) { | 3569 if (stack_overflow_) { |
| 3530 // Scanner failed. | 3570 // Scanner failed. |
| 3531 isolate()->StackOverflow(); | 3571 isolate()->StackOverflow(); |
| 3532 } else { | 3572 } else { |
| 3533 // Parse failed. Scanner's current token is the unexpected token. | 3573 // Parse failed. Scanner's current token is the unexpected token. |
| 3534 Token::Value token = scanner_.current_token(); | 3574 Token::Value token = scanner_.current_token(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3550 message = "unexpected_token_identifier"; | 3590 message = "unexpected_token_identifier"; |
| 3551 break; | 3591 break; |
| 3552 default: | 3592 default: |
| 3553 message = "unexpected_token"; | 3593 message = "unexpected_token"; |
| 3554 name_opt = Token::String(token); | 3594 name_opt = Token::String(token); |
| 3555 ASSERT(name_opt != NULL); | 3595 ASSERT(name_opt != NULL); |
| 3556 break; | 3596 break; |
| 3557 } | 3597 } |
| 3558 | 3598 |
| 3559 Scanner::Location source_location = scanner_.location(); | 3599 Scanner::Location source_location = scanner_.location(); |
| 3560 MessageLocation location(isolate()->factory()->NewScript(source), | 3600 MessageLocation location(isolate()->factory()->NewScript(script), |
| 3561 source_location.beg_pos, | 3601 source_location.beg_pos, |
| 3562 source_location.end_pos); | 3602 source_location.end_pos); |
| 3563 int argc = (name_opt == NULL) ? 0 : 1; | 3603 int argc = (name_opt == NULL) ? 0 : 1; |
| 3564 Handle<JSArray> array = isolate()->factory()->NewJSArray(argc); | 3604 Handle<JSArray> array = isolate()->factory()->NewJSArray(argc); |
| 3565 if (name_opt != NULL) { | 3605 if (name_opt != NULL) { |
| 3566 SetElement( | 3606 SetElement( |
| 3567 array, | 3607 array, |
| 3568 0, | 3608 0, |
| 3569 isolate()->factory()->NewStringFromUtf8(CStrVector(name_opt))); | 3609 isolate()->factory()->NewStringFromUtf8(CStrVector(name_opt))); |
| 3570 } | 3610 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3704 in_(in), | 3744 in_(in), |
| 3705 current_(kEndMarker), | 3745 current_(kEndMarker), |
| 3706 next_pos_(0), | 3746 next_pos_(0), |
| 3707 capture_count_(0), | 3747 capture_count_(0), |
| 3708 has_more_(true), | 3748 has_more_(true), |
| 3709 multiline_(multiline), | 3749 multiline_(multiline), |
| 3710 simple_(false), | 3750 simple_(false), |
| 3711 contains_anchor_(false), | 3751 contains_anchor_(false), |
| 3712 is_scanned_for_captures_(false), | 3752 is_scanned_for_captures_(false), |
| 3713 failed_(false) { | 3753 failed_(false) { |
| 3714 Advance(1); | 3754 Advance(); |
| 3715 } | 3755 } |
| 3716 | 3756 |
| 3717 | 3757 |
| 3718 uc32 RegExpParser::Next() { | 3758 uc32 RegExpParser::Next() { |
| 3719 if (has_next()) { | 3759 if (has_next()) { |
| 3720 return in()->Get(next_pos_); | 3760 return in()->Get(next_pos_); |
| 3721 } else { | 3761 } else { |
| 3722 return kEndMarker; | 3762 return kEndMarker; |
| 3723 } | 3763 } |
| 3724 } | 3764 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3742 } | 3782 } |
| 3743 | 3783 |
| 3744 | 3784 |
| 3745 void RegExpParser::Reset(int pos) { | 3785 void RegExpParser::Reset(int pos) { |
| 3746 next_pos_ = pos; | 3786 next_pos_ = pos; |
| 3747 Advance(); | 3787 Advance(); |
| 3748 } | 3788 } |
| 3749 | 3789 |
| 3750 | 3790 |
| 3751 void RegExpParser::Advance(int dist) { | 3791 void RegExpParser::Advance(int dist) { |
| 3752 for (int i = 0; i < dist; i++) | 3792 next_pos_ += dist - 1; |
| 3753 Advance(); | 3793 Advance(); |
| 3754 } | 3794 } |
| 3755 | 3795 |
| 3756 | 3796 |
| 3757 bool RegExpParser::simple() { | 3797 bool RegExpParser::simple() { |
| 3758 return simple_; | 3798 return simple_; |
| 3759 } | 3799 } |
| 3760 | 3800 |
| 3761 RegExpTree* RegExpParser::ReportError(Vector<const char> message) { | 3801 RegExpTree* RegExpParser::ReportError(Vector<const char> message) { |
| 3762 failed_ = true; | 3802 failed_ = true; |
| 3763 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED); | 3803 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED); |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4399 uc32 c = ParseClassCharacterEscape(CHECK_FAILED); | 4439 uc32 c = ParseClassCharacterEscape(CHECK_FAILED); |
| 4400 return CharacterRange::Singleton(c); | 4440 return CharacterRange::Singleton(c); |
| 4401 } | 4441 } |
| 4402 } else { | 4442 } else { |
| 4403 Advance(); | 4443 Advance(); |
| 4404 return CharacterRange::Singleton(first); | 4444 return CharacterRange::Singleton(first); |
| 4405 } | 4445 } |
| 4406 } | 4446 } |
| 4407 | 4447 |
| 4408 | 4448 |
| 4449 static const uc16 kNoCharClass = 0; |
| 4450 |
| 4451 // Adds range or pre-defined character class to character ranges. |
| 4452 // If char_class is not kInvalidClass, it's interpreted as a class |
| 4453 // escape (i.e., 's' means whitespace, from '\s'). |
| 4454 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, |
| 4455 uc16 char_class, |
| 4456 CharacterRange range) { |
| 4457 if (char_class != kNoCharClass) { |
| 4458 CharacterRange::AddClassEscape(char_class, ranges); |
| 4459 } else { |
| 4460 ranges->Add(range); |
| 4461 } |
| 4462 } |
| 4463 |
| 4464 |
| 4409 RegExpTree* RegExpParser::ParseCharacterClass() { | 4465 RegExpTree* RegExpParser::ParseCharacterClass() { |
| 4410 static const char* kUnterminated = "Unterminated character class"; | 4466 static const char* kUnterminated = "Unterminated character class"; |
| 4411 static const char* kRangeOutOfOrder = "Range out of order in character class"; | 4467 static const char* kRangeOutOfOrder = "Range out of order in character class"; |
| 4412 static const char* kInvalidRange = "Invalid character range"; | |
| 4413 | 4468 |
| 4414 ASSERT_EQ(current(), '['); | 4469 ASSERT_EQ(current(), '['); |
| 4415 Advance(); | 4470 Advance(); |
| 4416 bool is_negated = false; | 4471 bool is_negated = false; |
| 4417 if (current() == '^') { | 4472 if (current() == '^') { |
| 4418 is_negated = true; | 4473 is_negated = true; |
| 4419 Advance(); | 4474 Advance(); |
| 4420 } | 4475 } |
| 4421 // A CharacterClass is a sequence of single characters, character class | |
| 4422 // escapes or ranges. Ranges are on the form "x-y" where x and y are | |
| 4423 // single characters (and not character class escapes like \s). | |
| 4424 // A "-" may occur at the start or end of the character class (just after | |
| 4425 // "[" or "[^", or just before "]") without being considered part of a | |
| 4426 // range. A "-" may also appear as the beginning or end of a range. | |
| 4427 // I.e., [--+] is valid, so is [!--]. | |
| 4428 | |
| 4429 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); | 4476 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); |
| 4430 while (has_more() && current() != ']') { | 4477 while (has_more() && current() != ']') { |
| 4431 uc16 char_class = 0; | 4478 uc16 char_class = kNoCharClass; |
| 4432 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); | 4479 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); |
| 4433 if (char_class) { | |
| 4434 CharacterRange::AddClassEscape(char_class, ranges); | |
| 4435 if (current() == '-') { | |
| 4436 Advance(); | |
| 4437 ranges->Add(CharacterRange::Singleton('-')); | |
| 4438 if (current() != ']') { | |
| 4439 ReportError(CStrVector(kInvalidRange) CHECK_FAILED); | |
| 4440 } | |
| 4441 break; | |
| 4442 } | |
| 4443 continue; | |
| 4444 } | |
| 4445 if (current() == '-') { | 4480 if (current() == '-') { |
| 4446 Advance(); | 4481 Advance(); |
| 4447 if (current() == kEndMarker) { | 4482 if (current() == kEndMarker) { |
| 4448 // If we reach the end we break out of the loop and let the | 4483 // If we reach the end we break out of the loop and let the |
| 4449 // following code report an error. | 4484 // following code report an error. |
| 4450 break; | 4485 break; |
| 4451 } else if (current() == ']') { | 4486 } else if (current() == ']') { |
| 4452 ranges->Add(first); | 4487 AddRangeOrEscape(ranges, char_class, first); |
| 4453 ranges->Add(CharacterRange::Singleton('-')); | 4488 ranges->Add(CharacterRange::Singleton('-')); |
| 4454 break; | 4489 break; |
| 4455 } | 4490 } |
| 4456 CharacterRange next = ParseClassAtom(&char_class CHECK_FAILED); | 4491 uc16 char_class_2 = kNoCharClass; |
| 4457 if (char_class) { | 4492 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED); |
| 4458 ReportError(CStrVector(kInvalidRange) CHECK_FAILED); | 4493 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) { |
| 4494 // Either end is an escaped character class. Treat the '-' verbatim. |
| 4495 AddRangeOrEscape(ranges, char_class, first); |
| 4496 ranges->Add(CharacterRange::Singleton('-')); |
| 4497 AddRangeOrEscape(ranges, char_class_2, next); |
| 4498 continue; |
| 4459 } | 4499 } |
| 4460 if (first.from() > next.to()) { | 4500 if (first.from() > next.to()) { |
| 4461 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); | 4501 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); |
| 4462 } | 4502 } |
| 4463 ranges->Add(CharacterRange::Range(first.from(), next.to())); | 4503 ranges->Add(CharacterRange::Range(first.from(), next.to())); |
| 4464 } else { | 4504 } else { |
| 4465 ranges->Add(first); | 4505 AddRangeOrEscape(ranges, char_class, first); |
| 4466 } | 4506 } |
| 4467 } | 4507 } |
| 4468 if (!has_more()) { | 4508 if (!has_more()) { |
| 4469 return ReportError(CStrVector(kUnterminated) CHECK_FAILED); | 4509 return ReportError(CStrVector(kUnterminated) CHECK_FAILED); |
| 4470 } | 4510 } |
| 4471 Advance(); | 4511 Advance(); |
| 4472 if (ranges->length() == 0) { | 4512 if (ranges->length() == 0) { |
| 4473 ranges->Add(CharacterRange::Everything()); | 4513 ranges->Add(CharacterRange::Everything()); |
| 4474 is_negated = !is_negated; | 4514 is_negated = !is_negated; |
| 4475 } | 4515 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4545 input = *data; | 4585 input = *data; |
| 4546 result = (result << 7) | (input & 0x7f); | 4586 result = (result << 7) | (input & 0x7f); |
| 4547 data++; | 4587 data++; |
| 4548 } | 4588 } |
| 4549 *source = data; | 4589 *source = data; |
| 4550 return result; | 4590 return result; |
| 4551 } | 4591 } |
| 4552 | 4592 |
| 4553 | 4593 |
| 4554 // Create a Scanner for the preparser to use as input, and preparse the source. | 4594 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 4555 static ScriptDataImpl* DoPreParse(Handle<String> source, | 4595 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, |
| 4556 unibrow::CharacterStream* stream, | |
| 4557 bool allow_lazy, | 4596 bool allow_lazy, |
| 4558 ParserRecorder* recorder, | 4597 ParserRecorder* recorder, |
| 4559 int literal_flags) { | 4598 int literal_flags) { |
| 4560 Isolate* isolate = Isolate::Current(); | 4599 Isolate* isolate = Isolate::Current(); |
| 4561 V8JavaScriptScanner scanner(isolate); | 4600 V8JavaScriptScanner scanner(isolate); |
| 4562 scanner.Initialize(source, stream, literal_flags); | 4601 scanner.Initialize(source, literal_flags); |
| 4563 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 4602 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 4564 if (!preparser::PreParser::PreParseProgram(&scanner, | 4603 if (!preparser::PreParser::PreParseProgram(&scanner, |
| 4565 recorder, | 4604 recorder, |
| 4566 allow_lazy, | 4605 allow_lazy, |
| 4567 stack_limit)) { | 4606 stack_limit)) { |
| 4568 isolate->StackOverflow(); | 4607 isolate->StackOverflow(); |
| 4569 return NULL; | 4608 return NULL; |
| 4570 } | 4609 } |
| 4571 | 4610 |
| 4572 // Extract the accumulated data from the recorder as a single | 4611 // Extract the accumulated data from the recorder as a single |
| 4573 // contiguous vector that we are responsible for disposing. | 4612 // contiguous vector that we are responsible for disposing. |
| 4574 Vector<unsigned> store = recorder->ExtractData(); | 4613 Vector<unsigned> store = recorder->ExtractData(); |
| 4575 return new ScriptDataImpl(store); | 4614 return new ScriptDataImpl(store); |
| 4576 } | 4615 } |
| 4577 | 4616 |
| 4578 | 4617 |
| 4579 // Preparse, but only collect data that is immediately useful, | 4618 // Preparse, but only collect data that is immediately useful, |
| 4580 // even if the preparser data is only used once. | 4619 // even if the preparser data is only used once. |
| 4581 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, | 4620 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, |
| 4582 unibrow::CharacterStream* stream, | |
| 4583 v8::Extension* extension) { | 4621 v8::Extension* extension) { |
| 4584 bool allow_lazy = FLAG_lazy && (extension == NULL); | 4622 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4585 if (!allow_lazy) { | 4623 if (!allow_lazy) { |
| 4586 // Partial preparsing is only about lazily compiled functions. | 4624 // Partial preparsing is only about lazily compiled functions. |
| 4587 // If we don't allow lazy compilation, the log data will be empty. | 4625 // If we don't allow lazy compilation, the log data will be empty. |
| 4588 return NULL; | 4626 return NULL; |
| 4589 } | 4627 } |
| 4590 PartialParserRecorder recorder; | 4628 PartialParserRecorder recorder; |
| 4591 | 4629 return DoPreParse(source, allow_lazy, &recorder, |
| 4592 return DoPreParse(source, stream, allow_lazy, &recorder, | |
| 4593 JavaScriptScanner::kNoLiterals); | 4630 JavaScriptScanner::kNoLiterals); |
| 4594 } | 4631 } |
| 4595 | 4632 |
| 4596 | 4633 |
| 4597 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, | 4634 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, |
| 4598 unibrow::CharacterStream* stream, | |
| 4599 v8::Extension* extension) { | 4635 v8::Extension* extension) { |
| 4600 Handle<Script> no_script; | 4636 Handle<Script> no_script; |
| 4601 bool allow_lazy = FLAG_lazy && (extension == NULL); | 4637 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4602 CompleteParserRecorder recorder; | 4638 CompleteParserRecorder recorder; |
| 4603 int kPreParseLiteralsFlags = | 4639 int kPreParseLiteralsFlags = |
| 4604 JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier; | 4640 JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier; |
| 4605 return DoPreParse(source, stream, allow_lazy, | 4641 return DoPreParse(source, allow_lazy, &recorder, kPreParseLiteralsFlags); |
| 4606 &recorder, kPreParseLiteralsFlags); | |
| 4607 } | 4642 } |
| 4608 | 4643 |
| 4609 | 4644 |
| 4610 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4645 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 4611 bool multiline, | 4646 bool multiline, |
| 4612 RegExpCompileData* result) { | 4647 RegExpCompileData* result) { |
| 4613 ASSERT(result != NULL); | 4648 ASSERT(result != NULL); |
| 4614 RegExpParser parser(input, &result->error, multiline); | 4649 RegExpParser parser(input, &result->error, multiline); |
| 4615 RegExpTree* tree = parser.ParsePattern(); | 4650 RegExpTree* tree = parser.ParsePattern(); |
| 4616 if (parser.failed()) { | 4651 if (parser.failed()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4657 Handle<String> source = Handle<String>(String::cast(script->source())); | 4692 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 4658 result = parser.ParseProgram(source, info->is_global()); | 4693 result = parser.ParseProgram(source, info->is_global()); |
| 4659 } | 4694 } |
| 4660 } | 4695 } |
| 4661 | 4696 |
| 4662 info->SetFunction(result); | 4697 info->SetFunction(result); |
| 4663 return (result != NULL); | 4698 return (result != NULL); |
| 4664 } | 4699 } |
| 4665 | 4700 |
| 4666 } } // namespace v8::internal | 4701 } } // namespace v8::internal |
| OLD | NEW |