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