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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 | 57 |
58 static const KeywordToken keywords[] = { | 58 static const KeywordToken keywords[] = { |
59 #define KEYWORD(t, s, d) { s, i::Token::t }, | 59 #define KEYWORD(t, s, d) { s, i::Token::t }, |
60 TOKEN_LIST(IGNORE_TOKEN, KEYWORD) | 60 TOKEN_LIST(IGNORE_TOKEN, KEYWORD) |
61 #undef KEYWORD | 61 #undef KEYWORD |
62 { NULL, i::Token::IDENTIFIER } | 62 { NULL, i::Token::IDENTIFIER } |
63 }; | 63 }; |
64 | 64 |
65 KeywordToken key_token; | 65 KeywordToken key_token; |
66 i::UnicodeCache unicode_cache; | 66 i::UnicodeCache unicode_cache; |
67 i::byte buffer[32]; | 67 char buffer[32]; |
68 for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) { | 68 for (int i = 0; (key_token = keywords[i]).keyword != NULL; i++) { |
69 const i::byte* keyword = | 69 const char* keyword = key_token.keyword; |
70 reinterpret_cast<const i::byte*>(key_token.keyword); | 70 size_t length = strlen(key_token.keyword); |
71 int length = i::StrLength(key_token.keyword); | |
72 CHECK(static_cast<int>(sizeof(buffer)) >= length); | 71 CHECK(static_cast<int>(sizeof(buffer)) >= length); |
73 { | 72 { |
74 i::Utf8ToUtf16CharacterStream stream(keyword, length); | 73 i::ExternalOneByteStringUtf16CharacterStream stream(keyword, length); |
75 i::Scanner scanner(&unicode_cache); | 74 i::Scanner scanner(&unicode_cache); |
76 scanner.Initialize(&stream); | 75 scanner.Initialize(&stream); |
77 CHECK_EQ(key_token.token, scanner.Next()); | 76 CHECK_EQ(key_token.token, scanner.Next()); |
78 CHECK_EQ(i::Token::EOS, scanner.Next()); | 77 CHECK_EQ(i::Token::EOS, scanner.Next()); |
79 } | 78 } |
80 // Removing characters will make keyword matching fail. | 79 // Removing characters will make keyword matching fail. |
81 { | 80 { |
82 i::Utf8ToUtf16CharacterStream stream(keyword, length - 1); | 81 i::ExternalOneByteStringUtf16CharacterStream stream(keyword, length - 1); |
83 i::Scanner scanner(&unicode_cache); | 82 i::Scanner scanner(&unicode_cache); |
84 scanner.Initialize(&stream); | 83 scanner.Initialize(&stream); |
85 CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); | 84 CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); |
86 CHECK_EQ(i::Token::EOS, scanner.Next()); | 85 CHECK_EQ(i::Token::EOS, scanner.Next()); |
87 } | 86 } |
88 // Adding characters will make keyword matching fail. | 87 // Adding characters will make keyword matching fail. |
89 static const char chars_to_append[] = { 'z', '0', '_' }; | 88 static const char chars_to_append[] = { 'z', '0', '_' }; |
90 for (int j = 0; j < static_cast<int>(arraysize(chars_to_append)); ++j) { | 89 for (int j = 0; j < static_cast<int>(arraysize(chars_to_append)); ++j) { |
91 i::MemMove(buffer, keyword, length); | 90 i::MemMove(buffer, keyword, length); |
92 buffer[length] = chars_to_append[j]; | 91 buffer[length] = chars_to_append[j]; |
93 i::Utf8ToUtf16CharacterStream stream(buffer, length + 1); | 92 i::ExternalOneByteStringUtf16CharacterStream stream(buffer, length + 1); |
94 i::Scanner scanner(&unicode_cache); | 93 i::Scanner scanner(&unicode_cache); |
95 scanner.Initialize(&stream); | 94 scanner.Initialize(&stream); |
96 CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); | 95 CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); |
97 CHECK_EQ(i::Token::EOS, scanner.Next()); | 96 CHECK_EQ(i::Token::EOS, scanner.Next()); |
98 } | 97 } |
99 // Replacing characters will make keyword matching fail. | 98 // Replacing characters will make keyword matching fail. |
100 { | 99 { |
101 i::MemMove(buffer, keyword, length); | 100 i::MemMove(buffer, keyword, length); |
102 buffer[length - 1] = '_'; | 101 buffer[length - 1] = '_'; |
103 i::Utf8ToUtf16CharacterStream stream(buffer, length); | 102 i::ExternalOneByteStringUtf16CharacterStream stream(buffer, length); |
104 i::Scanner scanner(&unicode_cache); | 103 i::Scanner scanner(&unicode_cache); |
105 scanner.Initialize(&stream); | 104 scanner.Initialize(&stream); |
106 CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); | 105 CHECK_EQ(i::Token::IDENTIFIER, scanner.Next()); |
107 CHECK_EQ(i::Token::EOS, scanner.Next()); | 106 CHECK_EQ(i::Token::EOS, scanner.Next()); |
108 } | 107 } |
109 } | 108 } |
110 } | 109 } |
111 | 110 |
112 | 111 |
113 TEST(ScanHTMLEndComments) { | 112 TEST(ScanHTMLEndComments) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 "var x = 42; --> is eol-comment\nvar y = 37;\n", | 157 "var x = 42; --> is eol-comment\nvar y = 37;\n", |
159 NULL | 158 NULL |
160 }; | 159 }; |
161 // clang-format on | 160 // clang-format on |
162 | 161 |
163 // Parser/Scanner needs a stack limit. | 162 // Parser/Scanner needs a stack limit. |
164 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 163 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
165 i::GetCurrentStackPosition() - 128 * 1024); | 164 i::GetCurrentStackPosition() - 128 * 1024); |
166 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 165 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
167 for (int i = 0; tests[i]; i++) { | 166 for (int i = 0; tests[i]; i++) { |
168 const i::byte* source = | 167 const char* source = tests[i]; |
169 reinterpret_cast<const i::byte*>(tests[i]); | 168 i::ExternalOneByteStringUtf16CharacterStream stream(source); |
170 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i])); | |
171 i::CompleteParserRecorder log; | 169 i::CompleteParserRecorder log; |
172 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 170 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
173 scanner.Initialize(&stream); | 171 scanner.Initialize(&stream); |
174 i::Zone zone(CcTest::i_isolate()->allocator()); | 172 i::Zone zone(CcTest::i_isolate()->allocator()); |
175 i::AstValueFactory ast_value_factory( | 173 i::AstValueFactory ast_value_factory( |
176 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 174 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
177 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 175 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
178 stack_limit); | 176 stack_limit); |
179 preparser.set_allow_lazy(true); | 177 preparser.set_allow_lazy(true); |
180 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 178 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
181 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 179 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
182 CHECK(!log.HasError()); | 180 CHECK(!log.HasError()); |
183 } | 181 } |
184 | 182 |
185 for (int i = 0; fail_tests[i]; i++) { | 183 for (int i = 0; fail_tests[i]; i++) { |
186 const i::byte* source = | 184 const char* source = fail_tests[i]; |
187 reinterpret_cast<const i::byte*>(fail_tests[i]); | 185 i::ExternalOneByteStringUtf16CharacterStream stream(source); |
188 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i])); | |
189 i::CompleteParserRecorder log; | 186 i::CompleteParserRecorder log; |
190 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 187 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
191 scanner.Initialize(&stream); | 188 scanner.Initialize(&stream); |
192 i::Zone zone(CcTest::i_isolate()->allocator()); | 189 i::Zone zone(CcTest::i_isolate()->allocator()); |
193 i::AstValueFactory ast_value_factory( | 190 i::AstValueFactory ast_value_factory( |
194 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 191 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
195 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 192 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
196 stack_limit); | 193 stack_limit); |
197 preparser.set_allow_lazy(true); | 194 preparser.set_allow_lazy(true); |
198 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 195 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 "function foo(x, y) { return x + y; }", | 333 "function foo(x, y) { return x + y; }", |
337 "%ArgleBargle(glop);", | 334 "%ArgleBargle(glop);", |
338 "var x = new new Function('this.x = 42');", | 335 "var x = new new Function('this.x = 42');", |
339 "var f = (x, y) => x + y;", | 336 "var f = (x, y) => x + y;", |
340 NULL | 337 NULL |
341 }; | 338 }; |
342 | 339 |
343 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 340 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
344 for (int i = 0; programs[i]; i++) { | 341 for (int i = 0; programs[i]; i++) { |
345 const char* program = programs[i]; | 342 const char* program = programs[i]; |
346 i::Utf8ToUtf16CharacterStream stream( | 343 i::ExternalOneByteStringUtf16CharacterStream stream(program); |
347 reinterpret_cast<const i::byte*>(program), | |
348 static_cast<unsigned>(strlen(program))); | |
349 i::CompleteParserRecorder log; | 344 i::CompleteParserRecorder log; |
350 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 345 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
351 scanner.Initialize(&stream); | 346 scanner.Initialize(&stream); |
352 | 347 |
353 i::Zone zone(CcTest::i_isolate()->allocator()); | 348 i::Zone zone(CcTest::i_isolate()->allocator()); |
354 i::AstValueFactory ast_value_factory( | 349 i::AstValueFactory ast_value_factory( |
355 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 350 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
356 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 351 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
357 stack_limit); | 352 stack_limit); |
358 preparser.set_allow_lazy(true); | 353 preparser.set_allow_lazy(true); |
(...skipping 13 matching lines...) Expand all Loading... |
372 | 367 |
373 const char* programs[] = { | 368 const char* programs[] = { |
374 "%ArgleBargle(glop);", | 369 "%ArgleBargle(glop);", |
375 "var x = %_IsSmi(42);", | 370 "var x = %_IsSmi(42);", |
376 NULL | 371 NULL |
377 }; | 372 }; |
378 | 373 |
379 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 374 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
380 for (int i = 0; programs[i]; i++) { | 375 for (int i = 0; programs[i]; i++) { |
381 const char* program = programs[i]; | 376 const char* program = programs[i]; |
382 i::Utf8ToUtf16CharacterStream stream( | 377 i::ExternalOneByteStringUtf16CharacterStream stream(program); |
383 reinterpret_cast<const i::byte*>(program), | |
384 static_cast<unsigned>(strlen(program))); | |
385 i::CompleteParserRecorder log; | 378 i::CompleteParserRecorder log; |
386 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 379 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
387 scanner.Initialize(&stream); | 380 scanner.Initialize(&stream); |
388 | 381 |
389 // Preparser defaults to disallowing natives syntax. | 382 // Preparser defaults to disallowing natives syntax. |
390 i::Zone zone(CcTest::i_isolate()->allocator()); | 383 i::Zone zone(CcTest::i_isolate()->allocator()); |
391 i::AstValueFactory ast_value_factory( | 384 i::AstValueFactory ast_value_factory( |
392 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 385 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
393 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 386 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
394 stack_limit); | 387 stack_limit); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - | 436 isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - |
444 128 * 1024); | 437 128 * 1024); |
445 | 438 |
446 const char* program = "var x = 'something';\n" | 439 const char* program = "var x = 'something';\n" |
447 "escape: function() {}"; | 440 "escape: function() {}"; |
448 // Fails parsing expecting an identifier after "function". | 441 // Fails parsing expecting an identifier after "function". |
449 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), | 442 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), |
450 // and then used the invalid currently scanned literal. This always | 443 // and then used the invalid currently scanned literal. This always |
451 // failed in debug mode, and sometimes crashed in release mode. | 444 // failed in debug mode, and sometimes crashed in release mode. |
452 | 445 |
453 i::Utf8ToUtf16CharacterStream stream( | 446 i::ExternalOneByteStringUtf16CharacterStream stream(program); |
454 reinterpret_cast<const i::byte*>(program), | |
455 static_cast<unsigned>(strlen(program))); | |
456 i::CompleteParserRecorder log; | 447 i::CompleteParserRecorder log; |
457 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 448 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
458 scanner.Initialize(&stream); | 449 scanner.Initialize(&stream); |
459 i::Zone zone(CcTest::i_isolate()->allocator()); | 450 i::Zone zone(CcTest::i_isolate()->allocator()); |
460 i::AstValueFactory ast_value_factory(&zone, | 451 i::AstValueFactory ast_value_factory(&zone, |
461 CcTest::i_isolate()->heap()->HashSeed()); | 452 CcTest::i_isolate()->heap()->HashSeed()); |
462 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 453 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
463 CcTest::i_isolate()->stack_guard()->real_climit()); | 454 CcTest::i_isolate()->stack_guard()->real_climit()); |
464 preparser.set_allow_lazy(true); | 455 preparser.set_allow_lazy(true); |
465 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 456 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 520 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
530 i::GetCurrentStackPosition() - 128 * 1024); | 521 i::GetCurrentStackPosition() - 128 * 1024); |
531 | 522 |
532 size_t kProgramSize = 1024 * 1024; | 523 size_t kProgramSize = 1024 * 1024; |
533 std::unique_ptr<char[]> program(i::NewArray<char>(kProgramSize + 1)); | 524 std::unique_ptr<char[]> program(i::NewArray<char>(kProgramSize + 1)); |
534 memset(program.get(), '(', kProgramSize); | 525 memset(program.get(), '(', kProgramSize); |
535 program[kProgramSize] = '\0'; | 526 program[kProgramSize] = '\0'; |
536 | 527 |
537 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 528 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
538 | 529 |
539 i::Utf8ToUtf16CharacterStream stream( | 530 i::ExternalOneByteStringUtf16CharacterStream stream(program.get(), |
540 reinterpret_cast<const i::byte*>(program.get()), | 531 kProgramSize); |
541 static_cast<unsigned>(kProgramSize)); | |
542 i::CompleteParserRecorder log; | 532 i::CompleteParserRecorder log; |
543 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 533 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
544 scanner.Initialize(&stream); | 534 scanner.Initialize(&stream); |
545 | 535 |
546 i::Zone zone(CcTest::i_isolate()->allocator()); | 536 i::Zone zone(CcTest::i_isolate()->allocator()); |
547 i::AstValueFactory ast_value_factory(&zone, | 537 i::AstValueFactory ast_value_factory(&zone, |
548 CcTest::i_isolate()->heap()->HashSeed()); | 538 CcTest::i_isolate()->heap()->HashSeed()); |
549 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 539 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, |
550 stack_limit); | 540 stack_limit); |
551 preparser.set_allow_lazy(true); | 541 preparser.set_allow_lazy(true); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 factory->NewExternalStringFromOneByte(&one_byte_resource) | 589 factory->NewExternalStringFromOneByte(&one_byte_resource) |
600 .ToHandleChecked()); | 590 .ToHandleChecked()); |
601 | 591 |
602 i::ExternalTwoByteStringUtf16CharacterStream uc16_stream( | 592 i::ExternalTwoByteStringUtf16CharacterStream uc16_stream( |
603 i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end); | 593 i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end); |
604 i::ExternalOneByteStringUtf16CharacterStream one_byte_stream( | 594 i::ExternalOneByteStringUtf16CharacterStream one_byte_stream( |
605 i::Handle<i::ExternalOneByteString>::cast(ext_one_byte_string), start, | 595 i::Handle<i::ExternalOneByteString>::cast(ext_one_byte_string), start, |
606 end); | 596 end); |
607 i::GenericStringUtf16CharacterStream string_stream(one_byte_string, start, | 597 i::GenericStringUtf16CharacterStream string_stream(one_byte_string, start, |
608 end); | 598 end); |
609 i::Utf8ToUtf16CharacterStream utf8_stream( | 599 i::ExternalOneByteStringUtf16CharacterStream utf8_stream(one_byte_source, |
610 reinterpret_cast<const i::byte*>(one_byte_source), end); | 600 end); |
611 utf8_stream.SeekForward(start); | 601 utf8_stream.SeekForward(start); |
612 | 602 |
613 unsigned i = start; | 603 unsigned i = start; |
614 while (i < end) { | 604 while (i < end) { |
615 // Read streams one char at a time | 605 // Read streams one char at a time |
616 CHECK_EQU(i, uc16_stream.pos()); | 606 CHECK_EQU(i, uc16_stream.pos()); |
617 CHECK_EQU(i, string_stream.pos()); | 607 CHECK_EQU(i, string_stream.pos()); |
618 CHECK_EQU(i, utf8_stream.pos()); | 608 CHECK_EQU(i, utf8_stream.pos()); |
619 CHECK_EQU(i, one_byte_stream.pos()); | 609 CHECK_EQU(i, one_byte_stream.pos()); |
620 int32_t c0 = one_byte_source[i]; | 610 int32_t c0 = one_byte_source[i]; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 int32_t c1 = uc16_stream.Advance(); | 697 int32_t c1 = uc16_stream.Advance(); |
708 int32_t c2 = string_stream.Advance(); | 698 int32_t c2 = string_stream.Advance(); |
709 int32_t c3 = utf8_stream.Advance(); | 699 int32_t c3 = utf8_stream.Advance(); |
710 int32_t c4 = one_byte_stream.Advance(); | 700 int32_t c4 = one_byte_stream.Advance(); |
711 CHECK_LT(c1, 0); | 701 CHECK_LT(c1, 0); |
712 CHECK_LT(c2, 0); | 702 CHECK_LT(c2, 0); |
713 CHECK_LT(c3, 0); | 703 CHECK_LT(c3, 0); |
714 CHECK_LT(c4, 0); | 704 CHECK_LT(c4, 0); |
715 } | 705 } |
716 | 706 |
| 707 #undef CHECK_EQU |
717 | 708 |
718 TEST(CharacterStreams) { | 709 TEST(CharacterStreams) { |
719 v8::Isolate* isolate = CcTest::isolate(); | 710 v8::Isolate* isolate = CcTest::isolate(); |
720 v8::HandleScope handles(isolate); | 711 v8::HandleScope handles(isolate); |
721 v8::Local<v8::Context> context = v8::Context::New(isolate); | 712 v8::Local<v8::Context> context = v8::Context::New(isolate); |
722 v8::Context::Scope context_scope(context); | 713 v8::Context::Scope context_scope(context); |
723 | 714 |
724 TestCharacterStream("abc\0\n\r\x7f", 7); | 715 TestCharacterStream("abc\0\n\r\x7f", 7); |
725 static const unsigned kBigStringSize = 4096; | 716 static const unsigned kBigStringSize = 4096; |
726 char buffer[kBigStringSize + 1]; | 717 char buffer[kBigStringSize + 1]; |
727 for (unsigned i = 0; i < kBigStringSize; i++) { | 718 for (unsigned i = 0; i < kBigStringSize; i++) { |
728 buffer[i] = static_cast<char>(i & 0x7f); | 719 buffer[i] = static_cast<char>(i & 0x7f); |
729 } | 720 } |
730 TestCharacterStream(buffer, kBigStringSize); | 721 TestCharacterStream(buffer, kBigStringSize); |
731 | 722 |
732 TestCharacterStream(buffer, kBigStringSize, 576, 3298); | 723 TestCharacterStream(buffer, kBigStringSize, 576, 3298); |
733 | 724 |
734 TestCharacterStream("\0", 1); | 725 TestCharacterStream("\0", 1); |
735 TestCharacterStream("", 0); | 726 TestCharacterStream("", 0); |
736 } | 727 } |
737 | 728 |
738 | 729 |
739 TEST(Utf8CharacterStream) { | |
740 static const unsigned kMaxUC16CharU = unibrow::Utf8::kMaxThreeByteChar; | |
741 static const int kMaxUC16Char = static_cast<int>(kMaxUC16CharU); | |
742 | |
743 static const int kAllUtf8CharsSize = | |
744 (unibrow::Utf8::kMaxOneByteChar + 1) + | |
745 (unibrow::Utf8::kMaxTwoByteChar - unibrow::Utf8::kMaxOneByteChar) * 2 + | |
746 (unibrow::Utf8::kMaxThreeByteChar - unibrow::Utf8::kMaxTwoByteChar) * 3; | |
747 static const unsigned kAllUtf8CharsSizeU = | |
748 static_cast<unsigned>(kAllUtf8CharsSize); | |
749 | |
750 char buffer[kAllUtf8CharsSizeU]; | |
751 unsigned cursor = 0; | |
752 for (int i = 0; i <= kMaxUC16Char; i++) { | |
753 cursor += unibrow::Utf8::Encode(buffer + cursor, i, | |
754 unibrow::Utf16::kNoPreviousCharacter, true); | |
755 } | |
756 CHECK(cursor == kAllUtf8CharsSizeU); | |
757 | |
758 i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer), | |
759 kAllUtf8CharsSizeU); | |
760 int32_t bad = unibrow::Utf8::kBadChar; | |
761 for (int i = 0; i <= kMaxUC16Char; i++) { | |
762 CHECK_EQU(i, stream.pos()); | |
763 int32_t c = stream.Advance(); | |
764 if (i >= 0xd800 && i <= 0xdfff) { | |
765 CHECK_EQ(bad, c); | |
766 } else { | |
767 CHECK_EQ(i, c); | |
768 } | |
769 CHECK_EQU(i + 1, stream.pos()); | |
770 } | |
771 for (int i = kMaxUC16Char; i >= 0; i--) { | |
772 CHECK_EQU(i + 1, stream.pos()); | |
773 stream.PushBack(i); | |
774 CHECK_EQU(i, stream.pos()); | |
775 } | |
776 int i = 0; | |
777 while (stream.pos() < kMaxUC16CharU) { | |
778 CHECK_EQU(i, stream.pos()); | |
779 int progress = static_cast<int>(stream.SeekForward(12)); | |
780 i += progress; | |
781 int32_t c = stream.Advance(); | |
782 if (i >= 0xd800 && i <= 0xdfff) { | |
783 CHECK_EQ(bad, c); | |
784 } else if (i <= kMaxUC16Char) { | |
785 CHECK_EQ(i, c); | |
786 } else { | |
787 CHECK_EQ(-1, c); | |
788 } | |
789 i += 1; | |
790 CHECK_EQU(i, stream.pos()); | |
791 } | |
792 } | |
793 | |
794 #undef CHECK_EQU | |
795 | |
796 void TestStreamScanner(i::Utf16CharacterStream* stream, | 730 void TestStreamScanner(i::Utf16CharacterStream* stream, |
797 i::Token::Value* expected_tokens, | 731 i::Token::Value* expected_tokens, |
798 int skip_pos = 0, // Zero means not skipping. | 732 int skip_pos = 0, // Zero means not skipping. |
799 int skip_to = 0) { | 733 int skip_to = 0) { |
800 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 734 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
801 scanner.Initialize(stream); | 735 scanner.Initialize(stream); |
802 | 736 |
803 int i = 0; | 737 int i = 0; |
804 do { | 738 do { |
805 i::Token::Value expected = expected_tokens[i]; | 739 i::Token::Value expected = expected_tokens[i]; |
806 i::Token::Value actual = scanner.Next(); | 740 i::Token::Value actual = scanner.Next(); |
807 CHECK_EQ(i::Token::String(expected), i::Token::String(actual)); | 741 CHECK_EQ(i::Token::String(expected), i::Token::String(actual)); |
808 if (scanner.location().end_pos == skip_pos) { | 742 if (scanner.location().end_pos == skip_pos) { |
809 scanner.SeekForward(skip_to); | 743 scanner.SeekForward(skip_to); |
810 } | 744 } |
811 i++; | 745 i++; |
812 } while (expected_tokens[i] != i::Token::ILLEGAL); | 746 } while (expected_tokens[i] != i::Token::ILLEGAL); |
813 } | 747 } |
814 | 748 |
815 | 749 |
816 TEST(StreamScanner) { | 750 TEST(StreamScanner) { |
817 v8::V8::Initialize(); | 751 v8::V8::Initialize(); |
818 | 752 |
819 const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib"; | 753 const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib"; |
820 i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1), | 754 i::ExternalOneByteStringUtf16CharacterStream stream1(str1); |
821 static_cast<unsigned>(strlen(str1))); | |
822 i::Token::Value expectations1[] = { | 755 i::Token::Value expectations1[] = { |
823 i::Token::LBRACE, | 756 i::Token::LBRACE, |
824 i::Token::IDENTIFIER, | 757 i::Token::IDENTIFIER, |
825 i::Token::IDENTIFIER, | 758 i::Token::IDENTIFIER, |
826 i::Token::FOR, | 759 i::Token::FOR, |
827 i::Token::COLON, | 760 i::Token::COLON, |
828 i::Token::MUL, | 761 i::Token::MUL, |
829 i::Token::DIV, | 762 i::Token::DIV, |
830 i::Token::LT, | 763 i::Token::LT, |
831 i::Token::SUB, | 764 i::Token::SUB, |
832 i::Token::IDENTIFIER, | 765 i::Token::IDENTIFIER, |
833 i::Token::EOS, | 766 i::Token::EOS, |
834 i::Token::ILLEGAL | 767 i::Token::ILLEGAL |
835 }; | 768 }; |
836 TestStreamScanner(&stream1, expectations1, 0, 0); | 769 TestStreamScanner(&stream1, expectations1, 0, 0); |
837 | 770 |
838 const char* str2 = "case default const {THIS\nPART\nSKIPPED} do"; | 771 const char* str2 = "case default const {THIS\nPART\nSKIPPED} do"; |
839 i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2), | 772 i::ExternalOneByteStringUtf16CharacterStream stream2(str2); |
840 static_cast<unsigned>(strlen(str2))); | |
841 i::Token::Value expectations2[] = { | 773 i::Token::Value expectations2[] = { |
842 i::Token::CASE, | 774 i::Token::CASE, |
843 i::Token::DEFAULT, | 775 i::Token::DEFAULT, |
844 i::Token::CONST, | 776 i::Token::CONST, |
845 i::Token::LBRACE, | 777 i::Token::LBRACE, |
846 // Skipped part here | 778 // Skipped part here |
847 i::Token::RBRACE, | 779 i::Token::RBRACE, |
848 i::Token::DO, | 780 i::Token::DO, |
849 i::Token::EOS, | 781 i::Token::EOS, |
850 i::Token::ILLEGAL | 782 i::Token::ILLEGAL |
851 }; | 783 }; |
852 CHECK_EQ('{', str2[19]); | 784 CHECK_EQ('{', str2[19]); |
853 CHECK_EQ('}', str2[37]); | 785 CHECK_EQ('}', str2[37]); |
854 TestStreamScanner(&stream2, expectations2, 20, 37); | 786 TestStreamScanner(&stream2, expectations2, 20, 37); |
855 | 787 |
856 const char* str3 = "{}}}}"; | 788 const char* str3 = "{}}}}"; |
857 i::Token::Value expectations3[] = { | 789 i::Token::Value expectations3[] = { |
858 i::Token::LBRACE, | 790 i::Token::LBRACE, |
859 i::Token::RBRACE, | 791 i::Token::RBRACE, |
860 i::Token::RBRACE, | 792 i::Token::RBRACE, |
861 i::Token::RBRACE, | 793 i::Token::RBRACE, |
862 i::Token::RBRACE, | 794 i::Token::RBRACE, |
863 i::Token::EOS, | 795 i::Token::EOS, |
864 i::Token::ILLEGAL | 796 i::Token::ILLEGAL |
865 }; | 797 }; |
866 // Skip zero-four RBRACEs. | 798 // Skip zero-four RBRACEs. |
867 for (int i = 0; i <= 4; i++) { | 799 for (int i = 0; i <= 4; i++) { |
868 expectations3[6 - i] = i::Token::ILLEGAL; | 800 expectations3[6 - i] = i::Token::ILLEGAL; |
869 expectations3[5 - i] = i::Token::EOS; | 801 expectations3[5 - i] = i::Token::EOS; |
870 i::Utf8ToUtf16CharacterStream stream3( | 802 i::ExternalOneByteStringUtf16CharacterStream stream3(str3); |
871 reinterpret_cast<const i::byte*>(str3), | |
872 static_cast<unsigned>(strlen(str3))); | |
873 TestStreamScanner(&stream3, expectations3, 1, 1 + i); | 803 TestStreamScanner(&stream3, expectations3, 1, 1 + i); |
874 } | 804 } |
875 } | 805 } |
876 | 806 |
877 | 807 |
878 void TestScanRegExp(const char* re_source, const char* expected) { | 808 void TestScanRegExp(const char* re_source, const char* expected) { |
879 i::Utf8ToUtf16CharacterStream stream( | 809 i::ExternalOneByteStringUtf16CharacterStream stream(re_source); |
880 reinterpret_cast<const i::byte*>(re_source), | |
881 static_cast<unsigned>(strlen(re_source))); | |
882 i::HandleScope scope(CcTest::i_isolate()); | 810 i::HandleScope scope(CcTest::i_isolate()); |
883 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 811 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
884 scanner.Initialize(&stream); | 812 scanner.Initialize(&stream); |
885 | 813 |
886 i::Token::Value start = scanner.peek(); | 814 i::Token::Value start = scanner.peek(); |
887 CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); | 815 CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV); |
888 CHECK(scanner.ScanRegExpPattern()); | 816 CHECK(scanner.ScanRegExpPattern()); |
889 scanner.Next(); // Current token is now the regexp literal. | 817 scanner.Next(); // Current token is now the regexp literal. |
890 i::Zone zone(CcTest::i_isolate()->allocator()); | 818 i::Zone zone(CcTest::i_isolate()->allocator()); |
891 i::AstValueFactory ast_value_factory(&zone, | 819 i::AstValueFactory ast_value_factory(&zone, |
(...skipping 7249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8141 "(a,);", | 8069 "(a,);", |
8142 "(a,b,c,);", | 8070 "(a,b,c,);", |
8143 NULL | 8071 NULL |
8144 }; | 8072 }; |
8145 // clang-format on | 8073 // clang-format on |
8146 | 8074 |
8147 static const ParserFlag always_flags[] = {kAllowHarmonyTrailingCommas}; | 8075 static const ParserFlag always_flags[] = {kAllowHarmonyTrailingCommas}; |
8148 RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, | 8076 RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, |
8149 arraysize(always_flags)); | 8077 arraysize(always_flags)); |
8150 } | 8078 } |
OLD | NEW |