Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(716)

Side by Side Diff: test/cctest/test-parsing.cc

Issue 641283003: Support lazy parsing of inner functions (Closed) Base URL: https://chromium.googlesource.com/external/v8.git@bleeding_edge
Patch Set: Actually track variable declarations in the preparser Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/vector.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/vector.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698