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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 | 669 |
670 int NextMaterializedLiteralIndex() { | 670 int NextMaterializedLiteralIndex() { |
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 SetThisPropertyAssignmentInfo( | 678 void SetThisPropertyAssignmentInfo( |
679 bool only_this_property_assignments, | |
680 bool only_simple_this_property_assignments, | 679 bool only_simple_this_property_assignments, |
681 Handle<FixedArray> this_property_assignments) { | 680 Handle<FixedArray> this_property_assignments) { |
682 only_this_property_assignments_ = only_this_property_assignments; | |
683 only_simple_this_property_assignments_ = | 681 only_simple_this_property_assignments_ = |
684 only_simple_this_property_assignments; | 682 only_simple_this_property_assignments; |
685 this_property_assignments_ = this_property_assignments; | 683 this_property_assignments_ = this_property_assignments; |
686 } | 684 } |
687 bool only_this_property_assignments() { | |
688 return only_this_property_assignments_; | |
689 } | |
690 bool only_simple_this_property_assignments() { | 685 bool only_simple_this_property_assignments() { |
691 return only_simple_this_property_assignments_; | 686 return only_simple_this_property_assignments_; |
692 } | 687 } |
693 Handle<FixedArray> this_property_assignments() { | 688 Handle<FixedArray> this_property_assignments() { |
694 return this_property_assignments_; | 689 return this_property_assignments_; |
695 } | 690 } |
696 | 691 |
697 void AddProperty() { expected_property_count_++; } | 692 void AddProperty() { expected_property_count_++; } |
698 int expected_property_count() { return expected_property_count_; } | 693 int expected_property_count() { return expected_property_count_; } |
699 private: | 694 private: |
700 // Captures the number of literals that need materialization in the | 695 // Captures the number of literals that need materialization in the |
701 // function. Includes regexp literals, and boilerplate for object | 696 // function. Includes regexp literals, and boilerplate for object |
702 // and array literals. | 697 // and array literals. |
703 int materialized_literal_count_; | 698 int materialized_literal_count_; |
704 | 699 |
705 // Properties count estimation. | 700 // Properties count estimation. |
706 int expected_property_count_; | 701 int expected_property_count_; |
707 | 702 |
708 bool only_this_property_assignments_; | |
709 bool only_simple_this_property_assignments_; | 703 bool only_simple_this_property_assignments_; |
710 Handle<FixedArray> this_property_assignments_; | 704 Handle<FixedArray> this_property_assignments_; |
711 | 705 |
712 // Bookkeeping | 706 // Bookkeeping |
713 Parser* parser_; | 707 Parser* parser_; |
714 TemporaryScope* parent_; | 708 TemporaryScope* parent_; |
715 | 709 |
716 friend class Parser; | 710 friend class Parser; |
717 }; | 711 }; |
718 | 712 |
719 | 713 |
720 TemporaryScope::TemporaryScope(Parser* parser) | 714 TemporaryScope::TemporaryScope(Parser* parser) |
721 : materialized_literal_count_(0), | 715 : materialized_literal_count_(0), |
722 expected_property_count_(0), | 716 expected_property_count_(0), |
723 only_this_property_assignments_(false), | |
724 only_simple_this_property_assignments_(false), | 717 only_simple_this_property_assignments_(false), |
725 this_property_assignments_(Factory::empty_fixed_array()), | 718 this_property_assignments_(Factory::empty_fixed_array()), |
726 parser_(parser), | 719 parser_(parser), |
727 parent_(parser->temp_scope_) { | 720 parent_(parser->temp_scope_) { |
728 parser->temp_scope_ = this; | 721 parser->temp_scope_ = this; |
729 } | 722 } |
730 | 723 |
731 | 724 |
732 TemporaryScope::~TemporaryScope() { | 725 TemporaryScope::~TemporaryScope() { |
733 parser_->temp_scope_ = parent_; | 726 parser_->temp_scope_ = parent_; |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 ZoneListWrapper<Statement> body(16); | 1213 ZoneListWrapper<Statement> body(16); |
1221 bool ok = true; | 1214 bool ok = true; |
1222 ParseSourceElements(&body, Token::EOS, &ok); | 1215 ParseSourceElements(&body, Token::EOS, &ok); |
1223 if (ok) { | 1216 if (ok) { |
1224 result = NEW(FunctionLiteral( | 1217 result = NEW(FunctionLiteral( |
1225 no_name, | 1218 no_name, |
1226 top_scope_, | 1219 top_scope_, |
1227 body.elements(), | 1220 body.elements(), |
1228 temp_scope.materialized_literal_count(), | 1221 temp_scope.materialized_literal_count(), |
1229 temp_scope.expected_property_count(), | 1222 temp_scope.expected_property_count(), |
1230 temp_scope.only_this_property_assignments(), | |
1231 temp_scope.only_simple_this_property_assignments(), | 1223 temp_scope.only_simple_this_property_assignments(), |
1232 temp_scope.this_property_assignments(), | 1224 temp_scope.this_property_assignments(), |
1233 0, | 1225 0, |
1234 0, | 1226 0, |
1235 source->length(), | 1227 source->length(), |
1236 false)); | 1228 false)); |
1237 } else if (scanner().stack_overflow()) { | 1229 } else if (scanner().stack_overflow()) { |
1238 Top::StackOverflow(); | 1230 Top::StackOverflow(); |
1239 } | 1231 } |
1240 } | 1232 } |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); | 1426 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); |
1435 }; | 1427 }; |
1436 | 1428 |
1437 | 1429 |
1438 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form | 1430 // A ThisNamedPropertyAssigmentFinder finds and marks statements of the form |
1439 // this.x = ...;, where x is a named property. It also determines whether a | 1431 // this.x = ...;, where x is a named property. It also determines whether a |
1440 // function contains only assignments of this type. | 1432 // function contains only assignments of this type. |
1441 class ThisNamedPropertyAssigmentFinder : public ParserFinder { | 1433 class ThisNamedPropertyAssigmentFinder : public ParserFinder { |
1442 public: | 1434 public: |
1443 ThisNamedPropertyAssigmentFinder() | 1435 ThisNamedPropertyAssigmentFinder() |
1444 : only_this_property_assignments_(true), | 1436 : only_simple_this_property_assignments_(true), |
1445 only_simple_this_property_assignments_(true), | |
1446 names_(NULL), | 1437 names_(NULL), |
1447 assigned_arguments_(NULL), | 1438 assigned_arguments_(NULL), |
1448 assigned_constants_(NULL) {} | 1439 assigned_constants_(NULL) {} |
1449 | 1440 |
1450 void Update(Scope* scope, Statement* stat) { | 1441 void Update(Scope* scope, Statement* stat) { |
1451 // Bail out if function already has non this property assignment | 1442 // Bail out if function already has property assignment that are |
1452 // statements. | 1443 // not simple this property assignments. |
1453 if (!only_this_property_assignments_) { | 1444 if (!only_simple_this_property_assignments_) { |
1454 return; | 1445 return; |
1455 } | 1446 } |
1456 | 1447 |
1457 // Check whether this statement is of the form this.x = ...; | 1448 // Check whether this statement is of the form this.x = ...; |
1458 Assignment* assignment = AsAssignment(stat); | 1449 Assignment* assignment = AsAssignment(stat); |
1459 if (IsThisPropertyAssignment(assignment)) { | 1450 if (IsThisPropertyAssignment(assignment)) { |
1460 HandleThisPropertyAssignment(scope, assignment); | 1451 HandleThisPropertyAssignment(scope, assignment); |
1461 } else { | 1452 } else { |
1462 only_this_property_assignments_ = false; | |
1463 only_simple_this_property_assignments_ = false; | 1453 only_simple_this_property_assignments_ = false; |
1464 } | 1454 } |
1465 } | 1455 } |
1466 | 1456 |
1467 // Returns whether only statements of the form this.x = ...; was encountered. | |
1468 bool only_this_property_assignments() { | |
1469 return only_this_property_assignments_; | |
1470 } | |
1471 | |
1472 // Returns whether only statements of the form this.x = y; where y is either a | 1457 // Returns whether only statements of the form this.x = y; where y is either a |
1473 // constant or a function argument was encountered. | 1458 // constant or a function argument was encountered. |
1474 bool only_simple_this_property_assignments() { | 1459 bool only_simple_this_property_assignments() { |
1475 return only_simple_this_property_assignments_; | 1460 return only_simple_this_property_assignments_; |
1476 } | 1461 } |
1477 | 1462 |
1478 // Returns a fixed array containing three elements for each assignment of the | 1463 // Returns a fixed array containing three elements for each assignment of the |
1479 // form this.x = y; | 1464 // form this.x = y; |
1480 Handle<FixedArray> GetThisPropertyAssignments() { | 1465 Handle<FixedArray> GetThisPropertyAssignments() { |
1481 if (names_ == NULL) { | 1466 if (names_ == NULL) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 literal->handle()->IsString() && | 1502 literal->handle()->IsString() && |
1518 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { | 1503 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { |
1519 Handle<String> key = Handle<String>::cast(literal->handle()); | 1504 Handle<String> key = Handle<String>::cast(literal->handle()); |
1520 | 1505 |
1521 // Check whether the value assigned is either a constant or matches the | 1506 // Check whether the value assigned is either a constant or matches the |
1522 // name of one of the arguments to the function. | 1507 // name of one of the arguments to the function. |
1523 if (assignment->value()->AsLiteral() != NULL) { | 1508 if (assignment->value()->AsLiteral() != NULL) { |
1524 // Constant assigned. | 1509 // Constant assigned. |
1525 Literal* literal = assignment->value()->AsLiteral(); | 1510 Literal* literal = assignment->value()->AsLiteral(); |
1526 AssignmentFromConstant(key, literal->handle()); | 1511 AssignmentFromConstant(key, literal->handle()); |
| 1512 return; |
1527 } else if (assignment->value()->AsVariableProxy() != NULL) { | 1513 } else if (assignment->value()->AsVariableProxy() != NULL) { |
1528 // Variable assigned. | 1514 // Variable assigned. |
1529 Handle<String> name = | 1515 Handle<String> name = |
1530 assignment->value()->AsVariableProxy()->name(); | 1516 assignment->value()->AsVariableProxy()->name(); |
1531 // Check whether the variable assigned matches an argument name. | 1517 // Check whether the variable assigned matches an argument name. |
1532 int index = -1; | |
1533 for (int i = 0; i < scope->num_parameters(); i++) { | 1518 for (int i = 0; i < scope->num_parameters(); i++) { |
1534 if (*scope->parameter(i)->name() == *name) { | 1519 if (*scope->parameter(i)->name() == *name) { |
1535 // Assigned from function argument. | 1520 // Assigned from function argument. |
1536 index = i; | 1521 AssignmentFromParameter(key, i); |
1537 break; | 1522 return; |
1538 } | 1523 } |
1539 } | 1524 } |
1540 if (index != -1) { | |
1541 AssignmentFromParameter(key, index); | |
1542 } else { | |
1543 AssignmentFromSomethingElse(key); | |
1544 } | |
1545 } else { | |
1546 AssignmentFromSomethingElse(key); | |
1547 } | 1525 } |
1548 } | 1526 } |
| 1527 // It is not a simple "this.x = value;" assignment with a constant |
| 1528 // or parameter value. |
| 1529 AssignmentFromSomethingElse(); |
1549 } | 1530 } |
1550 | 1531 |
1551 void AssignmentFromParameter(Handle<String> name, int index) { | 1532 void AssignmentFromParameter(Handle<String> name, int index) { |
1552 EnsureAllocation(); | 1533 EnsureAllocation(); |
1553 names_->Add(name); | 1534 names_->Add(name); |
1554 assigned_arguments_->Add(index); | 1535 assigned_arguments_->Add(index); |
1555 assigned_constants_->Add(Factory::undefined_value()); | 1536 assigned_constants_->Add(Factory::undefined_value()); |
1556 } | 1537 } |
1557 | 1538 |
1558 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { | 1539 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { |
1559 EnsureAllocation(); | 1540 EnsureAllocation(); |
1560 names_->Add(name); | 1541 names_->Add(name); |
1561 assigned_arguments_->Add(-1); | 1542 assigned_arguments_->Add(-1); |
1562 assigned_constants_->Add(value); | 1543 assigned_constants_->Add(value); |
1563 } | 1544 } |
1564 | 1545 |
1565 void AssignmentFromSomethingElse(Handle<String> name) { | 1546 void AssignmentFromSomethingElse() { |
1566 EnsureAllocation(); | |
1567 names_->Add(name); | |
1568 assigned_arguments_->Add(-1); | |
1569 assigned_constants_->Add(Factory::undefined_value()); | |
1570 | |
1571 // The this assignment is not a simple one. | 1547 // The this assignment is not a simple one. |
1572 only_simple_this_property_assignments_ = false; | 1548 only_simple_this_property_assignments_ = false; |
1573 } | 1549 } |
1574 | 1550 |
1575 void EnsureAllocation() { | 1551 void EnsureAllocation() { |
1576 if (names_ == NULL) { | 1552 if (names_ == NULL) { |
1577 ASSERT(assigned_arguments_ == NULL); | 1553 ASSERT(assigned_arguments_ == NULL); |
1578 ASSERT(assigned_constants_ == NULL); | 1554 ASSERT(assigned_constants_ == NULL); |
1579 names_ = new ZoneStringList(4); | 1555 names_ = new ZoneStringList(4); |
1580 assigned_arguments_ = new ZoneList<int>(4); | 1556 assigned_arguments_ = new ZoneList<int>(4); |
1581 assigned_constants_ = new ZoneObjectList(4); | 1557 assigned_constants_ = new ZoneObjectList(4); |
1582 } | 1558 } |
1583 } | 1559 } |
1584 | 1560 |
1585 bool only_this_property_assignments_; | |
1586 bool only_simple_this_property_assignments_; | 1561 bool only_simple_this_property_assignments_; |
1587 ZoneStringList* names_; | 1562 ZoneStringList* names_; |
1588 ZoneList<int>* assigned_arguments_; | 1563 ZoneList<int>* assigned_arguments_; |
1589 ZoneObjectList* assigned_constants_; | 1564 ZoneObjectList* assigned_constants_; |
1590 }; | 1565 }; |
1591 | 1566 |
1592 | 1567 |
1593 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, | 1568 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, |
1594 int end_token, | 1569 int end_token, |
1595 bool* ok) { | 1570 bool* ok) { |
(...skipping 20 matching lines...) Expand all Loading... |
1616 } | 1591 } |
1617 // Find and mark all assignments to named properties in this (this.x =) | 1592 // Find and mark all assignments to named properties in this (this.x =) |
1618 if (top_scope_->is_function_scope()) { | 1593 if (top_scope_->is_function_scope()) { |
1619 this_property_assignment_finder.Update(top_scope_, stat); | 1594 this_property_assignment_finder.Update(top_scope_, stat); |
1620 } | 1595 } |
1621 processor->Add(stat); | 1596 processor->Add(stat); |
1622 } | 1597 } |
1623 | 1598 |
1624 // Propagate the collected information on this property assignments. | 1599 // Propagate the collected information on this property assignments. |
1625 if (top_scope_->is_function_scope()) { | 1600 if (top_scope_->is_function_scope()) { |
1626 if (this_property_assignment_finder.only_this_property_assignments()) { | 1601 bool only_simple_this_property_assignments = |
| 1602 this_property_assignment_finder.only_simple_this_property_assignments(); |
| 1603 if (only_simple_this_property_assignments) { |
1627 temp_scope_->SetThisPropertyAssignmentInfo( | 1604 temp_scope_->SetThisPropertyAssignmentInfo( |
1628 this_property_assignment_finder.only_this_property_assignments(), | 1605 only_simple_this_property_assignments, |
1629 this_property_assignment_finder. | |
1630 only_simple_this_property_assignments(), | |
1631 this_property_assignment_finder.GetThisPropertyAssignments()); | 1606 this_property_assignment_finder.GetThisPropertyAssignments()); |
1632 } | 1607 } |
1633 } | 1608 } |
1634 return 0; | 1609 return 0; |
1635 } | 1610 } |
1636 | 1611 |
1637 | 1612 |
1638 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1613 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
1639 // Statement :: | 1614 // Statement :: |
1640 // Block | 1615 // Block |
(...skipping 1976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3617 RelocInfo::kNoPosition))); | 3592 RelocInfo::kNoPosition))); |
3618 } | 3593 } |
3619 | 3594 |
3620 // Determine if the function will be lazily compiled. The mode can | 3595 // Determine if the function will be lazily compiled. The mode can |
3621 // only be PARSE_LAZILY if the --lazy flag is true. | 3596 // only be PARSE_LAZILY if the --lazy flag is true. |
3622 bool is_lazily_compiled = | 3597 bool is_lazily_compiled = |
3623 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); | 3598 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); |
3624 | 3599 |
3625 int materialized_literal_count; | 3600 int materialized_literal_count; |
3626 int expected_property_count; | 3601 int expected_property_count; |
3627 bool only_this_property_assignments; | |
3628 bool only_simple_this_property_assignments; | 3602 bool only_simple_this_property_assignments; |
3629 Handle<FixedArray> this_property_assignments; | 3603 Handle<FixedArray> this_property_assignments; |
3630 if (is_lazily_compiled && pre_data() != NULL) { | 3604 if (is_lazily_compiled && pre_data() != NULL) { |
3631 FunctionEntry entry = pre_data()->GetFunctionEnd(start_pos); | 3605 FunctionEntry entry = pre_data()->GetFunctionEnd(start_pos); |
3632 int end_pos = entry.end_pos(); | 3606 int end_pos = entry.end_pos(); |
3633 Counters::total_preparse_skipped.Increment(end_pos - start_pos); | 3607 Counters::total_preparse_skipped.Increment(end_pos - start_pos); |
3634 scanner_.SeekForward(end_pos); | 3608 scanner_.SeekForward(end_pos); |
3635 materialized_literal_count = entry.literal_count(); | 3609 materialized_literal_count = entry.literal_count(); |
3636 expected_property_count = entry.property_count(); | 3610 expected_property_count = entry.property_count(); |
3637 only_this_property_assignments = false; | |
3638 only_simple_this_property_assignments = false; | 3611 only_simple_this_property_assignments = false; |
3639 this_property_assignments = Factory::empty_fixed_array(); | 3612 this_property_assignments = Factory::empty_fixed_array(); |
3640 } else { | 3613 } else { |
3641 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | 3614 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); |
3642 materialized_literal_count = temp_scope.materialized_literal_count(); | 3615 materialized_literal_count = temp_scope.materialized_literal_count(); |
3643 expected_property_count = temp_scope.expected_property_count(); | 3616 expected_property_count = temp_scope.expected_property_count(); |
3644 only_this_property_assignments = | |
3645 temp_scope.only_this_property_assignments(); | |
3646 only_simple_this_property_assignments = | 3617 only_simple_this_property_assignments = |
3647 temp_scope.only_simple_this_property_assignments(); | 3618 temp_scope.only_simple_this_property_assignments(); |
3648 this_property_assignments = temp_scope.this_property_assignments(); | 3619 this_property_assignments = temp_scope.this_property_assignments(); |
3649 } | 3620 } |
3650 | 3621 |
3651 Expect(Token::RBRACE, CHECK_OK); | 3622 Expect(Token::RBRACE, CHECK_OK); |
3652 int end_pos = scanner_.location().end_pos; | 3623 int end_pos = scanner_.location().end_pos; |
3653 | 3624 |
3654 FunctionEntry entry = log()->LogFunction(start_pos); | 3625 FunctionEntry entry = log()->LogFunction(start_pos); |
3655 if (entry.is_valid()) { | 3626 if (entry.is_valid()) { |
3656 entry.set_end_pos(end_pos); | 3627 entry.set_end_pos(end_pos); |
3657 entry.set_literal_count(materialized_literal_count); | 3628 entry.set_literal_count(materialized_literal_count); |
3658 entry.set_property_count(expected_property_count); | 3629 entry.set_property_count(expected_property_count); |
3659 } | 3630 } |
3660 | 3631 |
3661 FunctionLiteral* function_literal = | 3632 FunctionLiteral* function_literal = |
3662 NEW(FunctionLiteral(name, | 3633 NEW(FunctionLiteral(name, |
3663 top_scope_, | 3634 top_scope_, |
3664 body.elements(), | 3635 body.elements(), |
3665 materialized_literal_count, | 3636 materialized_literal_count, |
3666 expected_property_count, | 3637 expected_property_count, |
3667 only_this_property_assignments, | |
3668 only_simple_this_property_assignments, | 3638 only_simple_this_property_assignments, |
3669 this_property_assignments, | 3639 this_property_assignments, |
3670 num_parameters, | 3640 num_parameters, |
3671 start_pos, | 3641 start_pos, |
3672 end_pos, | 3642 end_pos, |
3673 function_name->length() > 0)); | 3643 function_name->length() > 0)); |
3674 if (!is_pre_parsing_) { | 3644 if (!is_pre_parsing_) { |
3675 function_literal->set_function_token_position(function_token_position); | 3645 function_literal->set_function_token_position(function_token_position); |
3676 } | 3646 } |
3677 return function_literal; | 3647 return function_literal; |
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4811 start_position, | 4781 start_position, |
4812 is_expression); | 4782 is_expression); |
4813 return result; | 4783 return result; |
4814 } | 4784 } |
4815 | 4785 |
4816 | 4786 |
4817 #undef NEW | 4787 #undef NEW |
4818 | 4788 |
4819 | 4789 |
4820 } } // namespace v8::internal | 4790 } } // namespace v8::internal |
OLD | NEW |