OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]"); | 737 TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]"); |
738 TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]"); | 738 TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]"); |
739 // Escaped ']'s wont end the character class. | 739 // Escaped ']'s wont end the character class. |
740 TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]"); | 740 TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]"); |
741 // Escaped slashes are not terminating. | 741 // Escaped slashes are not terminating. |
742 TestScanRegExp("/\\//flipperwald", "\\/"); | 742 TestScanRegExp("/\\//flipperwald", "\\/"); |
743 // Starting with '=' works too. | 743 // Starting with '=' works too. |
744 TestScanRegExp("/=/", "="); | 744 TestScanRegExp("/=/", "="); |
745 TestScanRegExp("/=?/", "=?"); | 745 TestScanRegExp("/=?/", "=?"); |
746 } | 746 } |
| 747 |
| 748 |
| 749 TEST(ScopePositions) { |
| 750 // Test the parser for correctly setting the start and end positions |
| 751 // of a scope. We check the scope positions of exactly one scope |
| 752 // nested in the global scope of a program. 'inner source' is the |
| 753 // source code that determines the part of the source belonging |
| 754 // to the nested scope. 'outer_prefix' and 'outer_suffix' are |
| 755 // parts of the source that belong to the global scope. |
| 756 struct SourceData { |
| 757 const char* outer_prefix; |
| 758 const char* inner_source; |
| 759 const char* outer_suffix; |
| 760 i::ScopeType scope_type; |
| 761 }; |
| 762 |
| 763 const SourceData source_data[] = { |
| 764 { " with ({}) ", "{ block; }", " more;", i::WITH_SCOPE }, |
| 765 { " with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE }, |
| 766 { " with ({}) ", "{\n" |
| 767 " block;\n" |
| 768 " }", "\n" |
| 769 " more;", i::WITH_SCOPE }, |
| 770 { " with ({}) ", "statement;", " more;", i::WITH_SCOPE }, |
| 771 { " with ({}) ", "statement", "\n" |
| 772 " more;", i::WITH_SCOPE }, |
| 773 { " with ({})\n" |
| 774 " ", "statement;", "\n" |
| 775 " more;", i::WITH_SCOPE }, |
| 776 { " try {} catch ", "(e) { block; }", " more;", i::CATCH_SCOPE }, |
| 777 { " try {} catch ", "(e) { block; }", "; more;", i::CATCH_SCOPE }, |
| 778 { " try {} catch ", "(e) {\n" |
| 779 " block;\n" |
| 780 " }", "\n" |
| 781 " more;", i::CATCH_SCOPE }, |
| 782 { " try {} catch ", "(e) { block; }", " finally { block; } more;", |
| 783 i::CATCH_SCOPE }, |
| 784 { " start;\n" |
| 785 " ", "{ let block; }", " more;", i::BLOCK_SCOPE }, |
| 786 { " start;\n" |
| 787 " ", "{ let block; }", "; more;", i::BLOCK_SCOPE }, |
| 788 { " start;\n" |
| 789 " ", "{\n" |
| 790 " let block;\n" |
| 791 " }", "\n" |
| 792 " more;", i::BLOCK_SCOPE }, |
| 793 { " start;\n" |
| 794 " function fun", "(a,b) { infunction; }", " more;", |
| 795 i::FUNCTION_SCOPE }, |
| 796 { " start;\n" |
| 797 " function fun", "(a,b) {\n" |
| 798 " infunction;\n" |
| 799 " }", "\n" |
| 800 " more;", i::FUNCTION_SCOPE }, |
| 801 { " (function fun", "(a,b) { infunction; }", ")();", |
| 802 i::FUNCTION_SCOPE }, |
| 803 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", |
| 804 i::BLOCK_SCOPE }, |
| 805 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", |
| 806 i::BLOCK_SCOPE }, |
| 807 { " for ", "(let x = 1 ; x < 10; ++ x) {\n" |
| 808 " block;\n" |
| 809 " }", "\n" |
| 810 " more;", i::BLOCK_SCOPE }, |
| 811 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;", |
| 812 i::BLOCK_SCOPE }, |
| 813 { " for ", "(let x = 1 ; x < 10; ++ x) statement", "\n" |
| 814 " more;", i::BLOCK_SCOPE }, |
| 815 { " for ", "(let x = 1 ; x < 10; ++ x)\n" |
| 816 " statement;", "\n" |
| 817 " more;", i::BLOCK_SCOPE }, |
| 818 { " for ", "(let x in {}) { block; }", " more;", i::BLOCK_SCOPE }, |
| 819 { " for ", "(let x in {}) { block; }", "; more;", i::BLOCK_SCOPE }, |
| 820 { " for ", "(let x in {}) {\n" |
| 821 " block;\n" |
| 822 " }", "\n" |
| 823 " more;", i::BLOCK_SCOPE }, |
| 824 { " for ", "(let x in {}) statement;", " more;", i::BLOCK_SCOPE }, |
| 825 { " for ", "(let x in {}) statement", "\n" |
| 826 " more;", i::BLOCK_SCOPE }, |
| 827 { " for ", "(let x in {})\n" |
| 828 " statement;", "\n" |
| 829 " more;", i::BLOCK_SCOPE }, |
| 830 { NULL, NULL, NULL, i::EVAL_SCOPE } |
| 831 }; |
| 832 |
| 833 v8::HandleScope handles; |
| 834 v8::Persistent<v8::Context> context = v8::Context::New(); |
| 835 v8::Context::Scope context_scope(context); |
| 836 |
| 837 int marker; |
| 838 i::Isolate::Current()->stack_guard()->SetStackLimit( |
| 839 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
| 840 |
| 841 for (int i = 0; source_data[i].outer_prefix; i++) { |
| 842 int kPrefixLen = i::StrLength(source_data[i].outer_prefix); |
| 843 int kInnerLen = i::StrLength(source_data[i].inner_source); |
| 844 int kSuffixLen = i::StrLength(source_data[i].outer_suffix); |
| 845 int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen; |
| 846 i::Vector<char> program = i::Vector<char>::New(kProgramSize + 1); |
| 847 int length; |
| 848 length = i::OS::SNPrintF(program, "%s%s%s", |
| 849 source_data[i].outer_prefix, |
| 850 source_data[i].inner_source, |
| 851 source_data[i].outer_suffix); |
| 852 ASSERT(length == kProgramSize); |
| 853 |
| 854 // Parse program source. |
| 855 i::Handle<i::String> source( |
| 856 FACTORY->NewStringFromAscii(i::CStrVector(program.start()))); |
| 857 i::Handle<i::Script> script = FACTORY->NewScript(source); |
| 858 i::Parser parser(script, false, NULL, NULL); |
| 859 parser.SetHarmonyScoping(true); |
| 860 i::FunctionLiteral* function = |
| 861 parser.ParseProgram(source, true, i::kNonStrictMode); |
| 862 ASSERT(function != NULL); |
| 863 |
| 864 // Check scope types and positions. |
| 865 i::Scope* scope = function->scope(); |
| 866 CHECK(scope->is_global_scope()); |
| 867 CHECK_EQ(scope->start_position(), 0); |
| 868 CHECK_EQ(scope->end_position(), kProgramSize); |
| 869 CHECK_EQ(scope->inner_scopes()->length(), 1); |
| 870 |
| 871 i::Scope* inner_scope = scope->inner_scopes()->at(0); |
| 872 CHECK_EQ(inner_scope->type(), source_data[i].scope_type); |
| 873 CHECK_EQ(inner_scope->start_position(), kPrefixLen); |
| 874 // The end position of a token is one position after the last |
| 875 // character belonging to that token. |
| 876 CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen); |
| 877 } |
| 878 } |
OLD | NEW |