| 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 |