| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 }; | 161 }; |
| 162 // clang-format on | 162 // clang-format on |
| 163 | 163 |
| 164 // Parser/Scanner needs a stack limit. | 164 // Parser/Scanner needs a stack limit. |
| 165 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 165 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 166 i::GetCurrentStackPosition() - 128 * 1024); | 166 i::GetCurrentStackPosition() - 128 * 1024); |
| 167 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 167 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 168 for (int i = 0; tests[i]; i++) { | 168 for (int i = 0; tests[i]; i++) { |
| 169 const char* source = tests[i]; | 169 const char* source = tests[i]; |
| 170 auto stream = i::ScannerStream::ForTesting(source); | 170 auto stream = i::ScannerStream::ForTesting(source); |
| 171 i::CompleteParserRecorder log; | |
| 172 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 171 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 173 scanner.Initialize(stream.get()); | 172 scanner.Initialize(stream.get()); |
| 174 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 173 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 175 i::AstValueFactory ast_value_factory( | 174 i::AstValueFactory ast_value_factory( |
| 176 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 175 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 177 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 176 i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit); |
| 178 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(!preparser.logger()->has_error()); |
| 183 } | 181 } |
| 184 | 182 |
| 185 for (int i = 0; fail_tests[i]; i++) { | 183 for (int i = 0; fail_tests[i]; i++) { |
| 186 const char* source = fail_tests[i]; | 184 const char* source = fail_tests[i]; |
| 187 auto stream = i::ScannerStream::ForTesting(source); | 185 auto stream = i::ScannerStream::ForTesting(source); |
| 188 i::CompleteParserRecorder log; | |
| 189 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 186 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 190 scanner.Initialize(stream.get()); | 187 scanner.Initialize(stream.get()); |
| 191 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 188 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 192 i::AstValueFactory ast_value_factory( | 189 i::AstValueFactory ast_value_factory( |
| 193 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 190 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 194 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 191 i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit); |
| 195 stack_limit); | |
| 196 preparser.set_allow_lazy(true); | 192 preparser.set_allow_lazy(true); |
| 197 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 193 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 198 // Even in the case of a syntax error, kPreParseSuccess is returned. | 194 // Even in the case of a syntax error, kPreParseSuccess is returned. |
| 199 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 195 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 200 CHECK(log.HasError()); | 196 CHECK(preparser.logger()->has_error()); |
| 201 } | 197 } |
| 202 } | 198 } |
| 203 | 199 |
| 204 | 200 |
| 205 class ScriptResource : public v8::String::ExternalOneByteStringResource { | 201 class ScriptResource : public v8::String::ExternalOneByteStringResource { |
| 206 public: | 202 public: |
| 207 ScriptResource(const char* data, size_t length) | 203 ScriptResource(const char* data, size_t length) |
| 208 : data_(data), length_(length) { } | 204 : data_(data), length_(length) { } |
| 209 | 205 |
| 210 const char* data() const { return data_; } | 206 const char* data() const { return data_; } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 "function foo(x, y) { return x + y; }", | 347 "function foo(x, y) { return x + y; }", |
| 352 "%ArgleBargle(glop);", | 348 "%ArgleBargle(glop);", |
| 353 "var x = new new Function('this.x = 42');", | 349 "var x = new new Function('this.x = 42');", |
| 354 "var f = (x, y) => x + y;", | 350 "var f = (x, y) => x + y;", |
| 355 NULL | 351 NULL |
| 356 }; | 352 }; |
| 357 | 353 |
| 358 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 354 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 359 for (int i = 0; programs[i]; i++) { | 355 for (int i = 0; programs[i]; i++) { |
| 360 auto stream = i::ScannerStream::ForTesting(programs[i]); | 356 auto stream = i::ScannerStream::ForTesting(programs[i]); |
| 361 i::CompleteParserRecorder log; | |
| 362 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 357 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 363 scanner.Initialize(stream.get()); | 358 scanner.Initialize(stream.get()); |
| 364 | 359 |
| 365 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 360 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 366 i::AstValueFactory ast_value_factory( | 361 i::AstValueFactory ast_value_factory( |
| 367 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 362 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 368 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 363 i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit); |
| 369 stack_limit); | |
| 370 preparser.set_allow_lazy(true); | 364 preparser.set_allow_lazy(true); |
| 371 preparser.set_allow_natives(true); | 365 preparser.set_allow_natives(true); |
| 372 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 366 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 373 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 367 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 374 CHECK(!log.HasError()); | 368 CHECK(!preparser.logger()->has_error()); |
| 375 } | 369 } |
| 376 } | 370 } |
| 377 | 371 |
| 378 | 372 |
| 379 TEST(StandAlonePreParserNoNatives) { | 373 TEST(StandAlonePreParserNoNatives) { |
| 380 v8::V8::Initialize(); | 374 v8::V8::Initialize(); |
| 381 | 375 |
| 382 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 376 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 383 i::GetCurrentStackPosition() - 128 * 1024); | 377 i::GetCurrentStackPosition() - 128 * 1024); |
| 384 | 378 |
| 385 const char* programs[] = { | 379 const char* programs[] = { |
| 386 "%ArgleBargle(glop);", | 380 "%ArgleBargle(glop);", |
| 387 "var x = %_IsSmi(42);", | 381 "var x = %_IsSmi(42);", |
| 388 NULL | 382 NULL |
| 389 }; | 383 }; |
| 390 | 384 |
| 391 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 385 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 392 for (int i = 0; programs[i]; i++) { | 386 for (int i = 0; programs[i]; i++) { |
| 393 auto stream = i::ScannerStream::ForTesting(programs[i]); | 387 auto stream = i::ScannerStream::ForTesting(programs[i]); |
| 394 i::CompleteParserRecorder log; | |
| 395 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 388 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 396 scanner.Initialize(stream.get()); | 389 scanner.Initialize(stream.get()); |
| 397 | 390 |
| 398 // Preparser defaults to disallowing natives syntax. | 391 // Preparser defaults to disallowing natives syntax. |
| 399 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 392 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 400 i::AstValueFactory ast_value_factory( | 393 i::AstValueFactory ast_value_factory( |
| 401 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 394 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 402 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 395 i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit); |
| 403 stack_limit); | |
| 404 preparser.set_allow_lazy(true); | 396 preparser.set_allow_lazy(true); |
| 405 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 397 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 406 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 398 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 407 CHECK(log.HasError()); | 399 CHECK(preparser.logger()->has_error()); |
| 408 } | 400 } |
| 409 } | 401 } |
| 410 | 402 |
| 411 | 403 |
| 412 TEST(PreparsingObjectLiterals) { | 404 TEST(PreparsingObjectLiterals) { |
| 413 // Regression test for a bug where the symbol stream produced by PreParser | 405 // Regression test for a bug where the symbol stream produced by PreParser |
| 414 // didn't match what Parser wanted to consume. | 406 // didn't match what Parser wanted to consume. |
| 415 v8::Isolate* isolate = CcTest::isolate(); | 407 v8::Isolate* isolate = CcTest::isolate(); |
| 416 v8::HandleScope handles(isolate); | 408 v8::HandleScope handles(isolate); |
| 417 v8::Local<v8::Context> context = v8::Context::New(isolate); | 409 v8::Local<v8::Context> context = v8::Context::New(isolate); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 128 * 1024); | 445 128 * 1024); |
| 454 | 446 |
| 455 const char* program = "var x = 'something';\n" | 447 const char* program = "var x = 'something';\n" |
| 456 "escape: function() {}"; | 448 "escape: function() {}"; |
| 457 // Fails parsing expecting an identifier after "function". | 449 // Fails parsing expecting an identifier after "function". |
| 458 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), | 450 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), |
| 459 // and then used the invalid currently scanned literal. This always | 451 // and then used the invalid currently scanned literal. This always |
| 460 // failed in debug mode, and sometimes crashed in release mode. | 452 // failed in debug mode, and sometimes crashed in release mode. |
| 461 | 453 |
| 462 auto stream = i::ScannerStream::ForTesting(program); | 454 auto stream = i::ScannerStream::ForTesting(program); |
| 463 i::CompleteParserRecorder log; | |
| 464 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 455 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 465 scanner.Initialize(stream.get()); | 456 scanner.Initialize(stream.get()); |
| 466 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 457 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 467 i::AstValueFactory ast_value_factory(&zone, | 458 i::AstValueFactory ast_value_factory(&zone, |
| 468 CcTest::i_isolate()->heap()->HashSeed()); | 459 CcTest::i_isolate()->heap()->HashSeed()); |
| 469 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 460 i::PreParser preparser(&zone, &scanner, &ast_value_factory, |
| 470 CcTest::i_isolate()->stack_guard()->real_climit()); | 461 CcTest::i_isolate()->stack_guard()->real_climit()); |
| 471 preparser.set_allow_lazy(true); | 462 preparser.set_allow_lazy(true); |
| 472 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 463 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 473 // Even in the case of a syntax error, kPreParseSuccess is returned. | 464 // Even in the case of a syntax error, kPreParseSuccess is returned. |
| 474 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 465 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 475 CHECK(log.HasError()); | 466 CHECK(preparser.logger()->has_error()); |
| 476 } | 467 } |
| 477 | 468 |
| 478 | 469 |
| 479 TEST(Regress928) { | 470 TEST(Regress928) { |
| 480 // Test only applies when lazy parsing. | 471 // Test only applies when lazy parsing. |
| 481 if (!i::FLAG_lazy) return; | 472 if (!i::FLAG_lazy) return; |
| 482 i::FLAG_min_preparse_length = 0; | 473 i::FLAG_min_preparse_length = 0; |
| 483 | 474 |
| 484 // Tests that the first non-toplevel function is not included in the preparse | 475 // Tests that the first non-toplevel function is not included in the preparse |
| 485 // data. | 476 // data. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 i::GetCurrentStackPosition() - 128 * 1024); | 517 i::GetCurrentStackPosition() - 128 * 1024); |
| 527 | 518 |
| 528 size_t kProgramSize = 1024 * 1024; | 519 size_t kProgramSize = 1024 * 1024; |
| 529 std::unique_ptr<char[]> program(i::NewArray<char>(kProgramSize + 1)); | 520 std::unique_ptr<char[]> program(i::NewArray<char>(kProgramSize + 1)); |
| 530 memset(program.get(), '(', kProgramSize); | 521 memset(program.get(), '(', kProgramSize); |
| 531 program[kProgramSize] = '\0'; | 522 program[kProgramSize] = '\0'; |
| 532 | 523 |
| 533 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 524 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 534 | 525 |
| 535 auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize); | 526 auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize); |
| 536 i::CompleteParserRecorder log; | |
| 537 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 527 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 538 scanner.Initialize(stream.get()); | 528 scanner.Initialize(stream.get()); |
| 539 | 529 |
| 540 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 530 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 541 i::AstValueFactory ast_value_factory(&zone, | 531 i::AstValueFactory ast_value_factory(&zone, |
| 542 CcTest::i_isolate()->heap()->HashSeed()); | 532 CcTest::i_isolate()->heap()->HashSeed()); |
| 543 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 533 i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit); |
| 544 stack_limit); | |
| 545 preparser.set_allow_lazy(true); | 534 preparser.set_allow_lazy(true); |
| 546 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 535 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 547 CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); | 536 CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); |
| 548 } | 537 } |
| 549 | 538 |
| 550 | 539 |
| 551 void TestStreamScanner(i::Utf16CharacterStream* stream, | 540 void TestStreamScanner(i::Utf16CharacterStream* stream, |
| 552 i::Token::Value* expected_tokens, | 541 i::Token::Value* expected_tokens, |
| 553 int skip_pos = 0, // Zero means not skipping. | 542 int skip_pos = 0, // Zero means not skipping. |
| 554 int skip_to = 0) { | 543 int skip_to = 0) { |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 | 1342 |
| 1354 // Preparse the data. | 1343 // Preparse the data. |
| 1355 i::CompleteParserRecorder log; | 1344 i::CompleteParserRecorder log; |
| 1356 if (test_preparser) { | 1345 if (test_preparser) { |
| 1357 i::Scanner scanner(isolate->unicode_cache()); | 1346 i::Scanner scanner(isolate->unicode_cache()); |
| 1358 std::unique_ptr<i::Utf16CharacterStream> stream( | 1347 std::unique_ptr<i::Utf16CharacterStream> stream( |
| 1359 i::ScannerStream::For(source)); | 1348 i::ScannerStream::For(source)); |
| 1360 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 1349 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 1361 i::AstValueFactory ast_value_factory( | 1350 i::AstValueFactory ast_value_factory( |
| 1362 &zone, CcTest::i_isolate()->heap()->HashSeed()); | 1351 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 1363 i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log, | 1352 i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit); |
| 1364 stack_limit); | |
| 1365 SetParserFlags(&preparser, flags); | 1353 SetParserFlags(&preparser, flags); |
| 1366 scanner.Initialize(stream.get()); | 1354 scanner.Initialize(stream.get()); |
| 1367 i::PreParser::PreParseResult result = | 1355 i::PreParser::PreParseResult result = |
| 1368 preparser.PreParseProgram(&preparser_materialized_literals, is_module); | 1356 preparser.PreParseProgram(&preparser_materialized_literals, is_module); |
| 1369 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 1357 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 1358 i::SingletonLogger* logger = preparser.logger(); |
| 1359 // Convert to complete log. |
| 1360 if (logger->has_error()) { |
| 1361 log.LogMessage(logger->start(), logger->end(), logger->message(), |
| 1362 logger->argument_opt(), logger->error_type()); |
| 1363 } |
| 1370 } | 1364 } |
| 1371 bool preparse_error = log.HasError(); | 1365 bool preparse_error = log.HasError(); |
| 1372 | 1366 |
| 1373 // Parse the data | 1367 // Parse the data |
| 1374 i::FunctionLiteral* function; | 1368 i::FunctionLiteral* function; |
| 1375 { | 1369 { |
| 1376 i::Handle<i::Script> script = factory->NewScript(source); | 1370 i::Handle<i::Script> script = factory->NewScript(source); |
| 1377 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 1371 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); |
| 1378 i::ParseInfo info(&zone, script); | 1372 i::ParseInfo info(&zone, script); |
| 1379 i::Parser parser(&info); | 1373 i::Parser parser(&info); |
| (...skipping 6975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8355 const char* data[] = { | 8349 const char* data[] = { |
| 8356 "const arguments = 1", | 8350 "const arguments = 1", |
| 8357 "let arguments", | 8351 "let arguments", |
| 8358 "var arguments", | 8352 "var arguments", |
| 8359 NULL | 8353 NULL |
| 8360 }; | 8354 }; |
| 8361 // clang-format on | 8355 // clang-format on |
| 8362 RunParserSyncTest(context_data, data, kSuccess); | 8356 RunParserSyncTest(context_data, data, kSuccess); |
| 8363 } | 8357 } |
| 8364 } | 8358 } |
| OLD | NEW |