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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 // character was. | 460 // character was. |
461 bool follows_word_interest: 1; | 461 bool follows_word_interest: 1; |
462 bool follows_newline_interest: 1; | 462 bool follows_newline_interest: 1; |
463 bool follows_start_interest: 1; | 463 bool follows_start_interest: 1; |
464 | 464 |
465 bool at_end: 1; | 465 bool at_end: 1; |
466 bool visited: 1; | 466 bool visited: 1; |
467 }; | 467 }; |
468 | 468 |
469 | 469 |
470 class SiblingList { | |
471 public: | |
472 SiblingList() : list_(NULL) { } | |
473 int length() { | |
474 return list_ == NULL ? 0 : list_->length(); | |
475 } | |
476 void Ensure(RegExpNode* parent) { | |
477 if (list_ == NULL) { | |
478 list_ = new ZoneList<RegExpNode*>(2); | |
479 list_->Add(parent); | |
480 } | |
481 } | |
482 void Add(RegExpNode* node) { list_->Add(node); } | |
483 RegExpNode* Get(int index) { return list_->at(index); } | |
484 private: | |
485 ZoneList<RegExpNode*>* list_; | |
486 }; | |
487 | |
488 | |
489 // Details of a quick mask-compare check that can look ahead in the | 470 // Details of a quick mask-compare check that can look ahead in the |
490 // input stream. | 471 // input stream. |
491 class QuickCheckDetails { | 472 class QuickCheckDetails { |
492 public: | 473 public: |
493 QuickCheckDetails() | 474 QuickCheckDetails() |
494 : characters_(0), | 475 : characters_(0), |
495 mask_(0), | 476 mask_(0), |
496 value_(0), | 477 value_(0), |
497 cannot_match_(false) { } | 478 cannot_match_(false) { } |
498 explicit QuickCheckDetails(int characters) | 479 explicit QuickCheckDetails(int characters) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 uint32_t mask_; | 514 uint32_t mask_; |
534 uint32_t value_; | 515 uint32_t value_; |
535 // If set to true, there is no way this quick check can match at all. | 516 // If set to true, there is no way this quick check can match at all. |
536 // E.g., if it requires to be at the start of the input, and isn't. | 517 // E.g., if it requires to be at the start of the input, and isn't. |
537 bool cannot_match_; | 518 bool cannot_match_; |
538 }; | 519 }; |
539 | 520 |
540 | 521 |
541 class RegExpNode: public ZoneObject { | 522 class RegExpNode: public ZoneObject { |
542 public: | 523 public: |
543 RegExpNode() : first_character_set_(NULL), trace_count_(0) { | 524 RegExpNode() : trace_count_(0) { |
544 bm_info_[0] = bm_info_[1] = NULL; | 525 bm_info_[0] = bm_info_[1] = NULL; |
545 } | 526 } |
546 virtual ~RegExpNode(); | 527 virtual ~RegExpNode(); |
547 virtual void Accept(NodeVisitor* visitor) = 0; | 528 virtual void Accept(NodeVisitor* visitor) = 0; |
548 // Generates a goto to this node or actually generates the code at this point. | 529 // Generates a goto to this node or actually generates the code at this point. |
549 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; | 530 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; |
550 // How many characters must this node consume at a minimum in order to | 531 // How many characters must this node consume at a minimum in order to |
551 // succeed. If we have found at least 'still_to_find' characters that | 532 // succeed. If we have found at least 'still_to_find' characters that |
552 // must be consumed there is no need to ask any following nodes whether | 533 // must be consumed there is no need to ask any following nodes whether |
553 // they are sure to eat any more characters. The not_at_start argument is | 534 // they are sure to eat any more characters. The not_at_start argument is |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 Label* label() { return &label_; } | 583 Label* label() { return &label_; } |
603 // If non-generic code is generated for a node (i.e. the node is not at the | 584 // If non-generic code is generated for a node (i.e. the node is not at the |
604 // start of the trace) then it cannot be reused. This variable sets a limit | 585 // start of the trace) then it cannot be reused. This variable sets a limit |
605 // on how often we allow that to happen before we insist on starting a new | 586 // on how often we allow that to happen before we insist on starting a new |
606 // trace and generating generic code for a node that can be reused by flushing | 587 // trace and generating generic code for a node that can be reused by flushing |
607 // the deferred actions in the current trace and generating a goto. | 588 // the deferred actions in the current trace and generating a goto. |
608 static const int kMaxCopiesCodeGenerated = 10; | 589 static const int kMaxCopiesCodeGenerated = 10; |
609 | 590 |
610 NodeInfo* info() { return &info_; } | 591 NodeInfo* info() { return &info_; } |
611 | 592 |
612 void AddSibling(RegExpNode* node) { siblings_.Add(node); } | |
613 | |
614 // Static version of EnsureSibling that expresses the fact that the | |
615 // result has the same type as the input. | |
616 template <class C> | |
617 static C* EnsureSibling(C* node, NodeInfo* info, bool* cloned) { | |
618 return static_cast<C*>(node->EnsureSibling(info, cloned)); | |
619 } | |
620 | |
621 SiblingList* siblings() { return &siblings_; } | |
622 void set_siblings(SiblingList* other) { siblings_ = *other; } | |
623 | |
624 // Get and set the cached first character set value. | |
625 ZoneList<CharacterRange>* first_character_set() { | |
626 return first_character_set_; | |
627 } | |
628 void set_first_character_set(ZoneList<CharacterRange>* character_set) { | |
629 first_character_set_ = character_set; | |
630 } | |
631 BoyerMooreLookahead* bm_info(bool not_at_start) { | 593 BoyerMooreLookahead* bm_info(bool not_at_start) { |
632 return bm_info_[not_at_start ? 1 : 0]; | 594 return bm_info_[not_at_start ? 1 : 0]; |
633 } | 595 } |
634 | 596 |
635 protected: | 597 protected: |
636 enum LimitResult { DONE, CONTINUE }; | 598 enum LimitResult { DONE, CONTINUE }; |
637 static const int kComputeFirstCharacterSetFail = -1; | |
638 | 599 |
639 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); | 600 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); |
640 | 601 |
641 // Returns a sibling of this node whose interests and assumptions | |
642 // match the ones in the given node info. If no sibling exists NULL | |
643 // is returned. | |
644 RegExpNode* TryGetSibling(NodeInfo* info); | |
645 | |
646 // Returns a sibling of this node whose interests match the ones in | |
647 // the given node info. The info must not contain any assertions. | |
648 // If no node exists a new one will be created by cloning the current | |
649 // node. The result will always be an instance of the same concrete | |
650 // class as this node. | |
651 RegExpNode* EnsureSibling(NodeInfo* info, bool* cloned); | |
652 | |
653 // Returns a clone of this node initialized using the copy constructor | 602 // Returns a clone of this node initialized using the copy constructor |
654 // of its concrete class. Note that the node may have to be pre- | 603 // of its concrete class. Note that the node may have to be pre- |
655 // processed before it is on a usable state. | 604 // processed before it is on a usable state. |
656 virtual RegExpNode* Clone() = 0; | 605 virtual RegExpNode* Clone() = 0; |
657 | 606 |
658 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { | 607 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { |
659 bm_info_[not_at_start ? 1 : 0] = bm; | 608 bm_info_[not_at_start ? 1 : 0] = bm; |
660 } | 609 } |
661 | 610 |
662 private: | 611 private: |
663 static const int kFirstCharBudget = 10; | 612 static const int kFirstCharBudget = 10; |
664 Label label_; | 613 Label label_; |
665 NodeInfo info_; | 614 NodeInfo info_; |
666 SiblingList siblings_; | |
667 ZoneList<CharacterRange>* first_character_set_; | |
668 // This variable keeps track of how many times code has been generated for | 615 // This variable keeps track of how many times code has been generated for |
669 // this node (in different traces). We don't keep track of where the | 616 // this node (in different traces). We don't keep track of where the |
670 // generated code is located unless the code is generated at the start of | 617 // generated code is located unless the code is generated at the start of |
671 // a trace, in which case it is generic and can be reused by flushing the | 618 // a trace, in which case it is generic and can be reused by flushing the |
672 // deferred operations in the current trace and generating a goto. | 619 // deferred operations in the current trace and generating a goto. |
673 int trace_count_; | 620 int trace_count_; |
674 BoyerMooreLookahead* bm_info_[2]; | 621 BoyerMooreLookahead* bm_info_[2]; |
675 }; | 622 }; |
676 | 623 |
677 | 624 |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 int* vector_; | 1565 int* vector_; |
1619 int offsets_vector_length_; | 1566 int offsets_vector_length_; |
1620 | 1567 |
1621 friend class ExternalReference; | 1568 friend class ExternalReference; |
1622 }; | 1569 }; |
1623 | 1570 |
1624 | 1571 |
1625 } } // namespace v8::internal | 1572 } } // namespace v8::internal |
1626 | 1573 |
1627 #endif // V8_JSREGEXP_H_ | 1574 #endif // V8_JSREGEXP_H_ |
OLD | NEW |