| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 17 matching lines...) Expand all Loading... |
| 28 #include <stdlib.h> | 28 #include <stdlib.h> |
| 29 #include <stdio.h> | 29 #include <stdio.h> |
| 30 #include <string.h> | 30 #include <string.h> |
| 31 | 31 |
| 32 #include "v8.h" | 32 #include "v8.h" |
| 33 | 33 |
| 34 #include "cctest.h" | 34 #include "cctest.h" |
| 35 #include "compiler.h" | 35 #include "compiler.h" |
| 36 #include "execution.h" | 36 #include "execution.h" |
| 37 #include "isolate.h" | 37 #include "isolate.h" |
| 38 #include "objects.h" |
| 38 #include "parser.h" | 39 #include "parser.h" |
| 39 #include "preparser.h" | 40 #include "preparser.h" |
| 40 #include "scanner-character-streams.h" | 41 #include "scanner-character-streams.h" |
| 41 #include "token.h" | 42 #include "token.h" |
| 42 #include "utils.h" | 43 #include "utils.h" |
| 43 | 44 |
| 44 TEST(ScanKeywords) { | 45 TEST(ScanKeywords) { |
| 45 struct KeywordToken { | 46 struct KeywordToken { |
| 46 const char* keyword; | 47 const char* keyword; |
| 47 i::Token::Value token; | 48 i::Token::Value token; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 const char* error_source = "var x = y z;"; | 206 const char* error_source = "var x = y z;"; |
| 206 int error_source_length = i::StrLength(error_source); | 207 int error_source_length = i::StrLength(error_source); |
| 207 | 208 |
| 208 v8::ScriptData* preparse = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( | 209 v8::ScriptData* preparse = v8::ScriptData::PreCompile(v8::String::NewFromUtf8( |
| 209 isolate, source, v8::String::kNormalString, source_length)); | 210 isolate, source, v8::String::kNormalString, source_length)); |
| 210 CHECK(!preparse->HasError()); | 211 CHECK(!preparse->HasError()); |
| 211 bool lazy_flag = i::FLAG_lazy; | 212 bool lazy_flag = i::FLAG_lazy; |
| 212 { | 213 { |
| 213 i::FLAG_lazy = true; | 214 i::FLAG_lazy = true; |
| 214 ScriptResource* resource = new ScriptResource(source, source_length); | 215 ScriptResource* resource = new ScriptResource(source, source_length); |
| 215 v8::Local<v8::String> script_source = | 216 v8::ScriptCompiler::Source script_source( |
| 216 v8::String::NewExternal(isolate, resource); | 217 v8::String::NewExternal(isolate, resource), |
| 217 v8::Script::Compile(script_source, NULL, preparse); | 218 v8::ScriptCompiler::CachedData( |
| 219 reinterpret_cast<const uint8_t*>(preparse->Data()), |
| 220 preparse->Length())); |
| 221 v8::ScriptCompiler::Compile(isolate, |
| 222 v8::ScriptCompiler::Source(script_source)); |
| 218 } | 223 } |
| 219 | 224 |
| 220 { | 225 { |
| 221 i::FLAG_lazy = false; | 226 i::FLAG_lazy = false; |
| 222 | 227 |
| 223 ScriptResource* resource = new ScriptResource(source, source_length); | 228 ScriptResource* resource = new ScriptResource(source, source_length); |
| 224 v8::Local<v8::String> script_source = | 229 v8::ScriptCompiler::Source script_source( |
| 225 v8::String::NewExternal(isolate, resource); | 230 v8::String::NewExternal(isolate, resource), |
| 226 v8::Script::New(script_source, NULL, preparse, v8::Local<v8::String>()); | 231 v8::ScriptCompiler::CachedData( |
| 232 reinterpret_cast<const uint8_t*>(preparse->Data()), |
| 233 preparse->Length())); |
| 234 v8::ScriptCompiler::CompileUnbound(isolate, script_source); |
| 227 } | 235 } |
| 228 delete preparse; | 236 delete preparse; |
| 229 i::FLAG_lazy = lazy_flag; | 237 i::FLAG_lazy = lazy_flag; |
| 230 | 238 |
| 231 // Syntax error. | 239 // Syntax error. |
| 232 v8::ScriptData* error_preparse = v8::ScriptData::PreCompile( | 240 v8::ScriptData* error_preparse = v8::ScriptData::PreCompile( |
| 233 v8::String::NewFromUtf8(isolate, | 241 v8::String::NewFromUtf8(isolate, |
| 234 error_source, | 242 error_source, |
| 235 v8::String::kNormalString, | 243 v8::String::kNormalString, |
| 236 error_source_length)); | 244 error_source_length)); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 v8::Local<v8::Value> result = PreCompileCompileRun(source); | 364 v8::Local<v8::Value> result = PreCompileCompileRun(source); |
| 357 CHECK(result->IsString()); | 365 CHECK(result->IsString()); |
| 358 v8::String::Utf8Value utf8(result); | 366 v8::String::Utf8Value utf8(result); |
| 359 CHECK_EQ("foo", *utf8); | 367 CHECK_EQ("foo", *utf8); |
| 360 } | 368 } |
| 361 } | 369 } |
| 362 | 370 |
| 363 namespace v8 { | 371 namespace v8 { |
| 364 namespace internal { | 372 namespace internal { |
| 365 | 373 |
| 366 void FakeWritingSymbolIdInPreParseData(i::CompleteParserRecorder* log, | 374 struct CompleteParserRecorderFriend { |
| 367 int number) { | 375 static void FakeWritingSymbolIdInPreParseData(CompleteParserRecorder* log, |
| 368 log->WriteNumber(number); | 376 int number) { |
| 369 if (log->symbol_id_ < number + 1) { | 377 log->WriteNumber(number); |
| 370 log->symbol_id_ = number + 1; | 378 if (log->symbol_id_ < number + 1) { |
| 379 log->symbol_id_ = number + 1; |
| 380 } |
| 371 } | 381 } |
| 372 } | 382 static int symbol_position(CompleteParserRecorder* log) { |
| 383 return log->symbol_store_.size(); |
| 384 } |
| 385 static int symbol_ids(CompleteParserRecorder* log) { |
| 386 return log->symbol_id_; |
| 387 } |
| 388 static int function_position(CompleteParserRecorder* log) { |
| 389 return log->function_store_.size(); |
| 390 } |
| 391 }; |
| 373 | 392 |
| 374 } | 393 } |
| 375 } | 394 } |
| 376 | 395 |
| 377 | 396 |
| 378 TEST(StoringNumbersInPreParseData) { | 397 TEST(StoringNumbersInPreParseData) { |
| 379 // Symbol IDs are split into chunks of 7 bits for storing. This is a | 398 // Symbol IDs are split into chunks of 7 bits for storing. This is a |
| 380 // regression test for a bug where a symbol id was incorrectly stored if some | 399 // regression test for a bug where a symbol id was incorrectly stored if some |
| 381 // of the chunks in the middle were all zeros. | 400 // of the chunks in the middle were all zeros. |
| 401 typedef i::CompleteParserRecorderFriend F; |
| 382 i::CompleteParserRecorder log; | 402 i::CompleteParserRecorder log; |
| 383 for (int i = 0; i < 18; ++i) { | 403 for (int i = 0; i < 18; ++i) { |
| 384 FakeWritingSymbolIdInPreParseData(&log, 1 << i); | 404 F::FakeWritingSymbolIdInPreParseData(&log, 1 << i); |
| 385 } | 405 } |
| 386 for (int i = 1; i < 18; ++i) { | 406 for (int i = 1; i < 18; ++i) { |
| 387 FakeWritingSymbolIdInPreParseData(&log, (1 << i) + 1); | 407 F::FakeWritingSymbolIdInPreParseData(&log, (1 << i) + 1); |
| 388 } | 408 } |
| 389 for (int i = 6; i < 18; ++i) { | 409 for (int i = 6; i < 18; ++i) { |
| 390 FakeWritingSymbolIdInPreParseData(&log, (3 << i) + (5 << (i - 6))); | 410 F::FakeWritingSymbolIdInPreParseData(&log, (3 << i) + (5 << (i - 6))); |
| 391 } | 411 } |
| 392 i::Vector<unsigned> store = log.ExtractData(); | 412 i::Vector<unsigned> store = log.ExtractData(); |
| 393 i::ScriptDataImpl script_data(store); | 413 i::ScriptDataImpl script_data(store); |
| 394 script_data.Initialize(); | 414 script_data.Initialize(); |
| 395 // Check that we get the same symbols back. | 415 // Check that we get the same symbols back. |
| 396 for (int i = 0; i < 18; ++i) { | 416 for (int i = 0; i < 18; ++i) { |
| 397 CHECK_EQ(1 << i, script_data.GetSymbolIdentifier()); | 417 CHECK_EQ(1 << i, script_data.GetSymbolIdentifier()); |
| 398 } | 418 } |
| 399 for (int i = 1; i < 18; ++i) { | 419 for (int i = 1; i < 18; ++i) { |
| 400 CHECK_EQ((1 << i) + 1, script_data.GetSymbolIdentifier()); | 420 CHECK_EQ((1 << i) + 1, script_data.GetSymbolIdentifier()); |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 static_cast<unsigned>(strlen(str3))); | 815 static_cast<unsigned>(strlen(str3))); |
| 796 TestStreamScanner(&stream3, expectations3, 1, 1 + i); | 816 TestStreamScanner(&stream3, expectations3, 1, 1 + i); |
| 797 } | 817 } |
| 798 } | 818 } |
| 799 | 819 |
| 800 | 820 |
| 801 void TestScanRegExp(const char* re_source, const char* expected) { | 821 void TestScanRegExp(const char* re_source, const char* expected) { |
| 802 i::Utf8ToUtf16CharacterStream stream( | 822 i::Utf8ToUtf16CharacterStream stream( |
| 803 reinterpret_cast<const i::byte*>(re_source), | 823 reinterpret_cast<const i::byte*>(re_source), |
| 804 static_cast<unsigned>(strlen(re_source))); | 824 static_cast<unsigned>(strlen(re_source))); |
| 825 i::HandleScope scope(CcTest::i_isolate()); |
| 805 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 826 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 806 scanner.Initialize(&stream); | 827 scanner.Initialize(&stream); |
| 807 | 828 |
| 808 i::Token::Value start = scanner.peek(); | 829 i::Token::Value start = scanner.peek(); |
| 809 CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); | 830 CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); |
| 810 CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV)); | 831 CHECK(scanner.ScanRegExpPattern(start == i::Token::ASSIGN_DIV)); |
| 811 scanner.Next(); // Current token is now the regexp literal. | 832 scanner.Next(); // Current token is now the regexp literal. |
| 812 CHECK(scanner.is_literal_ascii()); | 833 i::Handle<i::String> val = |
| 813 i::Vector<const char> actual = scanner.literal_ascii_string(); | 834 scanner.AllocateInternalizedString(CcTest::i_isolate()); |
| 835 i::DisallowHeapAllocation no_alloc; |
| 836 i::String::FlatContent content = val->GetFlatContent(); |
| 837 CHECK(content.IsAscii()); |
| 838 i::Vector<const uint8_t> actual = content.ToOneByteVector(); |
| 814 for (int i = 0; i < actual.length(); i++) { | 839 for (int i = 0; i < actual.length(); i++) { |
| 815 CHECK_NE('\0', expected[i]); | 840 CHECK_NE('\0', expected[i]); |
| 816 CHECK_EQ(expected[i], actual[i]); | 841 CHECK_EQ(expected[i], actual[i]); |
| 817 } | 842 } |
| 818 } | 843 } |
| 819 | 844 |
| 820 | 845 |
| 821 TEST(RegExpScanning) { | 846 TEST(RegExpScanning) { |
| 822 v8::V8::Initialize(); | 847 v8::V8::Initialize(); |
| 823 | 848 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 i += input_offset; | 935 i += input_offset; |
| 911 character_length -= output_adjust; | 936 character_length -= output_adjust; |
| 912 } | 937 } |
| 913 } | 938 } |
| 914 } | 939 } |
| 915 return character_length; | 940 return character_length; |
| 916 } | 941 } |
| 917 | 942 |
| 918 | 943 |
| 919 TEST(ScopePositions) { | 944 TEST(ScopePositions) { |
| 945 v8::internal::FLAG_harmony_scoping = true; |
| 946 |
| 920 // Test the parser for correctly setting the start and end positions | 947 // Test the parser for correctly setting the start and end positions |
| 921 // of a scope. We check the scope positions of exactly one scope | 948 // of a scope. We check the scope positions of exactly one scope |
| 922 // nested in the global scope of a program. 'inner source' is the | 949 // nested in the global scope of a program. 'inner source' is the |
| 923 // source code that determines the part of the source belonging | 950 // source code that determines the part of the source belonging |
| 924 // to the nested scope. 'outer_prefix' and 'outer_suffix' are | 951 // to the nested scope. 'outer_prefix' and 'outer_suffix' are |
| 925 // parts of the source that belong to the global scope. | 952 // parts of the source that belong to the global scope. |
| 926 struct SourceData { | 953 struct SourceData { |
| 927 const char* outer_prefix; | 954 const char* outer_prefix; |
| 928 const char* inner_source; | 955 const char* inner_source; |
| 929 const char* outer_suffix; | 956 const char* outer_suffix; |
| 930 i::ScopeType scope_type; | 957 i::ScopeType scope_type; |
| 931 i::LanguageMode language_mode; | 958 i::StrictMode strict_mode; |
| 932 }; | 959 }; |
| 933 | 960 |
| 934 const SourceData source_data[] = { | 961 const SourceData source_data[] = { |
| 935 { " with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, | 962 { " with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::SLOPPY }, |
| 936 { " with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::CLASSIC_MODE }, | 963 { " with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::SLOPPY }, |
| 937 { " with ({}) ", "{\n" | 964 { " with ({}) ", "{\n" |
| 938 " block;\n" | 965 " block;\n" |
| 939 " }", "\n" | 966 " }", "\n" |
| 940 " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, | 967 " more;", i::WITH_SCOPE, i::SLOPPY }, |
| 941 { " with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, | 968 { " with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::SLOPPY }, |
| 942 { " with ({}) ", "statement", "\n" | 969 { " with ({}) ", "statement", "\n" |
| 943 " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, | 970 " more;", i::WITH_SCOPE, i::SLOPPY }, |
| 944 { " with ({})\n" | 971 { " with ({})\n" |
| 945 " ", "statement;", "\n" | 972 " ", "statement;", "\n" |
| 946 " more;", i::WITH_SCOPE, i::CLASSIC_MODE }, | 973 " more;", i::WITH_SCOPE, i::SLOPPY }, |
| 947 { " try {} catch ", "(e) { block; }", " more;", | 974 { " try {} catch ", "(e) { block; }", " more;", |
| 948 i::CATCH_SCOPE, i::CLASSIC_MODE }, | 975 i::CATCH_SCOPE, i::SLOPPY }, |
| 949 { " try {} catch ", "(e) { block; }", "; more;", | 976 { " try {} catch ", "(e) { block; }", "; more;", |
| 950 i::CATCH_SCOPE, i::CLASSIC_MODE }, | 977 i::CATCH_SCOPE, i::SLOPPY }, |
| 951 { " try {} catch ", "(e) {\n" | 978 { " try {} catch ", "(e) {\n" |
| 952 " block;\n" | 979 " block;\n" |
| 953 " }", "\n" | 980 " }", "\n" |
| 954 " more;", i::CATCH_SCOPE, i::CLASSIC_MODE }, | 981 " more;", i::CATCH_SCOPE, i::SLOPPY }, |
| 955 { " try {} catch ", "(e) { block; }", " finally { block; } more;", | 982 { " try {} catch ", "(e) { block; }", " finally { block; } more;", |
| 956 i::CATCH_SCOPE, i::CLASSIC_MODE }, | 983 i::CATCH_SCOPE, i::SLOPPY }, |
| 957 { " start;\n" | 984 { " start;\n" |
| 958 " ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 985 " ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 959 { " start;\n" | 986 { " start;\n" |
| 960 " ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 987 " ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::STRICT }, |
| 961 { " start;\n" | 988 { " start;\n" |
| 962 " ", "{\n" | 989 " ", "{\n" |
| 963 " let block;\n" | 990 " let block;\n" |
| 964 " }", "\n" | 991 " }", "\n" |
| 965 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 992 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 966 { " start;\n" | 993 { " start;\n" |
| 967 " function fun", "(a,b) { infunction; }", " more;", | 994 " function fun", "(a,b) { infunction; }", " more;", |
| 968 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 995 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 969 { " start;\n" | 996 { " start;\n" |
| 970 " function fun", "(a,b) {\n" | 997 " function fun", "(a,b) {\n" |
| 971 " infunction;\n" | 998 " infunction;\n" |
| 972 " }", "\n" | 999 " }", "\n" |
| 973 " more;", i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1000 " more;", i::FUNCTION_SCOPE, i::SLOPPY }, |
| 974 { " (function fun", "(a,b) { infunction; }", ")();", | 1001 { " (function fun", "(a,b) { infunction; }", ")();", |
| 975 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1002 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 976 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", | 1003 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", |
| 977 i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1004 i::BLOCK_SCOPE, i::STRICT }, |
| 978 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", | 1005 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", |
| 979 i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1006 i::BLOCK_SCOPE, i::STRICT }, |
| 980 { " for ", "(let x = 1 ; x < 10; ++ x) {\n" | 1007 { " for ", "(let x = 1 ; x < 10; ++ x) {\n" |
| 981 " block;\n" | 1008 " block;\n" |
| 982 " }", "\n" | 1009 " }", "\n" |
| 983 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1010 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 984 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;", | 1011 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;", |
| 985 i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1012 i::BLOCK_SCOPE, i::STRICT }, |
| 986 { " for ", "(let x = 1 ; x < 10; ++ x) statement", "\n" | 1013 { " for ", "(let x = 1 ; x < 10; ++ x) statement", "\n" |
| 987 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1014 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 988 { " for ", "(let x = 1 ; x < 10; ++ x)\n" | 1015 { " for ", "(let x = 1 ; x < 10; ++ x)\n" |
| 989 " statement;", "\n" | 1016 " statement;", "\n" |
| 990 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1017 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 991 { " for ", "(let x in {}) { block; }", " more;", | 1018 { " for ", "(let x in {}) { block; }", " more;", |
| 992 i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1019 i::BLOCK_SCOPE, i::STRICT }, |
| 993 { " for ", "(let x in {}) { block; }", "; more;", | 1020 { " for ", "(let x in {}) { block; }", "; more;", |
| 994 i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1021 i::BLOCK_SCOPE, i::STRICT }, |
| 995 { " for ", "(let x in {}) {\n" | 1022 { " for ", "(let x in {}) {\n" |
| 996 " block;\n" | 1023 " block;\n" |
| 997 " }", "\n" | 1024 " }", "\n" |
| 998 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1025 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 999 { " for ", "(let x in {}) statement;", " more;", | 1026 { " for ", "(let x in {}) statement;", " more;", |
| 1000 i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1027 i::BLOCK_SCOPE, i::STRICT }, |
| 1001 { " for ", "(let x in {}) statement", "\n" | 1028 { " for ", "(let x in {}) statement", "\n" |
| 1002 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1029 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 1003 { " for ", "(let x in {})\n" | 1030 { " for ", "(let x in {})\n" |
| 1004 " statement;", "\n" | 1031 " statement;", "\n" |
| 1005 " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE }, | 1032 " more;", i::BLOCK_SCOPE, i::STRICT }, |
| 1006 // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw | 1033 // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw |
| 1007 // the preparser off in terms of byte offsets. | 1034 // the preparser off in terms of byte offsets. |
| 1008 // 6 byte encoding. | 1035 // 6 byte encoding. |
| 1009 { " 'foo\355\240\201\355\260\211';\n" | 1036 { " 'foo\355\240\201\355\260\211';\n" |
| 1010 " (function fun", "(a,b) { infunction; }", ")();", | 1037 " (function fun", "(a,b) { infunction; }", ")();", |
| 1011 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1038 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1012 // 4 byte encoding. | 1039 // 4 byte encoding. |
| 1013 { " 'foo\360\220\220\212';\n" | 1040 { " 'foo\360\220\220\212';\n" |
| 1014 " (function fun", "(a,b) { infunction; }", ")();", | 1041 " (function fun", "(a,b) { infunction; }", ")();", |
| 1015 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1042 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1016 // 3 byte encoding of \u0fff. | 1043 // 3 byte encoding of \u0fff. |
| 1017 { " 'foo\340\277\277';\n" | 1044 { " 'foo\340\277\277';\n" |
| 1018 " (function fun", "(a,b) { infunction; }", ")();", | 1045 " (function fun", "(a,b) { infunction; }", ")();", |
| 1019 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1046 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1020 // Broken 6 byte encoding with missing last byte. | 1047 // Broken 6 byte encoding with missing last byte. |
| 1021 { " 'foo\355\240\201\355\211';\n" | 1048 { " 'foo\355\240\201\355\211';\n" |
| 1022 " (function fun", "(a,b) { infunction; }", ")();", | 1049 " (function fun", "(a,b) { infunction; }", ")();", |
| 1023 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1050 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1024 // Broken 3 byte encoding of \u0fff with missing last byte. | 1051 // Broken 3 byte encoding of \u0fff with missing last byte. |
| 1025 { " 'foo\340\277';\n" | 1052 { " 'foo\340\277';\n" |
| 1026 " (function fun", "(a,b) { infunction; }", ")();", | 1053 " (function fun", "(a,b) { infunction; }", ")();", |
| 1027 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1054 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1028 // Broken 3 byte encoding of \u0fff with missing 2 last bytes. | 1055 // Broken 3 byte encoding of \u0fff with missing 2 last bytes. |
| 1029 { " 'foo\340';\n" | 1056 { " 'foo\340';\n" |
| 1030 " (function fun", "(a,b) { infunction; }", ")();", | 1057 " (function fun", "(a,b) { infunction; }", ")();", |
| 1031 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1058 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1032 // Broken 3 byte encoding of \u00ff should be a 2 byte encoding. | 1059 // Broken 3 byte encoding of \u00ff should be a 2 byte encoding. |
| 1033 { " 'foo\340\203\277';\n" | 1060 { " 'foo\340\203\277';\n" |
| 1034 " (function fun", "(a,b) { infunction; }", ")();", | 1061 " (function fun", "(a,b) { infunction; }", ")();", |
| 1035 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1062 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1036 // Broken 3 byte encoding of \u007f should be a 2 byte encoding. | 1063 // Broken 3 byte encoding of \u007f should be a 2 byte encoding. |
| 1037 { " 'foo\340\201\277';\n" | 1064 { " 'foo\340\201\277';\n" |
| 1038 " (function fun", "(a,b) { infunction; }", ")();", | 1065 " (function fun", "(a,b) { infunction; }", ")();", |
| 1039 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1066 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1040 // Unpaired lead surrogate. | 1067 // Unpaired lead surrogate. |
| 1041 { " 'foo\355\240\201';\n" | 1068 { " 'foo\355\240\201';\n" |
| 1042 " (function fun", "(a,b) { infunction; }", ")();", | 1069 " (function fun", "(a,b) { infunction; }", ")();", |
| 1043 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1070 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1044 // Unpaired lead surrogate where following code point is a 3 byte sequence. | 1071 // Unpaired lead surrogate where following code point is a 3 byte sequence. |
| 1045 { " 'foo\355\240\201\340\277\277';\n" | 1072 { " 'foo\355\240\201\340\277\277';\n" |
| 1046 " (function fun", "(a,b) { infunction; }", ")();", | 1073 " (function fun", "(a,b) { infunction; }", ")();", |
| 1047 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1074 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1048 // Unpaired lead surrogate where following code point is a 4 byte encoding | 1075 // Unpaired lead surrogate where following code point is a 4 byte encoding |
| 1049 // of a trail surrogate. | 1076 // of a trail surrogate. |
| 1050 { " 'foo\355\240\201\360\215\260\211';\n" | 1077 { " 'foo\355\240\201\360\215\260\211';\n" |
| 1051 " (function fun", "(a,b) { infunction; }", ")();", | 1078 " (function fun", "(a,b) { infunction; }", ")();", |
| 1052 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1079 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1053 // Unpaired trail surrogate. | 1080 // Unpaired trail surrogate. |
| 1054 { " 'foo\355\260\211';\n" | 1081 { " 'foo\355\260\211';\n" |
| 1055 " (function fun", "(a,b) { infunction; }", ")();", | 1082 " (function fun", "(a,b) { infunction; }", ")();", |
| 1056 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1083 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1057 // 2 byte encoding of \u00ff. | 1084 // 2 byte encoding of \u00ff. |
| 1058 { " 'foo\303\277';\n" | 1085 { " 'foo\303\277';\n" |
| 1059 " (function fun", "(a,b) { infunction; }", ")();", | 1086 " (function fun", "(a,b) { infunction; }", ")();", |
| 1060 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1087 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1061 // Broken 2 byte encoding of \u00ff with missing last byte. | 1088 // Broken 2 byte encoding of \u00ff with missing last byte. |
| 1062 { " 'foo\303';\n" | 1089 { " 'foo\303';\n" |
| 1063 " (function fun", "(a,b) { infunction; }", ")();", | 1090 " (function fun", "(a,b) { infunction; }", ")();", |
| 1064 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1091 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1065 // Broken 2 byte encoding of \u007f should be a 1 byte encoding. | 1092 // Broken 2 byte encoding of \u007f should be a 1 byte encoding. |
| 1066 { " 'foo\301\277';\n" | 1093 { " 'foo\301\277';\n" |
| 1067 " (function fun", "(a,b) { infunction; }", ")();", | 1094 " (function fun", "(a,b) { infunction; }", ")();", |
| 1068 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1095 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1069 // Illegal 5 byte encoding. | 1096 // Illegal 5 byte encoding. |
| 1070 { " 'foo\370\277\277\277\277';\n" | 1097 { " 'foo\370\277\277\277\277';\n" |
| 1071 " (function fun", "(a,b) { infunction; }", ")();", | 1098 " (function fun", "(a,b) { infunction; }", ")();", |
| 1072 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1099 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1073 // Illegal 6 byte encoding. | 1100 // Illegal 6 byte encoding. |
| 1074 { " 'foo\374\277\277\277\277\277';\n" | 1101 { " 'foo\374\277\277\277\277\277';\n" |
| 1075 " (function fun", "(a,b) { infunction; }", ")();", | 1102 " (function fun", "(a,b) { infunction; }", ")();", |
| 1076 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1103 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1077 // Illegal 0xfe byte | 1104 // Illegal 0xfe byte |
| 1078 { " 'foo\376\277\277\277\277\277\277';\n" | 1105 { " 'foo\376\277\277\277\277\277\277';\n" |
| 1079 " (function fun", "(a,b) { infunction; }", ")();", | 1106 " (function fun", "(a,b) { infunction; }", ")();", |
| 1080 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1107 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1081 // Illegal 0xff byte | 1108 // Illegal 0xff byte |
| 1082 { " 'foo\377\277\277\277\277\277\277\277';\n" | 1109 { " 'foo\377\277\277\277\277\277\277\277';\n" |
| 1083 " (function fun", "(a,b) { infunction; }", ")();", | 1110 " (function fun", "(a,b) { infunction; }", ")();", |
| 1084 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1111 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1085 { " 'foo';\n" | 1112 { " 'foo';\n" |
| 1086 " (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();", | 1113 " (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();", |
| 1087 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1114 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1088 { " 'foo';\n" | 1115 { " 'foo';\n" |
| 1089 " (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();", | 1116 " (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();", |
| 1090 i::FUNCTION_SCOPE, i::CLASSIC_MODE }, | 1117 i::FUNCTION_SCOPE, i::SLOPPY }, |
| 1091 { NULL, NULL, NULL, i::EVAL_SCOPE, i::CLASSIC_MODE } | 1118 { NULL, NULL, NULL, i::EVAL_SCOPE, i::SLOPPY } |
| 1092 }; | 1119 }; |
| 1093 | 1120 |
| 1094 i::Isolate* isolate = CcTest::i_isolate(); | 1121 i::Isolate* isolate = CcTest::i_isolate(); |
| 1095 i::Factory* factory = isolate->factory(); | 1122 i::Factory* factory = isolate->factory(); |
| 1096 | 1123 |
| 1097 v8::HandleScope handles(CcTest::isolate()); | 1124 v8::HandleScope handles(CcTest::isolate()); |
| 1098 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); | 1125 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); |
| 1099 v8::Context::Scope context_scope(context); | 1126 v8::Context::Scope context_scope(context); |
| 1100 | 1127 |
| 1101 int marker; | 1128 int marker; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1120 // Parse program source. | 1147 // Parse program source. |
| 1121 i::Handle<i::String> source( | 1148 i::Handle<i::String> source( |
| 1122 factory->NewStringFromUtf8(i::CStrVector(program.start()))); | 1149 factory->NewStringFromUtf8(i::CStrVector(program.start()))); |
| 1123 CHECK_EQ(source->length(), kProgramSize); | 1150 CHECK_EQ(source->length(), kProgramSize); |
| 1124 i::Handle<i::Script> script = factory->NewScript(source); | 1151 i::Handle<i::Script> script = factory->NewScript(source); |
| 1125 i::CompilationInfoWithZone info(script); | 1152 i::CompilationInfoWithZone info(script); |
| 1126 i::Parser parser(&info); | 1153 i::Parser parser(&info); |
| 1127 parser.set_allow_lazy(true); | 1154 parser.set_allow_lazy(true); |
| 1128 parser.set_allow_harmony_scoping(true); | 1155 parser.set_allow_harmony_scoping(true); |
| 1129 info.MarkAsGlobal(); | 1156 info.MarkAsGlobal(); |
| 1130 info.SetLanguageMode(source_data[i].language_mode); | 1157 info.SetStrictMode(source_data[i].strict_mode); |
| 1131 parser.Parse(); | 1158 parser.Parse(); |
| 1132 CHECK(info.function() != NULL); | 1159 CHECK(info.function() != NULL); |
| 1133 | 1160 |
| 1134 // Check scope types and positions. | 1161 // Check scope types and positions. |
| 1135 i::Scope* scope = info.function()->scope(); | 1162 i::Scope* scope = info.function()->scope(); |
| 1136 CHECK(scope->is_global_scope()); | 1163 CHECK(scope->is_global_scope()); |
| 1137 CHECK_EQ(scope->start_position(), 0); | 1164 CHECK_EQ(scope->start_position(), 0); |
| 1138 CHECK_EQ(scope->end_position(), kProgramSize); | 1165 CHECK_EQ(scope->end_position(), kProgramSize); |
| 1139 CHECK_EQ(scope->inner_scopes()->length(), 1); | 1166 CHECK_EQ(scope->inner_scopes()->length(), 1); |
| 1140 | 1167 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1153 i::Factory* factory = isolate->factory(); | 1180 i::Factory* factory = isolate->factory(); |
| 1154 const char* message = data->BuildMessage(); | 1181 const char* message = data->BuildMessage(); |
| 1155 i::Handle<i::String> format = v8::Utils::OpenHandle( | 1182 i::Handle<i::String> format = v8::Utils::OpenHandle( |
| 1156 *v8::String::NewFromUtf8(CcTest::isolate(), message)); | 1183 *v8::String::NewFromUtf8(CcTest::isolate(), message)); |
| 1157 i::Vector<const char*> args = data->BuildArgs(); | 1184 i::Vector<const char*> args = data->BuildArgs(); |
| 1158 i::Handle<i::JSArray> args_array = factory->NewJSArray(args.length()); | 1185 i::Handle<i::JSArray> args_array = factory->NewJSArray(args.length()); |
| 1159 for (int i = 0; i < args.length(); i++) { | 1186 for (int i = 0; i < args.length(); i++) { |
| 1160 i::JSArray::SetElement( | 1187 i::JSArray::SetElement( |
| 1161 args_array, i, v8::Utils::OpenHandle(*v8::String::NewFromUtf8( | 1188 args_array, i, v8::Utils::OpenHandle(*v8::String::NewFromUtf8( |
| 1162 CcTest::isolate(), args[i])), | 1189 CcTest::isolate(), args[i])), |
| 1163 NONE, i::kNonStrictMode); | 1190 NONE, i::SLOPPY); |
| 1164 } | 1191 } |
| 1165 i::Handle<i::JSObject> builtins(isolate->js_builtins_object()); | 1192 i::Handle<i::JSObject> builtins(isolate->js_builtins_object()); |
| 1166 i::Handle<i::Object> format_fun = | 1193 i::Handle<i::Object> format_fun = |
| 1167 i::GetProperty(builtins, "FormatMessage"); | 1194 i::GetProperty(builtins, "FormatMessage"); |
| 1168 i::Handle<i::Object> arg_handles[] = { format, args_array }; | 1195 i::Handle<i::Object> arg_handles[] = { format, args_array }; |
| 1169 bool has_exception = false; | 1196 bool has_exception = false; |
| 1170 i::Handle<i::Object> result = i::Execution::Call( | 1197 i::Handle<i::Object> result = i::Execution::Call( |
| 1171 isolate, format_fun, builtins, 2, arg_handles, &has_exception); | 1198 isolate, format_fun, builtins, 2, arg_handles, &has_exception); |
| 1172 CHECK(!has_exception); | 1199 CHECK(!has_exception); |
| 1173 CHECK(result->IsString()); | 1200 CHECK(result->IsString()); |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1462 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); | 1489 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); |
| 1463 CHECK(try_catch.HasCaught()); | 1490 CHECK(try_catch.HasCaught()); |
| 1464 v8::String::Utf8Value exception(try_catch.Exception()); | 1491 v8::String::Utf8Value exception(try_catch.Exception()); |
| 1465 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", | 1492 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", |
| 1466 *exception); | 1493 *exception); |
| 1467 } | 1494 } |
| 1468 | 1495 |
| 1469 | 1496 |
| 1470 void RunParserSyncTest(const char* context_data[][2], | 1497 void RunParserSyncTest(const char* context_data[][2], |
| 1471 const char* statement_data[], | 1498 const char* statement_data[], |
| 1472 ParserSyncTestResult result) { | 1499 ParserSyncTestResult result, |
| 1500 const ParserFlag* flags = NULL, |
| 1501 int flags_len = 0) { |
| 1473 v8::HandleScope handles(CcTest::isolate()); | 1502 v8::HandleScope handles(CcTest::isolate()); |
| 1474 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); | 1503 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); |
| 1475 v8::Context::Scope context_scope(context); | 1504 v8::Context::Scope context_scope(context); |
| 1476 | 1505 |
| 1477 int marker; | 1506 int marker; |
| 1478 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 1507 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 1479 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 1508 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
| 1480 | 1509 |
| 1481 static const ParserFlag flags[] = { | 1510 static const ParserFlag default_flags[] = { |
| 1482 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, | 1511 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, |
| 1483 kAllowForOf, kAllowNativesSyntax | 1512 kAllowForOf, kAllowNativesSyntax |
| 1484 }; | 1513 }; |
| 1514 if (!flags) { |
| 1515 flags = default_flags; |
| 1516 flags_len = ARRAY_SIZE(default_flags); |
| 1517 } |
| 1485 for (int i = 0; context_data[i][0] != NULL; ++i) { | 1518 for (int i = 0; context_data[i][0] != NULL; ++i) { |
| 1486 for (int j = 0; statement_data[j] != NULL; ++j) { | 1519 for (int j = 0; statement_data[j] != NULL; ++j) { |
| 1487 int kPrefixLen = i::StrLength(context_data[i][0]); | 1520 int kPrefixLen = i::StrLength(context_data[i][0]); |
| 1488 int kStatementLen = i::StrLength(statement_data[j]); | 1521 int kStatementLen = i::StrLength(statement_data[j]); |
| 1489 int kSuffixLen = i::StrLength(context_data[i][1]); | 1522 int kSuffixLen = i::StrLength(context_data[i][1]); |
| 1490 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen; | 1523 int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen; |
| 1491 | 1524 |
| 1492 // Plug the source code pieces together. | 1525 // Plug the source code pieces together. |
| 1493 i::ScopedVector<char> program(kProgramSize + 1); | 1526 i::ScopedVector<char> program(kProgramSize + 1); |
| 1494 int length = i::OS::SNPrintF(program, | 1527 int length = i::OS::SNPrintF(program, |
| 1495 "%s%s%s", | 1528 "%s%s%s", |
| 1496 context_data[i][0], | 1529 context_data[i][0], |
| 1497 statement_data[j], | 1530 statement_data[j], |
| 1498 context_data[i][1]); | 1531 context_data[i][1]); |
| 1499 CHECK(length == kProgramSize); | 1532 CHECK(length == kProgramSize); |
| 1500 TestParserSync(program.start(), | 1533 TestParserSync(program.start(), |
| 1501 flags, | 1534 flags, |
| 1502 ARRAY_SIZE(flags), | 1535 flags_len, |
| 1503 result); | 1536 result); |
| 1504 } | 1537 } |
| 1505 } | 1538 } |
| 1506 } | 1539 } |
| 1507 | 1540 |
| 1508 | 1541 |
| 1509 TEST(ErrorsEvalAndArguments) { | 1542 TEST(ErrorsEvalAndArguments) { |
| 1510 // Tests that both preparsing and parsing produce the right kind of errors for | 1543 // Tests that both preparsing and parsing produce the right kind of errors for |
| 1511 // using "eval" and "arguments" as identifiers. Without the strict mode, it's | 1544 // using "eval" and "arguments" as identifiers. Without the strict mode, it's |
| 1512 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it | 1545 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1538 "++arguments;", | 1571 "++arguments;", |
| 1539 "eval++;", | 1572 "eval++;", |
| 1540 "arguments++;", | 1573 "arguments++;", |
| 1541 NULL | 1574 NULL |
| 1542 }; | 1575 }; |
| 1543 | 1576 |
| 1544 RunParserSyncTest(context_data, statement_data, kError); | 1577 RunParserSyncTest(context_data, statement_data, kError); |
| 1545 } | 1578 } |
| 1546 | 1579 |
| 1547 | 1580 |
| 1548 TEST(NoErrorsEvalAndArgumentsClassic) { | 1581 TEST(NoErrorsEvalAndArgumentsSloppy) { |
| 1549 // Tests that both preparsing and parsing accept "eval" and "arguments" as | 1582 // Tests that both preparsing and parsing accept "eval" and "arguments" as |
| 1550 // identifiers when needed. | 1583 // identifiers when needed. |
| 1551 const char* context_data[][2] = { | 1584 const char* context_data[][2] = { |
| 1552 { "", "" }, | 1585 { "", "" }, |
| 1553 { "function test_func() {", "}"}, | 1586 { "function test_func() {", "}"}, |
| 1554 { NULL, NULL } | 1587 { NULL, NULL } |
| 1555 }; | 1588 }; |
| 1556 | 1589 |
| 1557 const char* statement_data[] = { | 1590 const char* statement_data[] = { |
| 1558 "var eval;", | 1591 "var eval;", |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1683 "++super;", | 1716 "++super;", |
| 1684 "super++;", | 1717 "super++;", |
| 1685 "function foo super", | 1718 "function foo super", |
| 1686 NULL | 1719 NULL |
| 1687 }; | 1720 }; |
| 1688 | 1721 |
| 1689 RunParserSyncTest(context_data, statement_data, kError); | 1722 RunParserSyncTest(context_data, statement_data, kError); |
| 1690 } | 1723 } |
| 1691 | 1724 |
| 1692 | 1725 |
| 1693 TEST(NoErrorsYieldClassic) { | 1726 TEST(NoErrorsYieldSloppy) { |
| 1694 // In classic mode, it's okay to use "yield" as identifier, *except* inside a | 1727 // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a |
| 1695 // generator (see next test). | 1728 // generator (see next test). |
| 1696 const char* context_data[][2] = { | 1729 const char* context_data[][2] = { |
| 1697 { "", "" }, | 1730 { "", "" }, |
| 1698 { "function is_not_gen() {", "}" }, | 1731 { "function is_not_gen() {", "}" }, |
| 1699 { NULL, NULL } | 1732 { NULL, NULL } |
| 1700 }; | 1733 }; |
| 1701 | 1734 |
| 1702 const char* statement_data[] = { | 1735 const char* statement_data[] = { |
| 1703 "var yield;", | 1736 "var yield;", |
| 1704 "var foo, yield;", | 1737 "var foo, yield;", |
| 1705 "try { } catch (yield) { }", | 1738 "try { } catch (yield) { }", |
| 1706 "function yield() { }", | 1739 "function yield() { }", |
| 1707 "function foo(yield) { }", | 1740 "function foo(yield) { }", |
| 1708 "function foo(bar, yield) { }", | 1741 "function foo(bar, yield) { }", |
| 1709 "yield = 1;", | 1742 "yield = 1;", |
| 1710 "var foo = yield = 1;", | 1743 "var foo = yield = 1;", |
| 1711 "++yield;", | 1744 "++yield;", |
| 1712 "yield++;", | 1745 "yield++;", |
| 1713 NULL | 1746 NULL |
| 1714 }; | 1747 }; |
| 1715 | 1748 |
| 1716 RunParserSyncTest(context_data, statement_data, kSuccess); | 1749 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1717 } | 1750 } |
| 1718 | 1751 |
| 1719 | 1752 |
| 1720 TEST(ErrorsYieldClassicGenerator) { | 1753 TEST(ErrorsYieldSloppyGenerator) { |
| 1721 const char* context_data[][2] = { | 1754 const char* context_data[][2] = { |
| 1722 { "function * is_gen() {", "}" }, | 1755 { "function * is_gen() {", "}" }, |
| 1723 { NULL, NULL } | 1756 { NULL, NULL } |
| 1724 }; | 1757 }; |
| 1725 | 1758 |
| 1726 const char* statement_data[] = { | 1759 const char* statement_data[] = { |
| 1727 "var yield;", | 1760 "var yield;", |
| 1728 "var foo, yield;", | 1761 "var foo, yield;", |
| 1729 "try { } catch (yield) { }", | 1762 "try { } catch (yield) { }", |
| 1730 "function yield() { }", | 1763 "function yield() { }", |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 "function interface() { }", | 1859 "function interface() { }", |
| 1827 "function yield() { }", | 1860 "function yield() { }", |
| 1828 NULL | 1861 NULL |
| 1829 }; | 1862 }; |
| 1830 | 1863 |
| 1831 RunParserSyncTest(context_data, statement_data, kSuccess); | 1864 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1832 } | 1865 } |
| 1833 | 1866 |
| 1834 | 1867 |
| 1835 | 1868 |
| 1836 TEST(ErrorsIllegalWordsAsLabelsClassic) { | 1869 TEST(ErrorsIllegalWordsAsLabelsSloppy) { |
| 1837 // Using future reserved words as labels is always an error. | 1870 // Using future reserved words as labels is always an error. |
| 1838 const char* context_data[][2] = { | 1871 const char* context_data[][2] = { |
| 1839 { "", ""}, | 1872 { "", ""}, |
| 1840 { "function test_func() {", "}" }, | 1873 { "function test_func() {", "}" }, |
| 1841 { NULL, NULL } | 1874 { NULL, NULL } |
| 1842 }; | 1875 }; |
| 1843 | 1876 |
| 1844 const char* statement_data[] = { | 1877 const char* statement_data[] = { |
| 1845 "super: while(true) { break super; }", | 1878 "super: while(true) { break super; }", |
| 1846 NULL | 1879 NULL |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1963 }; | 1996 }; |
| 1964 | 1997 |
| 1965 RunParserSyncTest(context_data, statement_data, kSuccess); | 1998 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 1966 } | 1999 } |
| 1967 | 2000 |
| 1968 | 2001 |
| 1969 TEST(DontRegressPreParserDataSizes) { | 2002 TEST(DontRegressPreParserDataSizes) { |
| 1970 // These tests make sure that PreParser doesn't start producing less data. | 2003 // These tests make sure that PreParser doesn't start producing less data. |
| 1971 | 2004 |
| 1972 v8::V8::Initialize(); | 2005 v8::V8::Initialize(); |
| 1973 | |
| 1974 int marker; | 2006 int marker; |
| 1975 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 2007 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 1976 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); | 2008 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); |
| 1977 | 2009 |
| 1978 struct TestCase { | 2010 struct TestCase { |
| 1979 const char* program; | 2011 const char* program; |
| 1980 int symbols; | 2012 int symbols; |
| 1981 int functions; | 2013 int functions; |
| 1982 } test_cases[] = { | 2014 } test_cases[] = { |
| 1983 // Labels, variables and functions are recorded as symbols. | 2015 // Labels and variables are recorded as symbols. |
| 1984 {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0}, | 2016 {"{label: 42}", 1, 0}, {"{label: 42; label2: 43}", 2, 0}, |
| 1985 {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0}, | 2017 {"var x = 42;", 1, 0}, {"var x = 42, y = 43;", 2, 0}, |
| 2018 {"var x = {y: 1};", 2, 0}, |
| 2019 {"var x = {}; x.y = 1", 2, 0}, |
| 2020 // "get" is recorded as a symbol too. |
| 2021 {"var x = {get foo(){} };", 3, 1}, |
| 2022 // When keywords are used as identifiers, they're logged as symbols, too: |
| 2023 {"var x = {if: 1};", 2, 0}, |
| 2024 {"var x = {}; x.if = 1", 2, 0}, |
| 2025 {"var x = {get if(){} };", 3, 1}, |
| 2026 // Functions |
| 1986 {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2}, | 2027 {"function foo() {}", 1, 1}, {"function foo() {} function bar() {}", 2, 2}, |
| 1987 // Labels, variables and functions insize lazy functions are not recorded. | 2028 // Labels, variables and functions insize lazy functions are not recorded. |
| 1988 {"function lazy() { var a, b, c; }", 1, 1}, | 2029 {"function lazy() { var a, b, c; }", 1, 1}, |
| 1989 {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1}, | 2030 {"function lazy() { a: 1; b: 2; c: 3; }", 1, 1}, |
| 1990 {"function lazy() { function a() {} function b() {} function c() {} }", 1, | 2031 {"function lazy() { function a() {} function b() {} function c() {} }", 1, |
| 1991 1}, | 2032 1}, |
| 1992 {NULL, 0, 0} | 2033 {NULL, 0, 0} |
| 1993 }; | 2034 }; |
| 1994 // Each function adds 5 elements to the preparse function data. | 2035 // Each function adds 5 elements to the preparse function data. |
| 1995 const int kDataPerFunction = 5; | 2036 const int kDataPerFunction = 5; |
| 1996 | 2037 |
| 2038 typedef i::CompleteParserRecorderFriend F; |
| 1997 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 2039 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 1998 for (int i = 0; test_cases[i].program; i++) { | 2040 for (int i = 0; test_cases[i].program; i++) { |
| 1999 const char* program = test_cases[i].program; | 2041 const char* program = test_cases[i].program; |
| 2000 i::Utf8ToUtf16CharacterStream stream( | 2042 i::Utf8ToUtf16CharacterStream stream( |
| 2001 reinterpret_cast<const i::byte*>(program), | 2043 reinterpret_cast<const i::byte*>(program), |
| 2002 static_cast<unsigned>(strlen(program))); | 2044 static_cast<unsigned>(strlen(program))); |
| 2003 i::CompleteParserRecorder log; | 2045 i::CompleteParserRecorder log; |
| 2004 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 2046 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 2005 scanner.Initialize(&stream); | 2047 scanner.Initialize(&stream); |
| 2006 | 2048 |
| 2007 i::PreParser preparser(&scanner, &log, stack_limit); | 2049 i::PreParser preparser(&scanner, &log, stack_limit); |
| 2008 preparser.set_allow_lazy(true); | 2050 preparser.set_allow_lazy(true); |
| 2009 preparser.set_allow_natives_syntax(true); | 2051 preparser.set_allow_natives_syntax(true); |
| 2010 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 2052 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 2011 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 2053 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 2012 if (log.symbol_ids() != test_cases[i].symbols) { | 2054 if (F::symbol_ids(&log) != test_cases[i].symbols) { |
| 2013 i::OS::Print( | 2055 i::OS::Print( |
| 2014 "Expected preparse data for program:\n" | 2056 "Expected preparse data for program:\n" |
| 2015 "\t%s\n" | 2057 "\t%s\n" |
| 2016 "to contain %d symbols, however, received %d symbols.\n", | 2058 "to contain %d symbols, however, received %d symbols.\n", |
| 2017 program, test_cases[i].symbols, log.symbol_ids()); | 2059 program, test_cases[i].symbols, F::symbol_ids(&log)); |
| 2018 CHECK(false); | 2060 CHECK(false); |
| 2019 } | 2061 } |
| 2020 if (log.function_position() != test_cases[i].functions * kDataPerFunction) { | 2062 if (F::function_position(&log) != |
| 2063 test_cases[i].functions * kDataPerFunction) { |
| 2021 i::OS::Print( | 2064 i::OS::Print( |
| 2022 "Expected preparse data for program:\n" | 2065 "Expected preparse data for program:\n" |
| 2023 "\t%s\n" | 2066 "\t%s\n" |
| 2024 "to contain %d functions, however, received %d functions.\n", | 2067 "to contain %d functions, however, received %d functions.\n", |
| 2025 program, test_cases[i].functions, | 2068 program, test_cases[i].functions, |
| 2026 log.function_position() / kDataPerFunction); | 2069 F::function_position(&log) / kDataPerFunction); |
| 2027 CHECK(false); | 2070 CHECK(false); |
| 2028 } | 2071 } |
| 2029 i::ScriptDataImpl data(log.ExtractData()); | 2072 i::ScriptDataImpl data(log.ExtractData()); |
| 2030 CHECK(!data.has_error()); | 2073 CHECK(!data.has_error()); |
| 2031 } | 2074 } |
| 2032 } | 2075 } |
| 2033 | 2076 |
| 2034 | 2077 |
| 2035 TEST(FunctionDeclaresItselfStrict) { | 2078 TEST(FunctionDeclaresItselfStrict) { |
| 2036 // Tests that we produce the right kinds of errors when a function declares | 2079 // Tests that we produce the right kinds of errors when a function declares |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2203 | 2246 |
| 2204 const char* statement_data[] = { | 2247 const char* statement_data[] = { |
| 2205 "new foo bar", | 2248 "new foo bar", |
| 2206 "new ) foo", | 2249 "new ) foo", |
| 2207 "new ++foo", | 2250 "new ++foo", |
| 2208 NULL | 2251 NULL |
| 2209 }; | 2252 }; |
| 2210 | 2253 |
| 2211 RunParserSyncTest(context_data, statement_data, kError); | 2254 RunParserSyncTest(context_data, statement_data, kError); |
| 2212 } | 2255 } |
| 2256 |
| 2257 |
| 2258 TEST(StrictObjectLiteralChecking) { |
| 2259 const char* strict_context_data[][2] = { |
| 2260 {"\"use strict\"; var myobject = {", "};"}, |
| 2261 { NULL, NULL } |
| 2262 }; |
| 2263 const char* non_strict_context_data[][2] = { |
| 2264 {"var myobject = {", "};"}, |
| 2265 { NULL, NULL } |
| 2266 }; |
| 2267 |
| 2268 // These are only errors in strict mode. |
| 2269 const char* statement_data[] = { |
| 2270 "foo: 1, foo: 2", |
| 2271 "\"foo\": 1, \"foo\": 2", |
| 2272 "foo: 1, \"foo\": 2", |
| 2273 "1: 1, 1: 2", |
| 2274 "1: 1, \"1\": 2", |
| 2275 "get: 1, get: 2", // Not a getter for real, just a property called get. |
| 2276 "set: 1, set: 2", // Not a setter for real, just a property called set. |
| 2277 NULL |
| 2278 }; |
| 2279 |
| 2280 RunParserSyncTest(non_strict_context_data, statement_data, kSuccess); |
| 2281 RunParserSyncTest(strict_context_data, statement_data, kError); |
| 2282 } |
| 2283 |
| 2284 |
| 2285 TEST(ErrorsObjectLiteralChecking) { |
| 2286 const char* context_data[][2] = { |
| 2287 {"\"use strict\"; var myobject = {", "};"}, |
| 2288 {"var myobject = {", "};"}, |
| 2289 { NULL, NULL } |
| 2290 }; |
| 2291 |
| 2292 const char* statement_data[] = { |
| 2293 "foo: 1, get foo() {}", |
| 2294 "foo: 1, set foo() {}", |
| 2295 "\"foo\": 1, get \"foo\"() {}", |
| 2296 "\"foo\": 1, set \"foo\"() {}", |
| 2297 "1: 1, get 1() {}", |
| 2298 "1: 1, set 1() {}", |
| 2299 // It's counter-intuitive, but these collide too (even in classic |
| 2300 // mode). Note that we can have "foo" and foo as properties in classic mode, |
| 2301 // but we cannot have "foo" and get foo, or foo and get "foo". |
| 2302 "foo: 1, get \"foo\"() {}", |
| 2303 "foo: 1, set \"foo\"() {}", |
| 2304 "\"foo\": 1, get foo() {}", |
| 2305 "\"foo\": 1, set foo() {}", |
| 2306 "1: 1, get \"1\"() {}", |
| 2307 "1: 1, set \"1\"() {}", |
| 2308 "\"1\": 1, get 1() {}" |
| 2309 "\"1\": 1, set 1() {}" |
| 2310 // Parsing FunctionLiteral for getter or setter fails |
| 2311 "get foo( +", |
| 2312 "get foo() \"error\"", |
| 2313 NULL |
| 2314 }; |
| 2315 |
| 2316 RunParserSyncTest(context_data, statement_data, kError); |
| 2317 } |
| 2318 |
| 2319 |
| 2320 TEST(NoErrorsObjectLiteralChecking) { |
| 2321 const char* context_data[][2] = { |
| 2322 {"var myobject = {", "};"}, |
| 2323 {"\"use strict\"; var myobject = {", "};"}, |
| 2324 { NULL, NULL } |
| 2325 }; |
| 2326 |
| 2327 const char* statement_data[] = { |
| 2328 "foo: 1, bar: 2", |
| 2329 "\"foo\": 1, \"bar\": 2", |
| 2330 "1: 1, 2: 2", |
| 2331 // Syntax: IdentifierName ':' AssignmentExpression |
| 2332 "foo: bar = 5 + baz", |
| 2333 // Syntax: 'get' (IdentifierName | String | Number) FunctionLiteral |
| 2334 "get foo() {}", |
| 2335 "get \"foo\"() {}", |
| 2336 "get 1() {}", |
| 2337 // Syntax: 'set' (IdentifierName | String | Number) FunctionLiteral |
| 2338 "set foo() {}", |
| 2339 "set \"foo\"() {}", |
| 2340 "set 1() {}", |
| 2341 // Non-colliding getters and setters -> no errors |
| 2342 "foo: 1, get bar() {}", |
| 2343 "foo: 1, set bar(b) {}", |
| 2344 "\"foo\": 1, get \"bar\"() {}", |
| 2345 "\"foo\": 1, set \"bar\"() {}", |
| 2346 "1: 1, get 2() {}", |
| 2347 "1: 1, set 2() {}", |
| 2348 // Weird number of parameters -> no errors |
| 2349 "get bar() {}, set bar() {}", |
| 2350 "get bar(x) {}, set bar(x) {}", |
| 2351 "get bar(x, y) {}, set bar(x, y) {}", |
| 2352 // Keywords, future reserved and strict future reserved are also allowed as |
| 2353 // property names. |
| 2354 "if: 4", |
| 2355 "interface: 5", |
| 2356 "super: 6", |
| 2357 "eval: 7", |
| 2358 "arguments: 8", |
| 2359 NULL |
| 2360 }; |
| 2361 |
| 2362 RunParserSyncTest(context_data, statement_data, kSuccess); |
| 2363 } |
| 2364 |
| 2365 |
| 2366 TEST(TooManyArguments) { |
| 2367 const char* context_data[][2] = { |
| 2368 {"foo(", "0)"}, |
| 2369 { NULL, NULL } |
| 2370 }; |
| 2371 |
| 2372 using v8::internal::Code; |
| 2373 char statement[Code::kMaxArguments * 2 + 1]; |
| 2374 for (int i = 0; i < Code::kMaxArguments; ++i) { |
| 2375 statement[2 * i] = '0'; |
| 2376 statement[2 * i + 1] = ','; |
| 2377 } |
| 2378 statement[Code::kMaxArguments * 2] = 0; |
| 2379 |
| 2380 const char* statement_data[] = { |
| 2381 statement, |
| 2382 NULL |
| 2383 }; |
| 2384 |
| 2385 // The test is quite slow, so run it with a reduced set of flags. |
| 2386 static const ParserFlag empty_flags[] = {kAllowLazy}; |
| 2387 RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1); |
| 2388 } |
| OLD | NEW |