OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 int next_index = | 671 int next_index = |
672 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; | 672 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; |
673 materialized_literal_count_++; | 673 materialized_literal_count_++; |
674 return next_index; | 674 return next_index; |
675 } | 675 } |
676 int materialized_literal_count() { return materialized_literal_count_; } | 676 int materialized_literal_count() { return materialized_literal_count_; } |
677 | 677 |
678 void set_contains_array_literal() { contains_array_literal_ = true; } | 678 void set_contains_array_literal() { contains_array_literal_ = true; } |
679 bool contains_array_literal() { return contains_array_literal_; } | 679 bool contains_array_literal() { return contains_array_literal_; } |
680 | 680 |
| 681 void SetThisPropertyAssignmentInfo( |
| 682 bool only_this_property_assignments, |
| 683 bool only_simple_this_property_assignments, |
| 684 Handle<FixedArray> this_property_assignments) { |
| 685 only_this_property_assignments_ = only_this_property_assignments; |
| 686 only_simple_this_property_assignments_ = |
| 687 only_simple_this_property_assignments; |
| 688 this_property_assignments_ = this_property_assignments; |
| 689 } |
| 690 bool only_this_property_assignments() { |
| 691 return only_this_property_assignments_; |
| 692 } |
| 693 bool only_simple_this_property_assignments() { |
| 694 return only_simple_this_property_assignments_; |
| 695 } |
| 696 Handle<FixedArray> this_property_assignments() { |
| 697 return this_property_assignments_; |
| 698 } |
| 699 |
681 void AddProperty() { expected_property_count_++; } | 700 void AddProperty() { expected_property_count_++; } |
682 int expected_property_count() { return expected_property_count_; } | 701 int expected_property_count() { return expected_property_count_; } |
683 private: | 702 private: |
684 // Captures the number of nodes that need materialization in the | 703 // Captures the number of nodes that need materialization in the |
685 // function. regexp literals, and boilerplate for object literals. | 704 // function. regexp literals, and boilerplate for object literals. |
686 int materialized_literal_count_; | 705 int materialized_literal_count_; |
687 | 706 |
688 // Captures whether or not the function contains array literals. If | 707 // Captures whether or not the function contains array literals. If |
689 // the function contains array literals, we have to allocate space | 708 // the function contains array literals, we have to allocate space |
690 // for the array constructor in the literals array of the function. | 709 // for the array constructor in the literals array of the function. |
691 // This array constructor is used when creating the actual array | 710 // This array constructor is used when creating the actual array |
692 // literals. | 711 // literals. |
693 bool contains_array_literal_; | 712 bool contains_array_literal_; |
694 | 713 |
695 // Properties count estimation. | 714 // Properties count estimation. |
696 int expected_property_count_; | 715 int expected_property_count_; |
697 | 716 |
| 717 bool only_this_property_assignments_; |
| 718 bool only_simple_this_property_assignments_; |
| 719 Handle<FixedArray> this_property_assignments_; |
| 720 |
698 // Bookkeeping | 721 // Bookkeeping |
699 Parser* parser_; | 722 Parser* parser_; |
700 TemporaryScope* parent_; | 723 TemporaryScope* parent_; |
701 | 724 |
702 friend class Parser; | 725 friend class Parser; |
703 }; | 726 }; |
704 | 727 |
705 | 728 |
706 TemporaryScope::TemporaryScope(Parser* parser) | 729 TemporaryScope::TemporaryScope(Parser* parser) |
707 : materialized_literal_count_(0), | 730 : materialized_literal_count_(0), |
708 contains_array_literal_(false), | 731 contains_array_literal_(false), |
709 expected_property_count_(0), | 732 expected_property_count_(0), |
| 733 only_this_property_assignments_(false), |
| 734 only_simple_this_property_assignments_(false), |
| 735 this_property_assignments_(Factory::empty_fixed_array()), |
710 parser_(parser), | 736 parser_(parser), |
711 parent_(parser->temp_scope_) { | 737 parent_(parser->temp_scope_) { |
712 parser->temp_scope_ = this; | 738 parser->temp_scope_ = this; |
713 } | 739 } |
714 | 740 |
715 | 741 |
716 TemporaryScope::~TemporaryScope() { | 742 TemporaryScope::~TemporaryScope() { |
717 parser_->temp_scope_ = parent_; | 743 parser_->temp_scope_ = parent_; |
718 } | 744 } |
719 | 745 |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 Handle<String> no_name = factory()->EmptySymbol(); | 1237 Handle<String> no_name = factory()->EmptySymbol(); |
1212 | 1238 |
1213 FunctionLiteral* result = NULL; | 1239 FunctionLiteral* result = NULL; |
1214 { Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); | 1240 { Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); |
1215 LexicalScope lexical_scope(this, scope); | 1241 LexicalScope lexical_scope(this, scope); |
1216 TemporaryScope temp_scope(this); | 1242 TemporaryScope temp_scope(this); |
1217 ZoneListWrapper<Statement> body(16); | 1243 ZoneListWrapper<Statement> body(16); |
1218 bool ok = true; | 1244 bool ok = true; |
1219 ParseSourceElements(&body, Token::EOS, &ok); | 1245 ParseSourceElements(&body, Token::EOS, &ok); |
1220 if (ok) { | 1246 if (ok) { |
1221 result = NEW(FunctionLiteral(no_name, top_scope_, | 1247 result = NEW(FunctionLiteral( |
1222 body.elements(), | 1248 no_name, |
1223 temp_scope.materialized_literal_count(), | 1249 top_scope_, |
1224 temp_scope.contains_array_literal(), | 1250 body.elements(), |
1225 temp_scope.expected_property_count(), | 1251 temp_scope.materialized_literal_count(), |
1226 0, 0, source->length(), false)); | 1252 temp_scope.contains_array_literal(), |
| 1253 temp_scope.expected_property_count(), |
| 1254 temp_scope.only_this_property_assignments(), |
| 1255 temp_scope.only_simple_this_property_assignments(), |
| 1256 temp_scope.this_property_assignments(), |
| 1257 0, |
| 1258 0, |
| 1259 source->length(), |
| 1260 false)); |
1227 } else if (scanner().stack_overflow()) { | 1261 } else if (scanner().stack_overflow()) { |
1228 Top::StackOverflow(); | 1262 Top::StackOverflow(); |
1229 } | 1263 } |
1230 } | 1264 } |
1231 | 1265 |
1232 // Make sure the target stack is empty. | 1266 // Make sure the target stack is empty. |
1233 ASSERT(target_stack_ == NULL); | 1267 ASSERT(target_stack_ == NULL); |
1234 | 1268 |
1235 // If there was a syntax error we have to get rid of the AST | 1269 // If there was a syntax error we have to get rid of the AST |
1236 // and it is not safe to do so before the scope has been deleted. | 1270 // and it is not safe to do so before the scope has been deleted. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 } | 1341 } |
1308 | 1342 |
1309 | 1343 |
1310 void PreParser::ReportMessageAt(Scanner::Location source_location, | 1344 void PreParser::ReportMessageAt(Scanner::Location source_location, |
1311 const char* type, | 1345 const char* type, |
1312 Vector<const char*> args) { | 1346 Vector<const char*> args) { |
1313 recorder()->LogMessage(source_location, type, args); | 1347 recorder()->LogMessage(source_location, type, args); |
1314 } | 1348 } |
1315 | 1349 |
1316 | 1350 |
| 1351 // Base class containing common code for the different finder classes used by |
| 1352 // the parser. |
| 1353 class ParserFinder { |
| 1354 protected: |
| 1355 ParserFinder() {} |
| 1356 static Assignment* AsAssignment(Statement* stat) { |
| 1357 if (stat == NULL) return NULL; |
| 1358 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); |
| 1359 if (exp_stat == NULL) return NULL; |
| 1360 return exp_stat->expression()->AsAssignment(); |
| 1361 } |
| 1362 }; |
| 1363 |
| 1364 |
1317 // An InitializationBlockFinder finds and marks sequences of statements of the | 1365 // An InitializationBlockFinder finds and marks sequences of statements of the |
1318 // form x.y.z.a = ...; x.y.z.b = ...; etc. | 1366 // form x.y.z.a = ...; x.y.z.b = ...; etc. |
1319 class InitializationBlockFinder { | 1367 class InitializationBlockFinder : public ParserFinder { |
1320 public: | 1368 public: |
1321 InitializationBlockFinder() | 1369 InitializationBlockFinder() |
1322 : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {} | 1370 : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {} |
1323 | 1371 |
1324 ~InitializationBlockFinder() { | 1372 ~InitializationBlockFinder() { |
1325 if (InBlock()) EndBlock(); | 1373 if (InBlock()) EndBlock(); |
1326 } | 1374 } |
1327 | 1375 |
1328 void Update(Statement* stat) { | 1376 void Update(Statement* stat) { |
1329 Assignment* assignment = AsAssignment(stat); | 1377 Assignment* assignment = AsAssignment(stat); |
1330 if (InBlock()) { | 1378 if (InBlock()) { |
1331 if (BlockContinues(assignment)) { | 1379 if (BlockContinues(assignment)) { |
1332 UpdateBlock(assignment); | 1380 UpdateBlock(assignment); |
1333 } else { | 1381 } else { |
1334 EndBlock(); | 1382 EndBlock(); |
1335 } | 1383 } |
1336 } | 1384 } |
1337 if (!InBlock() && (assignment != NULL) && | 1385 if (!InBlock() && (assignment != NULL) && |
1338 (assignment->op() == Token::ASSIGN)) { | 1386 (assignment->op() == Token::ASSIGN)) { |
1339 StartBlock(assignment); | 1387 StartBlock(assignment); |
1340 } | 1388 } |
1341 } | 1389 } |
1342 | 1390 |
1343 private: | 1391 private: |
1344 static Assignment* AsAssignment(Statement* stat) { | |
1345 if (stat == NULL) return NULL; | |
1346 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); | |
1347 if (exp_stat == NULL) return NULL; | |
1348 return exp_stat->expression()->AsAssignment(); | |
1349 } | |
1350 | |
1351 // Returns true if the expressions appear to denote the same object. | 1392 // Returns true if the expressions appear to denote the same object. |
1352 // In the context of initialization blocks, we only consider expressions | 1393 // In the context of initialization blocks, we only consider expressions |
1353 // of the form 'x.y.z'. | 1394 // of the form 'x.y.z'. |
1354 static bool SameObject(Expression* e1, Expression* e2) { | 1395 static bool SameObject(Expression* e1, Expression* e2) { |
1355 VariableProxy* v1 = e1->AsVariableProxy(); | 1396 VariableProxy* v1 = e1->AsVariableProxy(); |
1356 VariableProxy* v2 = e2->AsVariableProxy(); | 1397 VariableProxy* v2 = e2->AsVariableProxy(); |
1357 if (v1 != NULL && v2 != NULL) { | 1398 if (v1 != NULL && v2 != NULL) { |
1358 return v1->name()->Equals(*v2->name()); | 1399 return v1->name()->Equals(*v2->name()); |
1359 } | 1400 } |
1360 Property* p1 = e1->AsProperty(); | 1401 Property* p1 = e1->AsProperty(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 bool InBlock() { return first_in_block_ != NULL; } | 1452 bool InBlock() { return first_in_block_ != NULL; } |
1412 | 1453 |
1413 Assignment* first_in_block_; | 1454 Assignment* first_in_block_; |
1414 Assignment* last_in_block_; | 1455 Assignment* last_in_block_; |
1415 int block_size_; | 1456 int block_size_; |
1416 | 1457 |
1417 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); | 1458 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); |
1418 }; | 1459 }; |
1419 | 1460 |
1420 | 1461 |
| 1462 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form |
| 1463 // this.x = ...;, where x is a named property. It also determines whether a |
| 1464 // function contains only assignments of this type. |
| 1465 class ThisNamedPropertyAssigmentFinder : public ParserFinder { |
| 1466 public: |
| 1467 ThisNamedPropertyAssigmentFinder() |
| 1468 : only_this_property_assignments_(true), |
| 1469 only_simple_this_property_assignments_(true), |
| 1470 names_(NULL), |
| 1471 assigned_arguments_(NULL), |
| 1472 assigned_constants_(NULL) {} |
| 1473 |
| 1474 void Update(Scope* scope, Statement* stat) { |
| 1475 // Bail out if function already has non this property assignment |
| 1476 // statements. |
| 1477 if (!only_this_property_assignments_) { |
| 1478 return; |
| 1479 } |
| 1480 |
| 1481 // Check whether this statement is of the form this.x = ...; |
| 1482 Assignment* assignment = AsAssignment(stat); |
| 1483 if (IsThisPropertyAssignment(assignment)) { |
| 1484 HandleThisPropertyAssignment(scope, assignment); |
| 1485 } else { |
| 1486 only_this_property_assignments_ = false; |
| 1487 only_simple_this_property_assignments_ = false; |
| 1488 } |
| 1489 } |
| 1490 |
| 1491 // Returns whether only statements of the form this.x = ...; was encountered. |
| 1492 bool only_this_property_assignments() { |
| 1493 return only_this_property_assignments_; |
| 1494 } |
| 1495 |
| 1496 // Returns whether only statements of the form this.x = y; where y is either a |
| 1497 // constant or a function argument was encountered. |
| 1498 bool only_simple_this_property_assignments() { |
| 1499 return only_simple_this_property_assignments_; |
| 1500 } |
| 1501 |
| 1502 // Returns a fixed array containing three elements for each assignment of the |
| 1503 // form this.x = y; |
| 1504 Handle<FixedArray> GetThisPropertyAssignments() { |
| 1505 if (names_ == NULL) { |
| 1506 return Factory::empty_fixed_array(); |
| 1507 } |
| 1508 ASSERT(names_ != NULL); |
| 1509 ASSERT(assigned_arguments_ != NULL); |
| 1510 ASSERT_EQ(names_->length(), assigned_arguments_->length()); |
| 1511 ASSERT_EQ(names_->length(), assigned_constants_->length()); |
| 1512 Handle<FixedArray> assignments = |
| 1513 Factory::NewFixedArray(names_->length() * 3); |
| 1514 for (int i = 0; i < names_->length(); i++) { |
| 1515 assignments->set(i * 3, *names_->at(i)); |
| 1516 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i))); |
| 1517 assignments->set(i * 3 + 2, *assigned_constants_->at(i)); |
| 1518 } |
| 1519 return assignments; |
| 1520 } |
| 1521 |
| 1522 private: |
| 1523 bool IsThisPropertyAssignment(Assignment* assignment) { |
| 1524 if (assignment != NULL) { |
| 1525 Property* property = assignment->target()->AsProperty(); |
| 1526 return assignment->op() == Token::ASSIGN |
| 1527 && property != NULL |
| 1528 && property->obj()->AsVariableProxy() != NULL |
| 1529 && property->obj()->AsVariableProxy()->is_this(); |
| 1530 } |
| 1531 return false; |
| 1532 } |
| 1533 |
| 1534 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) { |
| 1535 // Check that the property assigned to is a named property. |
| 1536 Property* property = assignment->target()->AsProperty(); |
| 1537 ASSERT(property != NULL); |
| 1538 Literal* literal = property->key()->AsLiteral(); |
| 1539 uint32_t dummy; |
| 1540 if (literal != NULL && |
| 1541 literal->handle()->IsString() && |
| 1542 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { |
| 1543 Handle<String> key = Handle<String>::cast(literal->handle()); |
| 1544 |
| 1545 // Check whether the value assigned is either a constant or matches the |
| 1546 // name of one of the arguments to the function. |
| 1547 if (assignment->value()->AsLiteral() != NULL) { |
| 1548 // Constant assigned. |
| 1549 Literal* literal = assignment->value()->AsLiteral(); |
| 1550 AssignmentFromConstant(key, literal->handle()); |
| 1551 } else if (assignment->value()->AsVariableProxy() != NULL) { |
| 1552 // Variable assigned. |
| 1553 Handle<String> name = |
| 1554 assignment->value()->AsVariableProxy()->name(); |
| 1555 // Check whether the variable assigned matches an argument name. |
| 1556 int index = -1; |
| 1557 for (int i = 0; i < scope->num_parameters(); i++) { |
| 1558 if (*scope->parameter(i)->name() == *name) { |
| 1559 // Assigned from function argument. |
| 1560 index = i; |
| 1561 break; |
| 1562 } |
| 1563 } |
| 1564 if (index != -1) { |
| 1565 AssignmentFromParameter(key, index); |
| 1566 } else { |
| 1567 AssignmentFromSomethingElse(key); |
| 1568 } |
| 1569 } else { |
| 1570 AssignmentFromSomethingElse(key); |
| 1571 } |
| 1572 } |
| 1573 } |
| 1574 |
| 1575 void AssignmentFromParameter(Handle<String> name, int index) { |
| 1576 EnsureAllocation(); |
| 1577 names_->Add(name); |
| 1578 assigned_arguments_->Add(index); |
| 1579 assigned_constants_->Add(Factory::undefined_value()); |
| 1580 } |
| 1581 |
| 1582 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { |
| 1583 EnsureAllocation(); |
| 1584 names_->Add(name); |
| 1585 assigned_arguments_->Add(-1); |
| 1586 assigned_constants_->Add(value); |
| 1587 } |
| 1588 |
| 1589 void AssignmentFromSomethingElse(Handle<String> name) { |
| 1590 EnsureAllocation(); |
| 1591 names_->Add(name); |
| 1592 assigned_arguments_->Add(-1); |
| 1593 assigned_constants_->Add(Factory::undefined_value()); |
| 1594 |
| 1595 // The this assignment is not a simple one. |
| 1596 only_simple_this_property_assignments_ = false; |
| 1597 } |
| 1598 |
| 1599 void EnsureAllocation() { |
| 1600 if (names_ == NULL) { |
| 1601 ASSERT(assigned_arguments_ == NULL); |
| 1602 ASSERT(assigned_constants_ == NULL); |
| 1603 names_ = new ZoneStringList(4); |
| 1604 assigned_arguments_ = new ZoneList<int>(4); |
| 1605 assigned_constants_ = new ZoneObjectList(4); |
| 1606 } |
| 1607 } |
| 1608 |
| 1609 bool only_this_property_assignments_; |
| 1610 bool only_simple_this_property_assignments_; |
| 1611 ZoneStringList* names_; |
| 1612 ZoneList<int>* assigned_arguments_; |
| 1613 ZoneObjectList* assigned_constants_; |
| 1614 }; |
| 1615 |
| 1616 |
1421 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, | 1617 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, |
1422 int end_token, | 1618 int end_token, |
1423 bool* ok) { | 1619 bool* ok) { |
1424 // SourceElements :: | 1620 // SourceElements :: |
1425 // (Statement)* <end_token> | 1621 // (Statement)* <end_token> |
1426 | 1622 |
1427 // Allocate a target stack to use for this set of source | 1623 // Allocate a target stack to use for this set of source |
1428 // elements. This way, all scripts and functions get their own | 1624 // elements. This way, all scripts and functions get their own |
1429 // target stack thus avoiding illegal breaks and continues across | 1625 // target stack thus avoiding illegal breaks and continues across |
1430 // functions. | 1626 // functions. |
1431 TargetScope scope(this); | 1627 TargetScope scope(this); |
1432 | 1628 |
1433 ASSERT(processor != NULL); | 1629 ASSERT(processor != NULL); |
1434 InitializationBlockFinder block_finder; | 1630 InitializationBlockFinder block_finder; |
| 1631 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; |
1435 while (peek() != end_token) { | 1632 while (peek() != end_token) { |
1436 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1633 Statement* stat = ParseStatement(NULL, CHECK_OK); |
1437 if (stat == NULL || stat->IsEmpty()) continue; | 1634 if (stat == NULL || stat->IsEmpty()) continue; |
1438 // We find and mark the initialization blocks on top level code only. | 1635 // We find and mark the initialization blocks on top level code only. |
1439 // This is because the optimization prevents reuse of the map transitions, | 1636 // This is because the optimization prevents reuse of the map transitions, |
1440 // so it should be used only for code that will only be run once. | 1637 // so it should be used only for code that will only be run once. |
1441 if (top_scope_->is_global_scope()) block_finder.Update(stat); | 1638 if (top_scope_->is_global_scope()) { |
| 1639 block_finder.Update(stat); |
| 1640 } |
| 1641 // Find and mark all assignments to named properties in this (this.x =) |
| 1642 if (top_scope_->is_function_scope()) { |
| 1643 this_property_assignment_finder.Update(top_scope_, stat); |
| 1644 } |
1442 processor->Add(stat); | 1645 processor->Add(stat); |
1443 } | 1646 } |
| 1647 |
| 1648 // Propagate the collected information on this property assignments. |
| 1649 if (top_scope_->is_function_scope()) { |
| 1650 if (this_property_assignment_finder.only_this_property_assignments()) { |
| 1651 temp_scope_->SetThisPropertyAssignmentInfo( |
| 1652 this_property_assignment_finder.only_this_property_assignments(), |
| 1653 this_property_assignment_finder. |
| 1654 only_simple_this_property_assignments(), |
| 1655 this_property_assignment_finder.GetThisPropertyAssignments()); |
| 1656 } |
| 1657 } |
1444 return 0; | 1658 return 0; |
1445 } | 1659 } |
1446 | 1660 |
1447 | 1661 |
1448 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1662 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
1449 // Statement :: | 1663 // Statement :: |
1450 // Block | 1664 // Block |
1451 // VariableStatement | 1665 // VariableStatement |
1452 // EmptyStatement | 1666 // EmptyStatement |
1453 // ExpressionStatement | 1667 // ExpressionStatement |
(...skipping 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3500 } | 3714 } |
3501 | 3715 |
3502 // Determine if the function will be lazily compiled. The mode can | 3716 // Determine if the function will be lazily compiled. The mode can |
3503 // only be PARSE_LAZILY if the --lazy flag is true. | 3717 // only be PARSE_LAZILY if the --lazy flag is true. |
3504 bool is_lazily_compiled = | 3718 bool is_lazily_compiled = |
3505 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); | 3719 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); |
3506 | 3720 |
3507 int materialized_literal_count; | 3721 int materialized_literal_count; |
3508 int expected_property_count; | 3722 int expected_property_count; |
3509 bool contains_array_literal; | 3723 bool contains_array_literal; |
| 3724 bool only_this_property_assignments; |
| 3725 bool only_simple_this_property_assignments; |
| 3726 Handle<FixedArray> this_property_assignments; |
3510 if (is_lazily_compiled && pre_data() != NULL) { | 3727 if (is_lazily_compiled && pre_data() != NULL) { |
3511 FunctionEntry entry = pre_data()->GetFunctionEnd(start_pos); | 3728 FunctionEntry entry = pre_data()->GetFunctionEnd(start_pos); |
3512 int end_pos = entry.end_pos(); | 3729 int end_pos = entry.end_pos(); |
3513 Counters::total_preparse_skipped.Increment(end_pos - start_pos); | 3730 Counters::total_preparse_skipped.Increment(end_pos - start_pos); |
3514 scanner_.SeekForward(end_pos); | 3731 scanner_.SeekForward(end_pos); |
3515 materialized_literal_count = entry.literal_count(); | 3732 materialized_literal_count = entry.literal_count(); |
3516 expected_property_count = entry.property_count(); | 3733 expected_property_count = entry.property_count(); |
| 3734 only_this_property_assignments = false; |
| 3735 only_simple_this_property_assignments = false; |
| 3736 this_property_assignments = Factory::empty_fixed_array(); |
3517 contains_array_literal = entry.contains_array_literal(); | 3737 contains_array_literal = entry.contains_array_literal(); |
3518 } else { | 3738 } else { |
3519 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | 3739 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); |
3520 materialized_literal_count = temp_scope.materialized_literal_count(); | 3740 materialized_literal_count = temp_scope.materialized_literal_count(); |
3521 expected_property_count = temp_scope.expected_property_count(); | 3741 expected_property_count = temp_scope.expected_property_count(); |
3522 contains_array_literal = temp_scope.contains_array_literal(); | 3742 contains_array_literal = temp_scope.contains_array_literal(); |
| 3743 only_this_property_assignments = |
| 3744 temp_scope.only_this_property_assignments(); |
| 3745 only_simple_this_property_assignments = |
| 3746 temp_scope.only_simple_this_property_assignments(); |
| 3747 this_property_assignments = temp_scope.this_property_assignments(); |
3523 } | 3748 } |
3524 | 3749 |
3525 Expect(Token::RBRACE, CHECK_OK); | 3750 Expect(Token::RBRACE, CHECK_OK); |
3526 int end_pos = scanner_.location().end_pos; | 3751 int end_pos = scanner_.location().end_pos; |
3527 | 3752 |
3528 FunctionEntry entry = log()->LogFunction(start_pos); | 3753 FunctionEntry entry = log()->LogFunction(start_pos); |
3529 if (entry.is_valid()) { | 3754 if (entry.is_valid()) { |
3530 entry.set_end_pos(end_pos); | 3755 entry.set_end_pos(end_pos); |
3531 entry.set_literal_count(materialized_literal_count); | 3756 entry.set_literal_count(materialized_literal_count); |
3532 entry.set_property_count(expected_property_count); | 3757 entry.set_property_count(expected_property_count); |
3533 entry.set_contains_array_literal(contains_array_literal); | 3758 entry.set_contains_array_literal(contains_array_literal); |
3534 } | 3759 } |
3535 | 3760 |
3536 FunctionLiteral* function_literal = | 3761 FunctionLiteral* function_literal = |
3537 NEW(FunctionLiteral(name, top_scope_, | 3762 NEW(FunctionLiteral(name, |
3538 body.elements(), materialized_literal_count, | 3763 top_scope_, |
3539 contains_array_literal, expected_property_count, | 3764 body.elements(), |
3540 num_parameters, start_pos, end_pos, | 3765 materialized_literal_count, |
| 3766 contains_array_literal, |
| 3767 expected_property_count, |
| 3768 only_this_property_assignments, |
| 3769 only_simple_this_property_assignments, |
| 3770 this_property_assignments, |
| 3771 num_parameters, |
| 3772 start_pos, |
| 3773 end_pos, |
3541 function_name->length() > 0)); | 3774 function_name->length() > 0)); |
3542 if (!is_pre_parsing_) { | 3775 if (!is_pre_parsing_) { |
3543 function_literal->set_function_token_position(function_token_position); | 3776 function_literal->set_function_token_position(function_token_position); |
3544 } | 3777 } |
3545 return function_literal; | 3778 return function_literal; |
3546 } | 3779 } |
3547 } | 3780 } |
3548 | 3781 |
3549 | 3782 |
3550 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3783 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4681 start_position, | 4914 start_position, |
4682 is_expression); | 4915 is_expression); |
4683 return result; | 4916 return result; |
4684 } | 4917 } |
4685 | 4918 |
4686 | 4919 |
4687 #undef NEW | 4920 #undef NEW |
4688 | 4921 |
4689 | 4922 |
4690 } } // namespace v8::internal | 4923 } } // namespace v8::internal |
OLD | NEW |