| 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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 150 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 151 i::GetCurrentStackPosition() - 128 * 1024); | 151 i::GetCurrentStackPosition() - 128 * 1024); |
| 152 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 152 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 153 for (int i = 0; tests[i]; i++) { | 153 for (int i = 0; tests[i]; i++) { |
| 154 const i::byte* source = | 154 const i::byte* source = |
| 155 reinterpret_cast<const i::byte*>(tests[i]); | 155 reinterpret_cast<const i::byte*>(tests[i]); |
| 156 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i])); | 156 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(tests[i])); |
| 157 i::CompleteParserRecorder log; | 157 i::CompleteParserRecorder log; |
| 158 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 158 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 159 scanner.Initialize(&stream); | 159 scanner.Initialize(&stream); |
| 160 i::PreParser preparser(&scanner, &log, stack_limit); | 160 i::Zone zone(CcTest::i_isolate()); |
| 161 i::AstValueFactory ast_value_factory( |
| 162 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 163 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 164 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 165 stack_limit); |
| 161 preparser.set_allow_lazy(true); | 166 preparser.set_allow_lazy(true); |
| 162 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 167 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 163 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 168 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 164 CHECK(!log.HasError()); | 169 CHECK(!log.HasError()); |
| 165 } | 170 } |
| 166 | 171 |
| 167 for (int i = 0; fail_tests[i]; i++) { | 172 for (int i = 0; fail_tests[i]; i++) { |
| 168 const i::byte* source = | 173 const i::byte* source = |
| 169 reinterpret_cast<const i::byte*>(fail_tests[i]); | 174 reinterpret_cast<const i::byte*>(fail_tests[i]); |
| 170 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i])); | 175 i::Utf8ToUtf16CharacterStream stream(source, i::StrLength(fail_tests[i])); |
| 171 i::CompleteParserRecorder log; | 176 i::CompleteParserRecorder log; |
| 172 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 177 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 173 scanner.Initialize(&stream); | 178 scanner.Initialize(&stream); |
| 174 i::PreParser preparser(&scanner, &log, stack_limit); | 179 i::Zone zone(CcTest::i_isolate()); |
| 180 i::AstValueFactory ast_value_factory( |
| 181 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 182 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 183 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 184 stack_limit); |
| 175 preparser.set_allow_lazy(true); | 185 preparser.set_allow_lazy(true); |
| 176 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 186 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 177 // Even in the case of a syntax error, kPreParseSuccess is returned. | 187 // Even in the case of a syntax error, kPreParseSuccess is returned. |
| 178 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 188 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 179 CHECK(log.HasError()); | 189 CHECK(log.HasError()); |
| 180 } | 190 } |
| 181 } | 191 } |
| 182 | 192 |
| 183 | 193 |
| 184 class ScriptResource : public v8::String::ExternalOneByteStringResource { | 194 class ScriptResource : public v8::String::ExternalOneByteStringResource { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 v8::Local<v8::Value> result = | 296 v8::Local<v8::Value> result = |
| 287 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run(); | 297 v8::ScriptCompiler::Compile(isolate, &bad_source)->Run(); |
| 288 CHECK(result->IsInt32()); | 298 CHECK(result->IsInt32()); |
| 289 CHECK_EQ(25, result->Int32Value()); | 299 CHECK_EQ(25, result->Int32Value()); |
| 290 } | 300 } |
| 291 } | 301 } |
| 292 | 302 |
| 293 | 303 |
| 294 TEST(StandAlonePreParser) { | 304 TEST(StandAlonePreParser) { |
| 295 v8::V8::Initialize(); | 305 v8::V8::Initialize(); |
| 306 v8::HandleScope handles(CcTest::isolate()); |
| 296 | 307 |
| 297 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 308 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 298 i::GetCurrentStackPosition() - 128 * 1024); | 309 i::GetCurrentStackPosition() - 128 * 1024); |
| 299 | 310 |
| 300 const char* programs[] = { | 311 const char* programs[] = { |
| 301 "{label: 42}", | 312 "{label: 42}", |
| 302 "var x = 42;", | 313 "var x = 42;", |
| 303 "function foo(x, y) { return x + y; }", | 314 "function foo(x, y) { return x + y; }", |
| 304 "%ArgleBargle(glop);", | 315 "%ArgleBargle(glop);", |
| 305 "var x = new new Function('this.x = 42');", | 316 "var x = new new Function('this.x = 42');", |
| 306 "var f = (x, y) => x + y;", | 317 "var f = (x, y) => x + y;", |
| 307 NULL | 318 NULL |
| 308 }; | 319 }; |
| 309 | 320 |
| 310 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 321 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 311 for (int i = 0; programs[i]; i++) { | 322 for (int i = 0; programs[i]; i++) { |
| 312 const char* program = programs[i]; | 323 const char* program = programs[i]; |
| 313 i::Utf8ToUtf16CharacterStream stream( | 324 i::Utf8ToUtf16CharacterStream stream( |
| 314 reinterpret_cast<const i::byte*>(program), | 325 reinterpret_cast<const i::byte*>(program), |
| 315 static_cast<unsigned>(strlen(program))); | 326 static_cast<unsigned>(strlen(program))); |
| 316 i::CompleteParserRecorder log; | 327 i::CompleteParserRecorder log; |
| 317 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 328 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 318 scanner.Initialize(&stream); | 329 scanner.Initialize(&stream); |
| 319 | 330 |
| 320 i::PreParser preparser(&scanner, &log, stack_limit); | 331 i::Zone zone(CcTest::i_isolate()); |
| 332 i::AstValueFactory ast_value_factory( |
| 333 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 334 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 335 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 336 stack_limit); |
| 321 preparser.set_allow_lazy(true); | 337 preparser.set_allow_lazy(true); |
| 322 preparser.set_allow_natives_syntax(true); | 338 preparser.set_allow_natives_syntax(true); |
| 323 preparser.set_allow_arrow_functions(true); | 339 preparser.set_allow_arrow_functions(true); |
| 324 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 340 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 325 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 341 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 326 CHECK(!log.HasError()); | 342 CHECK(!log.HasError()); |
| 327 } | 343 } |
| 328 } | 344 } |
| 329 | 345 |
| 330 | 346 |
| 331 TEST(StandAlonePreParserNoNatives) { | 347 TEST(StandAlonePreParserNoNatives) { |
| 332 v8::V8::Initialize(); | 348 v8::V8::Initialize(); |
| 349 v8::HandleScope handles(CcTest::isolate()); |
| 333 | 350 |
| 334 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 351 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 335 i::GetCurrentStackPosition() - 128 * 1024); | 352 i::GetCurrentStackPosition() - 128 * 1024); |
| 336 | 353 |
| 337 const char* programs[] = { | 354 const char* programs[] = { |
| 338 "%ArgleBargle(glop);", | 355 "%ArgleBargle(glop);", |
| 339 "var x = %_IsSmi(42);", | 356 "var x = %_IsSmi(42);", |
| 340 NULL | 357 NULL |
| 341 }; | 358 }; |
| 342 | 359 |
| 343 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 360 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 344 for (int i = 0; programs[i]; i++) { | 361 for (int i = 0; programs[i]; i++) { |
| 345 const char* program = programs[i]; | 362 const char* program = programs[i]; |
| 346 i::Utf8ToUtf16CharacterStream stream( | 363 i::Utf8ToUtf16CharacterStream stream( |
| 347 reinterpret_cast<const i::byte*>(program), | 364 reinterpret_cast<const i::byte*>(program), |
| 348 static_cast<unsigned>(strlen(program))); | 365 static_cast<unsigned>(strlen(program))); |
| 349 i::CompleteParserRecorder log; | 366 i::CompleteParserRecorder log; |
| 350 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 367 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 351 scanner.Initialize(&stream); | 368 scanner.Initialize(&stream); |
| 352 | 369 |
| 353 // Preparser defaults to disallowing natives syntax. | 370 // Preparser defaults to disallowing natives syntax. |
| 354 i::PreParser preparser(&scanner, &log, stack_limit); | 371 i::Zone zone(CcTest::i_isolate()); |
| 372 i::AstValueFactory ast_value_factory( |
| 373 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 374 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 375 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 376 stack_limit); |
| 355 preparser.set_allow_lazy(true); | 377 preparser.set_allow_lazy(true); |
| 356 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 378 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 357 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 379 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 358 CHECK(log.HasError()); | 380 CHECK(log.HasError()); |
| 359 } | 381 } |
| 360 } | 382 } |
| 361 | 383 |
| 362 | 384 |
| 363 TEST(PreparsingObjectLiterals) { | 385 TEST(PreparsingObjectLiterals) { |
| 364 // Regression test for a bug where the symbol stream produced by PreParser | 386 // Regression test for a bug where the symbol stream produced by PreParser |
| (...skipping 26 matching lines...) Expand all Loading... |
| 391 v8::Local<v8::Value> result = ParserCacheCompileRun(source); | 413 v8::Local<v8::Value> result = ParserCacheCompileRun(source); |
| 392 CHECK(result->IsString()); | 414 CHECK(result->IsString()); |
| 393 v8::String::Utf8Value utf8(result); | 415 v8::String::Utf8Value utf8(result); |
| 394 CHECK_EQ("foo", *utf8); | 416 CHECK_EQ("foo", *utf8); |
| 395 } | 417 } |
| 396 } | 418 } |
| 397 | 419 |
| 398 | 420 |
| 399 TEST(RegressChromium62639) { | 421 TEST(RegressChromium62639) { |
| 400 v8::V8::Initialize(); | 422 v8::V8::Initialize(); |
| 423 v8::HandleScope handles(CcTest::isolate()); |
| 401 i::Isolate* isolate = CcTest::i_isolate(); | 424 i::Isolate* isolate = CcTest::i_isolate(); |
| 402 | 425 |
| 403 isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - | 426 isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() - |
| 404 128 * 1024); | 427 128 * 1024); |
| 405 | 428 |
| 406 const char* program = "var x = 'something';\n" | 429 const char* program = "var x = 'something';\n" |
| 407 "escape: function() {}"; | 430 "escape: function() {}"; |
| 408 // Fails parsing expecting an identifier after "function". | 431 // Fails parsing expecting an identifier after "function". |
| 409 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), | 432 // Before fix, didn't check *ok after Expect(Token::Identifier, ok), |
| 410 // and then used the invalid currently scanned literal. This always | 433 // and then used the invalid currently scanned literal. This always |
| 411 // failed in debug mode, and sometimes crashed in release mode. | 434 // failed in debug mode, and sometimes crashed in release mode. |
| 412 | 435 |
| 413 i::Utf8ToUtf16CharacterStream stream( | 436 i::Utf8ToUtf16CharacterStream stream( |
| 414 reinterpret_cast<const i::byte*>(program), | 437 reinterpret_cast<const i::byte*>(program), |
| 415 static_cast<unsigned>(strlen(program))); | 438 static_cast<unsigned>(strlen(program))); |
| 416 i::CompleteParserRecorder log; | 439 i::CompleteParserRecorder log; |
| 417 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 440 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 418 scanner.Initialize(&stream); | 441 scanner.Initialize(&stream); |
| 419 i::PreParser preparser(&scanner, &log, | 442 i::Zone zone(CcTest::i_isolate()); |
| 443 i::AstValueFactory ast_value_factory(&zone, |
| 444 CcTest::i_isolate()->heap()->HashSeed()); |
| 445 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 446 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 420 CcTest::i_isolate()->stack_guard()->real_climit()); | 447 CcTest::i_isolate()->stack_guard()->real_climit()); |
| 421 preparser.set_allow_lazy(true); | 448 preparser.set_allow_lazy(true); |
| 422 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 449 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 423 // Even in the case of a syntax error, kPreParseSuccess is returned. | 450 // Even in the case of a syntax error, kPreParseSuccess is returned. |
| 424 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 451 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 425 CHECK(log.HasError()); | 452 CHECK(log.HasError()); |
| 426 } | 453 } |
| 427 | 454 |
| 428 | 455 |
| 429 TEST(Regress928) { | 456 TEST(Regress928) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 441 const char* program = | 468 const char* program = |
| 442 "try { } catch (e) { var foo = function () { /* first */ } }" | 469 "try { } catch (e) { var foo = function () { /* first */ } }" |
| 443 "var bar = function () { /* second */ }"; | 470 "var bar = function () { /* second */ }"; |
| 444 | 471 |
| 445 v8::HandleScope handles(CcTest::isolate()); | 472 v8::HandleScope handles(CcTest::isolate()); |
| 446 i::Handle<i::String> source = factory->NewStringFromAsciiChecked(program); | 473 i::Handle<i::String> source = factory->NewStringFromAsciiChecked(program); |
| 447 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 474 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 448 i::CompleteParserRecorder log; | 475 i::CompleteParserRecorder log; |
| 449 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 476 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 450 scanner.Initialize(&stream); | 477 scanner.Initialize(&stream); |
| 451 i::PreParser preparser(&scanner, &log, | 478 i::Zone zone(CcTest::i_isolate()); |
| 479 i::AstValueFactory ast_value_factory(&zone, |
| 480 CcTest::i_isolate()->heap()->HashSeed()); |
| 481 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 482 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 452 CcTest::i_isolate()->stack_guard()->real_climit()); | 483 CcTest::i_isolate()->stack_guard()->real_climit()); |
| 453 preparser.set_allow_lazy(true); | 484 preparser.set_allow_lazy(true); |
| 454 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 485 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 455 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 486 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 456 i::ScriptData* sd = log.GetScriptData(); | 487 i::ScriptData* sd = log.GetScriptData(); |
| 457 i::ParseData pd(sd); | 488 i::ParseData pd(sd); |
| 458 pd.Initialize(); | 489 pd.Initialize(); |
| 459 | 490 |
| 460 int first_function = | 491 int first_function = |
| 461 static_cast<int>(strstr(program, "function") - program); | 492 static_cast<int>(strstr(program, "function") - program); |
| 462 int first_lbrace = first_function + i::StrLength("function () "); | 493 int first_lbrace = first_function + i::StrLength("function () "); |
| 463 CHECK_EQ('{', program[first_lbrace]); | 494 CHECK_EQ('{', program[first_lbrace]); |
| 464 i::FunctionEntry entry1 = pd.GetFunctionEntry(first_lbrace); | 495 i::FunctionEntry entry1 = pd.GetFunctionEntry(first_lbrace); |
| 465 CHECK(!entry1.is_valid()); | 496 CHECK(!entry1.is_valid()); |
| 466 | 497 |
| 467 int second_function = | 498 int second_function = |
| 468 static_cast<int>(strstr(program + first_lbrace, "function") - program); | 499 static_cast<int>(strstr(program + first_lbrace, "function") - program); |
| 469 int second_lbrace = | 500 int second_lbrace = |
| 470 second_function + i::StrLength("function () "); | 501 second_function + i::StrLength("function () "); |
| 471 CHECK_EQ('{', program[second_lbrace]); | 502 CHECK_EQ('{', program[second_lbrace]); |
| 472 i::FunctionEntry entry2 = pd.GetFunctionEntry(second_lbrace); | 503 i::FunctionEntry entry2 = pd.GetFunctionEntry(second_lbrace); |
| 473 CHECK(entry2.is_valid()); | 504 CHECK(entry2.is_valid()); |
| 474 CHECK_EQ('}', program[entry2.end_pos() - 1]); | 505 CHECK_EQ('}', program[entry2.end_pos() - 1]); |
| 475 delete sd; | 506 delete sd; |
| 476 } | 507 } |
| 477 | 508 |
| 478 | 509 |
| 479 TEST(PreParseOverflow) { | 510 TEST(PreParseOverflow) { |
| 480 v8::V8::Initialize(); | 511 v8::V8::Initialize(); |
| 512 v8::HandleScope handles(CcTest::isolate()); |
| 481 | 513 |
| 482 CcTest::i_isolate()->stack_guard()->SetStackLimit( | 514 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 483 i::GetCurrentStackPosition() - 128 * 1024); | 515 i::GetCurrentStackPosition() - 128 * 1024); |
| 484 | 516 |
| 485 size_t kProgramSize = 1024 * 1024; | 517 size_t kProgramSize = 1024 * 1024; |
| 486 i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1)); | 518 i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1)); |
| 487 memset(program.get(), '(', kProgramSize); | 519 memset(program.get(), '(', kProgramSize); |
| 488 program[kProgramSize] = '\0'; | 520 program[kProgramSize] = '\0'; |
| 489 | 521 |
| 490 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); | 522 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); |
| 491 | 523 |
| 492 i::Utf8ToUtf16CharacterStream stream( | 524 i::Utf8ToUtf16CharacterStream stream( |
| 493 reinterpret_cast<const i::byte*>(program.get()), | 525 reinterpret_cast<const i::byte*>(program.get()), |
| 494 static_cast<unsigned>(kProgramSize)); | 526 static_cast<unsigned>(kProgramSize)); |
| 495 i::CompleteParserRecorder log; | 527 i::CompleteParserRecorder log; |
| 496 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); | 528 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 497 scanner.Initialize(&stream); | 529 scanner.Initialize(&stream); |
| 498 | 530 |
| 499 i::PreParser preparser(&scanner, &log, stack_limit); | 531 i::Zone zone(CcTest::i_isolate()); |
| 532 i::AstValueFactory ast_value_factory(&zone, |
| 533 CcTest::i_isolate()->heap()->HashSeed()); |
| 534 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 535 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 536 stack_limit); |
| 500 preparser.set_allow_lazy(true); | 537 preparser.set_allow_lazy(true); |
| 501 preparser.set_allow_arrow_functions(true); | 538 preparser.set_allow_arrow_functions(true); |
| 502 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 539 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 503 CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); | 540 CHECK_EQ(i::PreParser::kPreParseStackOverflow, result); |
| 504 } | 541 } |
| 505 | 542 |
| 506 | 543 |
| 507 class TestExternalResource: public v8::String::ExternalStringResource { | 544 class TestExternalResource: public v8::String::ExternalStringResource { |
| 508 public: | 545 public: |
| 509 explicit TestExternalResource(uint16_t* data, int length) | 546 explicit TestExternalResource(uint16_t* data, int length) |
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 i::Isolate* isolate = CcTest::i_isolate(); | 1403 i::Isolate* isolate = CcTest::i_isolate(); |
| 1367 i::Factory* factory = isolate->factory(); | 1404 i::Factory* factory = isolate->factory(); |
| 1368 | 1405 |
| 1369 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); | 1406 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 1370 | 1407 |
| 1371 // Preparse the data. | 1408 // Preparse the data. |
| 1372 i::CompleteParserRecorder log; | 1409 i::CompleteParserRecorder log; |
| 1373 { | 1410 { |
| 1374 i::Scanner scanner(isolate->unicode_cache()); | 1411 i::Scanner scanner(isolate->unicode_cache()); |
| 1375 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 1412 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 1376 i::PreParser preparser(&scanner, &log, stack_limit); | 1413 i::Zone zone(CcTest::i_isolate()); |
| 1414 i::AstValueFactory ast_value_factory( |
| 1415 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 1416 v8::HandleScope handles(CcTest::isolate()); |
| 1417 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 1418 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 1419 stack_limit); |
| 1377 SetParserFlags(&preparser, flags); | 1420 SetParserFlags(&preparser, flags); |
| 1378 scanner.Initialize(&stream); | 1421 scanner.Initialize(&stream); |
| 1379 i::PreParser::PreParseResult result = preparser.PreParseProgram(); | 1422 i::PreParser::PreParseResult result = preparser.PreParseProgram(); |
| 1380 CHECK_EQ(i::PreParser::kPreParseSuccess, result); | 1423 CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| 1381 } | 1424 } |
| 1382 | 1425 |
| 1383 bool preparse_error = log.HasError(); | 1426 bool preparse_error = log.HasError(); |
| 1384 | 1427 |
| 1385 // Parse the data | 1428 // Parse the data |
| 1386 i::FunctionLiteral* function; | 1429 i::FunctionLiteral* function; |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2382 // No functions. | 2425 // No functions. |
| 2383 {"var x = 42;", 0}, | 2426 {"var x = 42;", 0}, |
| 2384 // Functions. | 2427 // Functions. |
| 2385 {"function foo() {}", 1}, {"function foo() {} function bar() {}", 2}, | 2428 {"function foo() {}", 1}, {"function foo() {} function bar() {}", 2}, |
| 2386 // Getter / setter functions are recorded as functions if they're on the top | 2429 // Getter / setter functions are recorded as functions if they're on the top |
| 2387 // level. | 2430 // level. |
| 2388 {"var x = {get foo(){} };", 1}, | 2431 {"var x = {get foo(){} };", 1}, |
| 2389 // Functions insize lazy functions are not recorded. | 2432 // Functions insize lazy functions are not recorded. |
| 2390 {"function lazy() { function a() {} function b() {} function c() {} }", 1}, | 2433 {"function lazy() { function a() {} function b() {} function c() {} }", 1}, |
| 2391 {"function lazy() { var x = {get foo(){} } }", 1}, | 2434 {"function lazy() { var x = {get foo(){} } }", 1}, |
| 2435 // Functions inside eager functions are recorded. |
| 2436 {"(function() { function lazy() {} })()", 1}, |
| 2437 {"(function() { var lazy = function() {} })()", 1}, |
| 2392 {NULL, 0} | 2438 {NULL, 0} |
| 2393 }; | 2439 }; |
| 2394 | 2440 |
| 2395 for (int i = 0; test_cases[i].program; i++) { | 2441 for (int i = 0; test_cases[i].program; i++) { |
| 2396 const char* program = test_cases[i].program; | 2442 const char* program = test_cases[i].program; |
| 2397 i::Factory* factory = CcTest::i_isolate()->factory(); | 2443 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 2398 i::Handle<i::String> source = | 2444 i::Handle<i::String> source = |
| 2399 factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked(); | 2445 factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked(); |
| 2400 i::Handle<i::Script> script = factory->NewScript(source); | 2446 i::Handle<i::Script> script = factory->NewScript(source); |
| 2401 i::CompilationInfoWithZone info(script); | 2447 i::CompilationInfoWithZone info(script); |
| 2402 i::ScriptData* sd = NULL; | 2448 i::ScriptData* sd = NULL; |
| 2403 info.SetCachedData(&sd, v8::ScriptCompiler::kProduceParserCache); | 2449 info.SetCachedData(&sd, v8::ScriptCompiler::kProduceParserCache); |
| 2404 i::Parser::Parse(&info, true); | 2450 i::Parser::Parse(&info, true); |
| 2405 i::ParseData pd(sd); | 2451 i::ParseData pd(sd); |
| 2406 | 2452 |
| 2407 if (pd.FunctionCount() != test_cases[i].functions) { | 2453 if (pd.FunctionCount() != test_cases[i].functions) { |
| 2408 v8::base::OS::Print( | 2454 v8::base::OS::Print( |
| 2409 "Expected preparse data for program:\n" | 2455 "Expected preparse data for program:\n" |
| 2410 "\t%s\n" | 2456 "\t%s\n" |
| 2411 "to contain %d functions, however, received %d functions.\n", | 2457 "to contain %d functions, however, received %d functions.\n", |
| 2412 program, test_cases[i].functions, pd.FunctionCount()); | 2458 program, test_cases[i].functions, pd.FunctionCount()); |
| 2413 CHECK(false); | 2459 CHECK(false); |
| 2414 } | 2460 } |
| 2415 delete sd; | 2461 delete sd; |
| 2416 } | 2462 } |
| 2417 } | 2463 } |
| 2418 | 2464 |
| 2419 | 2465 |
| 2466 TEST(PreParserReportsUnboundIdentifiers) { |
| 2467 v8::V8::Initialize(); |
| 2468 v8::Isolate* isolate = CcTest::isolate(); |
| 2469 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 2470 v8::HandleScope handles(isolate); |
| 2471 |
| 2472 CcTest::i_isolate()->stack_guard()->SetStackLimit( |
| 2473 i::GetCurrentStackPosition() - 128 * 1024); |
| 2474 |
| 2475 struct TestCase { |
| 2476 const char* function; |
| 2477 i::StrictMode strict_mode; |
| 2478 const char* identifier; |
| 2479 } test_cases[] = { |
| 2480 {"{ a = 0; }", i::SLOPPY, "a"}, |
| 2481 {"{ var a = 0; }", i::SLOPPY, NULL}, |
| 2482 {"{ a(); }", i::SLOPPY, "a"}, |
| 2483 {"{ function a(){} a(); }", i::SLOPPY, NULL}, |
| 2484 {"{ function a(){ b = 0; } }", i::SLOPPY, "b"}, |
| 2485 {"{ function a(b){ b = 0; } }", i::SLOPPY, NULL}, |
| 2486 {"{ try { a = 0; } catch (e) {} }", i::SLOPPY, "a"}, |
| 2487 {"{ a = 0; try { var a = 1; } catch (e) { a = e; } }", i::SLOPPY, NULL}, |
| 2488 {"{ var a = {}; with (a) { b = 0; } }", i::SLOPPY, "b"}, |
| 2489 {"{ var a = {}; with (a) { var b = 0; } b = 1; }", i::SLOPPY, NULL}, |
| 2490 {"{ for (var i = 0; i < 2; i++) { a = i; } }", i::STRICT, "a"}, |
| 2491 {"{ for (let i = 0; i < 2; i++) { a = i; } }", i::STRICT, "a"}, |
| 2492 {"{ for (let i = 0; i < 2; i++) {} i++; }", i::STRICT, "i"}, |
| 2493 {"{ for (let a in a) {} }", i::STRICT, "a"}, |
| 2494 {"{ for (let a of a) {} }", i::STRICT, "a"}, |
| 2495 {"{ var o = {}; for (let a of o;;) { a(); } }", i::STRICT, NULL}, |
| 2496 {"{ var o = {}; for (let a of o;;) { a(); } }", i::STRICT, NULL}, |
| 2497 {"{ class C {} return C; }", i::SLOPPY, NULL}, |
| 2498 {"{ function a(){ class C {} } return C; }", i::SLOPPY, "C"}, |
| 2499 {"{ function a(){ let b = 0; } b = 1; }", i::STRICT, "b"}, |
| 2500 {"{ if (1) { let b = 0; } b = 1; }", i::STRICT, "b"}, |
| 2501 {"{ let a = 0; a = 1; }", i::STRICT, NULL}, |
| 2502 {"{ if (1) { const b = 0; } b = 1; }", i::STRICT, "b"}, |
| 2503 {NULL, i::STRICT, 0} |
| 2504 }; |
| 2505 |
| 2506 for (int i = 0; test_cases[i].function; i++) { |
| 2507 const char* function = test_cases[i].function; |
| 2508 const i::StrictMode strict_mode = test_cases[i].strict_mode; |
| 2509 i::Handle<i::String> source = factory->NewStringFromAsciiChecked(function); |
| 2510 i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 2511 i::SingletonLogger log; |
| 2512 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); |
| 2513 scanner.Initialize(&stream); |
| 2514 i::Zone zone(CcTest::i_isolate()); |
| 2515 i::AstValueFactory ast_value_factory( |
| 2516 &zone, CcTest::i_isolate()->heap()->HashSeed()); |
| 2517 ast_value_factory.Internalize(CcTest::i_isolate()); |
| 2518 i::PreParser preparser(&scanner, &log, &ast_value_factory, &zone, |
| 2519 CcTest::i_isolate()->stack_guard()->real_climit()); |
| 2520 preparser.set_allow_classes(true); |
| 2521 preparser.set_allow_harmony_scoping(true); |
| 2522 |
| 2523 scanner.Next(); // Kick-start the scanner so we have a current_token |
| 2524 CHECK_EQ(preparser.PreParseLazyFunction(strict_mode, false, true, &log), |
| 2525 i::PreParser::kPreParseSuccess); |
| 2526 |
| 2527 const char* expected_identifier = test_cases[i].identifier; |
| 2528 i::SingletonLogger::IdentifierIterator it = log.IdentifiersStart(); |
| 2529 if (expected_identifier) { |
| 2530 const i::AstRawString* reported_identifier = it.Next(); |
| 2531 if (!(reported_identifier && |
| 2532 reported_identifier->IsOneByteEqualTo(expected_identifier))) { |
| 2533 v8::base::OS::Print( |
| 2534 "Expected lazy preparse of function:\n" |
| 2535 "\t%s\n" |
| 2536 "to report identifier %s.\n", |
| 2537 function, expected_identifier); |
| 2538 if (reported_identifier) { |
| 2539 v8::base::OS::Print("(Actually reported %.*s)\n", |
| 2540 reported_identifier->length(), |
| 2541 reported_identifier->raw_data()); |
| 2542 } |
| 2543 CHECK(false); |
| 2544 } |
| 2545 } |
| 2546 CHECK_EQ(it.Next(), NULL); |
| 2547 } |
| 2548 } |
| 2549 |
| 2550 |
| 2420 TEST(FunctionDeclaresItselfStrict) { | 2551 TEST(FunctionDeclaresItselfStrict) { |
| 2421 // Tests that we produce the right kinds of errors when a function declares | 2552 // Tests that we produce the right kinds of errors when a function declares |
| 2422 // itself strict (we cannot produce there errors as soon as we see the | 2553 // itself strict (we cannot produce there errors as soon as we see the |
| 2423 // offending identifiers, because we don't know at that point whether the | 2554 // offending identifiers, because we don't know at that point whether the |
| 2424 // function is strict or not). | 2555 // function is strict or not). |
| 2425 const char* context_data[][2] = { | 2556 const char* context_data[][2] = { |
| 2426 {"function eval() {", "}"}, | 2557 {"function eval() {", "}"}, |
| 2427 {"function arguments() {", "}"}, | 2558 {"function arguments() {", "}"}, |
| 2428 {"function yield() {", "}"}, | 2559 {"function yield() {", "}"}, |
| 2429 {"function interface() {", "}"}, | 2560 {"function interface() {", "}"}, |
| (...skipping 1768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4198 | 4329 |
| 4199 const char* name_data[] = { | 4330 const char* name_data[] = { |
| 4200 "function* g() { ({yield}); }", | 4331 "function* g() { ({yield}); }", |
| 4201 NULL | 4332 NULL |
| 4202 }; | 4333 }; |
| 4203 | 4334 |
| 4204 static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; | 4335 static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals}; |
| 4205 RunParserSyncTest(context_data, name_data, kError, NULL, 0, | 4336 RunParserSyncTest(context_data, name_data, kError, NULL, 0, |
| 4206 always_flags, arraysize(always_flags)); | 4337 always_flags, arraysize(always_flags)); |
| 4207 } | 4338 } |
| OLD | NEW |