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 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 i::Scope* inner_scope = scope->inner_scopes()->at(0); | 1381 i::Scope* inner_scope = scope->inner_scopes()->at(0); |
1382 CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type); | 1382 CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type); |
1383 CHECK_EQ(inner_scope->start_position(), kPrefixLen); | 1383 CHECK_EQ(inner_scope->start_position(), kPrefixLen); |
1384 // The end position of a token is one position after the last | 1384 // The end position of a token is one position after the last |
1385 // character belonging to that token. | 1385 // character belonging to that token. |
1386 CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen); | 1386 CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen); |
1387 } | 1387 } |
1388 } | 1388 } |
1389 | 1389 |
1390 | 1390 |
| 1391 TEST(DiscardFunctionBody) { |
| 1392 // Test that inner function bodies are discarded if possible. |
| 1393 // See comments in ParseFunctionLiteral in parser.cc. |
| 1394 const char* discard_sources[] = { |
| 1395 "(function f() { function g() { var a; } })();", |
| 1396 /* TODO(conradw): In future it may be possible to apply this optimisation |
| 1397 * to these productions. |
| 1398 "(function f() { 0, function g() { var a; } })();", |
| 1399 "(function f() { 0, { g() { var a; } } })();", |
| 1400 "(function f() { 0, class c { g() { var a; } } })();", */ |
| 1401 NULL |
| 1402 }; |
| 1403 |
| 1404 i::Isolate* isolate = CcTest::i_isolate(); |
| 1405 i::Factory* factory = isolate->factory(); |
| 1406 v8::HandleScope handles(CcTest::isolate()); |
| 1407 i::FunctionLiteral* function; |
| 1408 |
| 1409 for (int i = 0; discard_sources[i]; i++) { |
| 1410 const char* source = discard_sources[i]; |
| 1411 i::Handle<i::String> source_code = |
| 1412 factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked(); |
| 1413 i::Handle<i::Script> script = factory->NewScript(source_code); |
| 1414 i::Zone zone; |
| 1415 i::ParseInfo info(&zone, script); |
| 1416 info.set_allow_lazy_parsing(); |
| 1417 i::Parser parser(&info); |
| 1418 parser.set_allow_harmony_sloppy(true); |
| 1419 parser.Parse(&info); |
| 1420 function = info.literal(); |
| 1421 CHECK_NOT_NULL(function); |
| 1422 CHECK_NOT_NULL(function->body()); |
| 1423 CHECK_EQ(1, function->body()->length()); |
| 1424 i::FunctionLiteral* inner = |
| 1425 function->body()->first()->AsExpressionStatement()->expression()-> |
| 1426 AsCall()->expression()->AsFunctionLiteral(); |
| 1427 i::Scope* inner_scope = inner->scope(); |
| 1428 i::FunctionLiteral* fun = nullptr; |
| 1429 if (inner_scope->declarations()->length() > 1) { |
| 1430 fun = inner_scope->declarations()->at(1)->AsFunctionDeclaration()->fun(); |
| 1431 } else { |
| 1432 // TODO(conradw): This path won't be hit until the other test cases can be |
| 1433 // uncommented. |
| 1434 CHECK_NOT_NULL(inner->body()); |
| 1435 CHECK_GE(2, inner->body()->length()); |
| 1436 i::Expression* exp = inner->body()->at(1)->AsExpressionStatement()-> |
| 1437 expression()->AsBinaryOperation()->right(); |
| 1438 if (exp->IsFunctionLiteral()) { |
| 1439 fun = exp->AsFunctionLiteral(); |
| 1440 } else if (exp->IsObjectLiteral()) { |
| 1441 fun = exp->AsObjectLiteral()->properties()->at(0)->value()-> |
| 1442 AsFunctionLiteral(); |
| 1443 } else { |
| 1444 fun = exp->AsClassLiteral()->properties()->at(0)->value()-> |
| 1445 AsFunctionLiteral(); |
| 1446 } |
| 1447 } |
| 1448 CHECK_NULL(fun->body()); |
| 1449 } |
| 1450 } |
| 1451 |
| 1452 |
1391 const char* ReadString(unsigned* start) { | 1453 const char* ReadString(unsigned* start) { |
1392 int length = start[0]; | 1454 int length = start[0]; |
1393 char* result = i::NewArray<char>(length + 1); | 1455 char* result = i::NewArray<char>(length + 1); |
1394 for (int i = 0; i < length; i++) { | 1456 for (int i = 0; i < length; i++) { |
1395 result[i] = start[i + 1]; | 1457 result[i] = start[i + 1]; |
1396 } | 1458 } |
1397 result[length] = '\0'; | 1459 result[length] = '\0'; |
1398 return result; | 1460 return result; |
1399 } | 1461 } |
1400 | 1462 |
(...skipping 5471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6872 "for (let x of []) {}", | 6934 "for (let x of []) {}", |
6873 NULL | 6935 NULL |
6874 }; | 6936 }; |
6875 // clang-format on | 6937 // clang-format on |
6876 | 6938 |
6877 static const ParserFlag always_flags[] = {kAllowHarmonySloppy, | 6939 static const ParserFlag always_flags[] = {kAllowHarmonySloppy, |
6878 kAllowHarmonySloppyLet}; | 6940 kAllowHarmonySloppyLet}; |
6879 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, | 6941 RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, |
6880 arraysize(always_flags)); | 6942 arraysize(always_flags)); |
6881 } | 6943 } |
OLD | NEW |