Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: src/jsregexp.h

Issue 13014: Rudimentary assertion expansion (Closed)
Patch Set: Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 }; 178 };
179 179
180 180
181 class CharacterRange { 181 class CharacterRange {
182 public: 182 public:
183 CharacterRange() : from_(0), to_(0) { } 183 CharacterRange() : from_(0), to_(0) { }
184 // For compatibility with the CHECK_OK macro 184 // For compatibility with the CHECK_OK macro
185 CharacterRange(void* null) { ASSERT_EQ(NULL, null); } //NOLINT 185 CharacterRange(void* null) { ASSERT_EQ(NULL, null); } //NOLINT
186 CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { } 186 CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { }
187 static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges); 187 static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges);
188 static Vector<const uc16> GetWordBounds();
188 static inline CharacterRange Singleton(uc16 value) { 189 static inline CharacterRange Singleton(uc16 value) {
189 return CharacterRange(value, value); 190 return CharacterRange(value, value);
190 } 191 }
191 static inline CharacterRange Range(uc16 from, uc16 to) { 192 static inline CharacterRange Range(uc16 from, uc16 to) {
192 ASSERT(from <= to); 193 ASSERT(from <= to);
193 return CharacterRange(from, to); 194 return CharacterRange(from, to);
194 } 195 }
195 static inline CharacterRange Everything() { 196 static inline CharacterRange Everything() {
196 return CharacterRange(0, 0xFFFF); 197 return CharacterRange(0, 0xFFFF);
197 } 198 }
198 bool Contains(uc16 i) { return from_ <= i && i <= to_; } 199 bool Contains(uc16 i) { return from_ <= i && i <= to_; }
199 uc16 from() const { return from_; } 200 uc16 from() const { return from_; }
200 void set_from(uc16 value) { from_ = value; } 201 void set_from(uc16 value) { from_ = value; }
201 uc16 to() const { return to_; } 202 uc16 to() const { return to_; }
202 void set_to(uc16 value) { to_ = value; } 203 void set_to(uc16 value) { to_ = value; }
203 bool is_valid() { return from_ <= to_; } 204 bool is_valid() { return from_ <= to_; }
204 bool IsSingleton() { return (from_ == to_); } 205 bool IsSingleton() { return (from_ == to_); }
205 void AddCaseEquivalents(ZoneList<CharacterRange>* ranges); 206 void AddCaseEquivalents(ZoneList<CharacterRange>* ranges);
207 static void Split(ZoneList<CharacterRange>* base,
208 Vector<const uc16> overlay,
209 ZoneList<CharacterRange>** included,
210 ZoneList<CharacterRange>** excluded);
211
206 static const int kRangeCanonicalizeMax = 0x346; 212 static const int kRangeCanonicalizeMax = 0x346;
207 static const int kStartMarker = (1 << 24); 213 static const int kStartMarker = (1 << 24);
208 static const int kPayloadMask = (1 << 24) - 1; 214 static const int kPayloadMask = (1 << 24) - 1;
215
209 private: 216 private:
210 uc16 from_; 217 uc16 from_;
211 uc16 to_; 218 uc16 to_;
212 }; 219 };
213 220
214 221
215 template <typename Node, class Callback> 222 template <typename Node, class Callback>
216 static void DoForEach(Node* node, Callback* callback); 223 static void DoForEach(Node* node, Callback* callback);
217 224
218 225
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 OutSet(uint32_t first, ZoneList<unsigned>* remaining) 344 OutSet(uint32_t first, ZoneList<unsigned>* remaining)
338 : first_(first), remaining_(remaining), successors_(NULL) { } 345 : first_(first), remaining_(remaining), successors_(NULL) { }
339 uint32_t first_; 346 uint32_t first_;
340 ZoneList<unsigned>* remaining_; 347 ZoneList<unsigned>* remaining_;
341 ZoneList<OutSet*>* successors_; 348 ZoneList<OutSet*>* successors_;
342 }; 349 };
343 350
344 351
345 // A mapping from integers, specified as ranges, to a set of integers. 352 // A mapping from integers, specified as ranges, to a set of integers.
346 // Used for mapping character ranges to choices. 353 // Used for mapping character ranges to choices.
347 class DispatchTable { 354 class DispatchTable : public ZoneObject {
348 public: 355 public:
349 class Entry { 356 class Entry {
350 public: 357 public:
351 Entry() : from_(0), to_(0), out_set_(NULL) { } 358 Entry() : from_(0), to_(0), out_set_(NULL) { }
352 Entry(uc16 from, uc16 to, OutSet* out_set) 359 Entry(uc16 from, uc16 to, OutSet* out_set)
353 : from_(from), to_(to), out_set_(out_set) { } 360 : from_(from), to_(to), out_set_(out_set) { }
354 uc16 from() { return from_; } 361 uc16 from() { return from_; }
355 uc16 to() { return to_; } 362 uc16 to() { return to_; }
356 void set_to(uc16 value) { to_ = value; } 363 void set_to(uc16 value) { to_ = value; }
357 void AddValue(int value) { out_set_ = out_set_->Extend(value); } 364 void AddValue(int value) { out_set_ = out_set_->Extend(value); }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 static TextElement CharClass(RegExpCharacterClass* char_class); 437 static TextElement CharClass(RegExpCharacterClass* char_class);
431 Type type; 438 Type type;
432 union { 439 union {
433 RegExpAtom* u_atom; 440 RegExpAtom* u_atom;
434 RegExpCharacterClass* u_char_class; 441 RegExpCharacterClass* u_char_class;
435 } data; 442 } data;
436 }; 443 };
437 444
438 445
439 struct NodeInfo { 446 struct NodeInfo {
440 enum PrecedingInfo { 447 enum TriBool {
Lasse Reichstein 2008/12/01 11:55:47 Not really a better name. Not that I can think of
441 UNKNOWN = -1, FALSE = 0, TRUE = 1 448 UNKNOWN = -1, FALSE = 0, TRUE = 1
442 }; 449 };
443 450
444 NodeInfo() 451 NodeInfo()
445 : being_analyzed(false), 452 : being_analyzed(false),
446 been_analyzed(false), 453 been_analyzed(false),
454 being_expanded(false),
455 been_expanded(false),
447 determine_word(false), 456 determine_word(false),
448 determine_newline(false), 457 determine_newline(false),
449 determine_start(false), 458 determine_start(false),
459 does_determine_word(false),
460 does_determine_newline(false),
461 does_determine_start(false),
450 follows_word_interest(false), 462 follows_word_interest(false),
451 follows_newline_interest(false), 463 follows_newline_interest(false),
452 follows_start_interest(false), 464 follows_start_interest(false),
465 is_word(UNKNOWN),
466 is_newline(UNKNOWN),
453 at_end(false), 467 at_end(false),
454 follows_word(UNKNOWN), 468 follows_word(UNKNOWN),
455 follows_newline(UNKNOWN), 469 follows_newline(UNKNOWN),
456 follows_start(UNKNOWN) { } 470 follows_start(UNKNOWN) { }
457 471
458 bool HasSameForwardInterests(NodeInfo* that) { 472 // Returns true if the interests and assumptions of this node
459 return (at_end == that->at_end) 473 // matches the given one.
460 && (follows_word_interest == that->follows_word_interest) 474 bool Matches(NodeInfo* that) {
461 && (follows_newline_interest == that->follows_newline_interest) 475 return (at_end == that->at_end) &&
462 && (follows_start_interest == that->follows_start_interest); 476 (follows_word_interest == that->follows_word_interest) &&
477 (follows_newline_interest == that->follows_newline_interest) &&
478 (follows_start_interest == that->follows_start_interest) &&
479 (follows_word == that->follows_word) &&
480 (follows_newline == that->follows_newline) &&
481 (follows_start == that->follows_start) &&
482 (does_determine_word == that->does_determine_word) &&
483 (does_determine_newline == that->does_determine_newline) &&
484 (does_determine_start == that->does_determine_start);
485 }
486
487 bool HasAssertions() {
488 return (follows_word != UNKNOWN) ||
489 (follows_newline != UNKNOWN) ||
490 (follows_start != UNKNOWN);
463 } 491 }
464 492
465 // Updates the interests of this node given the interests of the 493 // Updates the interests of this node given the interests of the
466 // node preceding it. 494 // node preceding it.
467 void AddFromPreceding(NodeInfo* that) { 495 void AddFromPreceding(NodeInfo* that) {
468 at_end |= that->at_end; 496 at_end |= that->at_end;
469 follows_word_interest |= that->follows_word_interest; 497 follows_word_interest |= that->follows_word_interest;
470 follows_newline_interest |= that->follows_newline_interest; 498 follows_newline_interest |= that->follows_newline_interest;
471 follows_start_interest |= that->follows_start_interest; 499 follows_start_interest |= that->follows_start_interest;
472 } 500 }
473 501
502 void AddAssumptions(NodeInfo* that) {
503 if (that->follows_word != UNKNOWN) {
504 ASSERT(follows_word == UNKNOWN || follows_word == that->follows_word);
505 follows_word = that->follows_word;
506 }
507 if (that->follows_newline != UNKNOWN) {
508 ASSERT(follows_newline == UNKNOWN ||
509 follows_newline == that->follows_newline);
510 follows_newline = that->follows_newline;
511 }
512 if (that->follows_start != UNKNOWN) {
513 ASSERT(follows_start == UNKNOWN ||
514 follows_start == that->follows_start);
515 follows_start = that->follows_start;
516 }
517 does_determine_word = that->does_determine_word;
518 does_determine_newline = that->does_determine_newline;
519 does_determine_start = that->does_determine_start;
520 }
521
474 // Sets the interests of this node to include the interests of the 522 // Sets the interests of this node to include the interests of the
475 // following node. 523 // following node.
476 void AddFromFollowing(NodeInfo* that) { 524 void AddFromFollowing(NodeInfo* that) {
477 follows_word_interest |= that->follows_word_interest; 525 follows_word_interest |= that->follows_word_interest;
478 follows_newline_interest |= that->follows_newline_interest; 526 follows_newline_interest |= that->follows_newline_interest;
479 follows_start_interest |= that->follows_start_interest; 527 follows_start_interest |= that->follows_start_interest;
480 } 528 }
481 529
530 void ResetCompilationState() {
531 being_analyzed = false;
532 been_analyzed = false;
533 being_expanded = false;
534 been_expanded = false;
535 }
536
482 bool being_analyzed: 1; 537 bool being_analyzed: 1;
483 bool been_analyzed: 1; 538 bool been_analyzed: 1;
539 bool being_expanded: 1;
540 bool been_expanded: 1;
484 541
485 // These bits are set if this node must propagate forward information 542 // These bits are set if this node must propagate forward information
486 // about the last character it consumed (or, in the case of 'start', 543 // about the last character it consumed (or, in the case of 'start',
487 // if it is at the start of the input). 544 // if it is at the start of the input).
488 bool determine_word: 1; 545 bool determine_word: 1;
489 bool determine_newline: 1; 546 bool determine_newline: 1;
490 bool determine_start: 1; 547 bool determine_start: 1;
491 548
549 bool does_determine_word: 1;
550 bool does_determine_newline: 1;
551 bool does_determine_start: 1;
552
492 // These bits are set of this node has to know what the preceding 553 // These bits are set of this node has to know what the preceding
493 // character was. 554 // character was.
494 bool follows_word_interest: 1; 555 bool follows_word_interest: 1;
495 bool follows_newline_interest: 1; 556 bool follows_newline_interest: 1;
496 bool follows_start_interest: 1; 557 bool follows_start_interest: 1;
497 558
559 TriBool is_word: 2;
560 TriBool is_newline: 2;
561
498 bool at_end: 1; 562 bool at_end: 1;
499 563
500 // These bits are set if the node can make assumptions about what 564 // These bits are set if the node can make assumptions about what
501 // the previous character was. 565 // the previous character was.
502 PrecedingInfo follows_word: 2; 566 TriBool follows_word: 2;
503 PrecedingInfo follows_newline: 2; 567 TriBool follows_newline: 2;
504 PrecedingInfo follows_start: 2; 568 TriBool follows_start: 2;
505 }; 569 };
506 570
507 571
572 class ExpansionGuard {
573 public:
574 explicit inline ExpansionGuard(NodeInfo* info) : info_(info) {
575 ASSERT(!info->being_expanded);
576 info->being_expanded = true;
577 }
578 inline ~ExpansionGuard() {
579 info_->being_expanded = false;
580 }
581 private:
582 NodeInfo* info_;
583 };
584
585
508 class SiblingList { 586 class SiblingList {
509 public: 587 public:
510 SiblingList() : list_(NULL) { } 588 SiblingList() : list_(NULL) { }
511 int length() { 589 int length() {
512 return list_ == NULL ? 0 : list_->length(); 590 return list_ == NULL ? 0 : list_->length();
513 } 591 }
514 void Ensure(RegExpNode* parent) { 592 void Ensure(RegExpNode* parent) {
515 if (list_ == NULL) { 593 if (list_ == NULL) {
516 list_ = new ZoneList<RegExpNode*>(2); 594 list_ = new ZoneList<RegExpNode*>(2);
517 list_->Add(parent); 595 list_->Add(parent);
(...skipping 13 matching lines...) Expand all
531 // Generates a goto to this node or actually generates the code at this point. 609 // Generates a goto to this node or actually generates the code at this point.
532 // Until the implementation is complete we will return true for success and 610 // Until the implementation is complete we will return true for success and
533 // false for failure. 611 // false for failure.
534 virtual bool GoTo(RegExpCompiler* compiler); 612 virtual bool GoTo(RegExpCompiler* compiler);
535 Label* label(); 613 Label* label();
536 614
537 // Until the implementation is complete we will return true for success and 615 // Until the implementation is complete we will return true for success and
538 // false for failure. 616 // false for failure.
539 virtual bool Emit(RegExpCompiler* compiler) = 0; 617 virtual bool Emit(RegExpCompiler* compiler) = 0;
540 618
619 RegExpNode* EnsureExpanded(NodeInfo* info);
620 virtual RegExpNode* ExpandLocal(NodeInfo* info) = 0;
621 virtual void ExpandChildren() = 0;
622
541 // Propagates the given interest information forward. When seeing 623 // Propagates the given interest information forward. When seeing
542 // \bfoo for instance, the \b is implemented by propagating forward 624 // \bfoo for instance, the \b is implemented by propagating forward
543 // to the 'foo' string that it should only succeed if its first 625 // to the 'foo' string that it should only succeed if its first
544 // character is a letter xor the previous character was a letter. 626 // character is a letter xor the previous character was a letter.
545 virtual RegExpNode* PropagateForward(NodeInfo* info) = 0; 627 virtual RegExpNode* PropagateForward(NodeInfo* info) = 0;
546 628
547 NodeInfo* info() { return &info_; } 629 NodeInfo* info() { return &info_; }
548 virtual bool IsBacktrack() { return false; } 630 virtual bool IsBacktrack() { return false; }
549 RegExpNode* GetSibling(NodeInfo* info); 631
550 void EnsureSiblings() { siblings_.Ensure(this); }
551 void AddSibling(RegExpNode* node) { siblings_.Add(node); } 632 void AddSibling(RegExpNode* node) { siblings_.Add(node); }
633
634 // Static version of EnsureSibling that expresses the fact that the
635 // result has the same type as the input.
636 template <class C>
637 static C* EnsureSibling(C* node, NodeInfo* info, bool* cloned) {
638 return static_cast<C*>(node->EnsureSibling(info, cloned));
639 }
640
641 SiblingList* siblings() { return &siblings_; }
642 void set_siblings(SiblingList* other) { siblings_ = *other; }
643
552 protected: 644 protected:
645
646 // Returns a sibling of this node whose interests and assumptions
647 // match the ones in the given node info. If no sibling exists NULL
648 // is returned.
649 RegExpNode* TryGetSibling(NodeInfo* info);
650
651 // Returns a sibling of this node whose interests match the ones in
652 // the given node info. The info must not contain any assertions.
653 // If no node exists a new one will be created by cloning the current
654 // node. The result will always be an instance of the same concrete
655 // class as this node.
656 RegExpNode* EnsureSibling(NodeInfo* info, bool* cloned);
657
658 // Returns a clone of this node initialized using the copy constructor
659 // of its concrete class. Note that the node may have to be pre-
660 // processed before it is on a useable state.
661 virtual RegExpNode* Clone() = 0;
662
553 inline void Bind(RegExpMacroAssembler* macro); 663 inline void Bind(RegExpMacroAssembler* macro);
664
554 private: 665 private:
555 Label label_; 666 Label label_;
556 NodeInfo info_; 667 NodeInfo info_;
557 SiblingList siblings_; 668 SiblingList siblings_;
558 }; 669 };
559 670
560 671
561 class SeqRegExpNode: public RegExpNode { 672 class SeqRegExpNode: public RegExpNode {
562 public: 673 public:
563 explicit SeqRegExpNode(RegExpNode* on_success) 674 explicit SeqRegExpNode(RegExpNode* on_success)
(...skipping 22 matching lines...) Expand all
586 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); 697 static ActionNode* RestorePosition(int reg, RegExpNode* on_success);
587 static ActionNode* BeginSubmatch(int stack_pointer_reg, 698 static ActionNode* BeginSubmatch(int stack_pointer_reg,
588 int position_reg, 699 int position_reg,
589 RegExpNode* on_success); 700 RegExpNode* on_success);
590 static ActionNode* EscapeSubmatch(int stack_pointer_reg, 701 static ActionNode* EscapeSubmatch(int stack_pointer_reg,
591 bool and_restore_position, 702 bool and_restore_position,
592 int restore_reg, 703 int restore_reg,
593 RegExpNode* on_success); 704 RegExpNode* on_success);
594 virtual void Accept(NodeVisitor* visitor); 705 virtual void Accept(NodeVisitor* visitor);
595 virtual bool Emit(RegExpCompiler* compiler); 706 virtual bool Emit(RegExpCompiler* compiler);
707 virtual RegExpNode* ExpandLocal(NodeInfo* info);
708 virtual void ExpandChildren();
596 virtual RegExpNode* PropagateForward(NodeInfo* info); 709 virtual RegExpNode* PropagateForward(NodeInfo* info);
710 virtual ActionNode* Clone() { return new ActionNode(*this); }
711
597 private: 712 private:
598 union { 713 union {
599 struct { 714 struct {
600 int reg; 715 int reg;
601 int value; 716 int value;
602 } u_store_register; 717 } u_store_register;
603 struct { 718 struct {
604 int reg; 719 int reg;
605 } u_increment_register; 720 } u_increment_register;
606 struct { 721 struct {
(...skipping 13 matching lines...) Expand all
620 735
621 736
622 class TextNode: public SeqRegExpNode { 737 class TextNode: public SeqRegExpNode {
623 public: 738 public:
624 TextNode(ZoneList<TextElement>* elms, 739 TextNode(ZoneList<TextElement>* elms,
625 RegExpNode* on_success, 740 RegExpNode* on_success,
626 RegExpNode* on_failure) 741 RegExpNode* on_failure)
627 : SeqRegExpNode(on_success), 742 : SeqRegExpNode(on_success),
628 on_failure_(on_failure), 743 on_failure_(on_failure),
629 elms_(elms) { } 744 elms_(elms) { }
745 TextNode(RegExpCharacterClass* that,
746 RegExpNode* on_success,
747 RegExpNode* on_failure)
748 : SeqRegExpNode(on_success),
749 on_failure_(on_failure),
750 elms_(new ZoneList<TextElement>(1)) {
751 elms_->Add(TextElement::CharClass(that));
752 }
630 virtual void Accept(NodeVisitor* visitor); 753 virtual void Accept(NodeVisitor* visitor);
631 virtual RegExpNode* PropagateForward(NodeInfo* info); 754 virtual RegExpNode* PropagateForward(NodeInfo* info);
755 virtual RegExpNode* ExpandLocal(NodeInfo* info);
756 virtual void ExpandChildren();
632 RegExpNode* on_failure() { return on_failure_; } 757 RegExpNode* on_failure() { return on_failure_; }
633 virtual bool Emit(RegExpCompiler* compiler); 758 virtual bool Emit(RegExpCompiler* compiler);
634 ZoneList<TextElement>* elements() { return elms_; } 759 ZoneList<TextElement>* elements() { return elms_; }
635 void MakeCaseIndependent(); 760 void MakeCaseIndependent();
761 virtual TextNode* Clone() { return new TextNode(*this); }
762
636 private: 763 private:
764 void ExpandAtomChildren(RegExpAtom* that);
765 void ExpandCharClassChildren(RegExpCharacterClass* that);
766
637 RegExpNode* on_failure_; 767 RegExpNode* on_failure_;
638 ZoneList<TextElement>* elms_; 768 ZoneList<TextElement>* elms_;
639 }; 769 };
640 770
641 771
642 class BackReferenceNode: public SeqRegExpNode { 772 class BackReferenceNode: public SeqRegExpNode {
643 public: 773 public:
644 BackReferenceNode(int start_reg, 774 BackReferenceNode(int start_reg,
645 int end_reg, 775 int end_reg,
646 RegExpNode* on_success, 776 RegExpNode* on_success,
647 RegExpNode* on_failure) 777 RegExpNode* on_failure)
648 : SeqRegExpNode(on_success), 778 : SeqRegExpNode(on_success),
649 on_failure_(on_failure), 779 on_failure_(on_failure),
650 start_reg_(start_reg), 780 start_reg_(start_reg),
651 end_reg_(end_reg) { } 781 end_reg_(end_reg) { }
652 virtual void Accept(NodeVisitor* visitor); 782 virtual void Accept(NodeVisitor* visitor);
653 RegExpNode* on_failure() { return on_failure_; } 783 RegExpNode* on_failure() { return on_failure_; }
654 int start_register() { return start_reg_; } 784 int start_register() { return start_reg_; }
655 int end_register() { return end_reg_; } 785 int end_register() { return end_reg_; }
656 virtual bool Emit(RegExpCompiler* compiler); 786 virtual bool Emit(RegExpCompiler* compiler);
657 virtual RegExpNode* PropagateForward(NodeInfo* info); 787 virtual RegExpNode* PropagateForward(NodeInfo* info);
788 virtual RegExpNode* ExpandLocal(NodeInfo* info);
789 virtual void ExpandChildren();
790 virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); }
791
658 private: 792 private:
659 RegExpNode* on_failure_; 793 RegExpNode* on_failure_;
660 int start_reg_; 794 int start_reg_;
661 int end_reg_; 795 int end_reg_;
662 }; 796 };
663 797
664 798
665 class EndNode: public RegExpNode { 799 class EndNode: public RegExpNode {
666 public: 800 public:
667 enum Action { ACCEPT, BACKTRACK }; 801 enum Action { ACCEPT, BACKTRACK };
668 explicit EndNode(Action action) : action_(action) { } 802 explicit EndNode(Action action) : action_(action) { }
669 virtual void Accept(NodeVisitor* visitor); 803 virtual void Accept(NodeVisitor* visitor);
670 virtual bool Emit(RegExpCompiler* compiler); 804 virtual bool Emit(RegExpCompiler* compiler);
671 virtual RegExpNode* PropagateForward(NodeInfo* info); 805 virtual RegExpNode* PropagateForward(NodeInfo* info);
806 virtual RegExpNode* ExpandLocal(NodeInfo* info);
807 virtual void ExpandChildren();
672 virtual bool IsBacktrack() { return action_ == BACKTRACK; } 808 virtual bool IsBacktrack() { return action_ == BACKTRACK; }
673 virtual bool GoTo(RegExpCompiler* compiler); 809 virtual bool GoTo(RegExpCompiler* compiler);
810 virtual EndNode* Clone() { return new EndNode(*this); }
811
674 private: 812 private:
675 Action action_; 813 Action action_;
676 }; 814 };
677 815
678 816
679 class Guard: public ZoneObject { 817 class Guard: public ZoneObject {
680 public: 818 public:
681 enum Relation { LT, GEQ }; 819 enum Relation { LT, GEQ };
682 Guard(int reg, Relation op, int value) 820 Guard(int reg, Relation op, int value)
683 : reg_(reg), 821 : reg_(reg),
684 op_(op), 822 op_(op),
685 value_(value) { } 823 value_(value) { }
686 int reg() { return reg_; } 824 int reg() { return reg_; }
687 Relation op() { return op_; } 825 Relation op() { return op_; }
688 int value() { return value_; } 826 int value() { return value_; }
827
689 private: 828 private:
690 int reg_; 829 int reg_;
691 Relation op_; 830 Relation op_;
692 int value_; 831 int value_;
693 }; 832 };
694 833
695 834
696 class GuardedAlternative { 835 class GuardedAlternative {
697 public: 836 public:
698 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } 837 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { }
699 void AddGuard(Guard* guard); 838 void AddGuard(Guard* guard);
700 RegExpNode* node() { return node_; } 839 RegExpNode* node() { return node_; }
701 void set_node(RegExpNode* node) { node_ = node; } 840 void set_node(RegExpNode* node) { node_ = node; }
702 ZoneList<Guard*>* guards() { return guards_; } 841 ZoneList<Guard*>* guards() { return guards_; }
842
703 private: 843 private:
704 RegExpNode* node_; 844 RegExpNode* node_;
705 ZoneList<Guard*>* guards_; 845 ZoneList<Guard*>* guards_;
706 }; 846 };
707 847
708 848
709 class ChoiceNode: public RegExpNode { 849 class ChoiceNode: public RegExpNode {
710 public: 850 public:
711 explicit ChoiceNode(int expected_size, RegExpNode* on_failure) 851 explicit ChoiceNode(int expected_size, RegExpNode* on_failure)
712 : on_failure_(on_failure), 852 : on_failure_(on_failure),
713 alternatives_(new ZoneList<GuardedAlternative>(expected_size)), 853 alternatives_(new ZoneList<GuardedAlternative>(expected_size)),
714 table_calculated_(false), 854 table_(NULL),
715 being_calculated_(false) { } 855 being_calculated_(false) { }
716 virtual void Accept(NodeVisitor* visitor); 856 virtual void Accept(NodeVisitor* visitor);
717 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } 857 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); }
718 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } 858 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
719 DispatchTable* table() { return &table_; } 859 DispatchTable* GetTable(bool ignore_case);
720 RegExpNode* on_failure() { return on_failure_; } 860 RegExpNode* on_failure() { return on_failure_; }
721 virtual bool Emit(RegExpCompiler* compiler); 861 virtual bool Emit(RegExpCompiler* compiler);
722 virtual RegExpNode* PropagateForward(NodeInfo* info); 862 virtual RegExpNode* PropagateForward(NodeInfo* info);
723 bool table_calculated() { return table_calculated_; } 863 virtual RegExpNode* ExpandLocal(NodeInfo* info);
724 void set_table_calculated(bool b) { table_calculated_ = b; } 864 virtual void ExpandChildren();
865 virtual ChoiceNode* Clone() { return new ChoiceNode(*this); }
866
725 bool being_calculated() { return being_calculated_; } 867 bool being_calculated() { return being_calculated_; }
726 void set_being_calculated(bool b) { being_calculated_ = b; } 868 void set_being_calculated(bool b) { being_calculated_ = b; }
869
727 private: 870 private:
871 friend class DispatchTableConstructor;
872 friend class Analysis;
728 void GenerateGuard(RegExpMacroAssembler* macro_assembler, 873 void GenerateGuard(RegExpMacroAssembler* macro_assembler,
729 Guard *guard, 874 Guard *guard,
730 Label* on_failure); 875 Label* on_failure);
731 RegExpNode* on_failure_; 876 RegExpNode* on_failure_;
732 ZoneList<GuardedAlternative>* alternatives_; 877 ZoneList<GuardedAlternative>* alternatives_;
733 DispatchTable table_; 878 DispatchTable* table_;
734 bool table_calculated_;
735 bool being_calculated_; 879 bool being_calculated_;
736 }; 880 };
737 881
738 882
739 class NodeVisitor { 883 class NodeVisitor {
740 public: 884 public:
741 virtual ~NodeVisitor() { } 885 virtual ~NodeVisitor() { }
742 #define DECLARE_VISIT(Type) \ 886 #define DECLARE_VISIT(Type) \
743 virtual void Visit##Type(Type##Node* that) = 0; 887 virtual void Visit##Type(Type##Node* that) = 0;
744 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 888 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
745 #undef DECLARE_VISIT 889 #undef DECLARE_VISIT
746 }; 890 };
747 891
748 892
749 // Node visitor used to add the start set of the alternatives to the 893 // Node visitor used to add the start set of the alternatives to the
750 // dispatch table of a choice node. 894 // dispatch table of a choice node.
751 class DispatchTableConstructor: public NodeVisitor { 895 class DispatchTableConstructor: public NodeVisitor {
752 public: 896 public:
753 explicit DispatchTableConstructor(DispatchTable* table) 897 DispatchTableConstructor(DispatchTable* table, bool ignore_case)
754 : table_(table), 898 : table_(table),
755 choice_index_(-1) { } 899 choice_index_(-1),
900 ignore_case_(ignore_case) { }
756 901
757 void BuildTable(ChoiceNode* node); 902 void BuildTable(ChoiceNode* node);
758 903
759 void AddRange(CharacterRange range) { 904 void AddRange(CharacterRange range) {
760 table()->AddRange(range, choice_index_); 905 table()->AddRange(range, choice_index_);
761 } 906 }
762 907
763 void AddInverse(ZoneList<CharacterRange>* ranges); 908 void AddInverse(ZoneList<CharacterRange>* ranges);
764 909
765 #define DECLARE_VISIT(Type) \ 910 #define DECLARE_VISIT(Type) \
766 virtual void Visit##Type(Type##Node* that); 911 virtual void Visit##Type(Type##Node* that);
767 FOR_EACH_NODE_TYPE(DECLARE_VISIT) 912 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
768 #undef DECLARE_VISIT 913 #undef DECLARE_VISIT
769 914
770 DispatchTable* table() { return table_; } 915 DispatchTable* table() { return table_; }
771 void set_choice_index(int value) { choice_index_ = value; } 916 void set_choice_index(int value) { choice_index_ = value; }
772 917
773 protected: 918 protected:
774 DispatchTable *table_; 919 DispatchTable *table_;
775 int choice_index_; 920 int choice_index_;
921 bool ignore_case_;
776 }; 922 };
777 923
778 924
779 class Analysis: public NodeVisitor { 925 class Analysis: public NodeVisitor {
780 public: 926 public:
781 explicit Analysis(bool ignore_case) 927 explicit Analysis(bool ignore_case)
782 : ignore_case_(ignore_case) { } 928 : ignore_case_(ignore_case) { }
783 void EnsureAnalyzed(RegExpNode* node); 929 void EnsureAnalyzed(RegExpNode* node);
784 930
785 #define DECLARE_VISIT(Type) \ 931 #define DECLARE_VISIT(Type) \
(...skipping 15 matching lines...) Expand all
801 int capture_count; 947 int capture_count;
802 }; 948 };
803 949
804 950
805 class RegExpEngine: public AllStatic { 951 class RegExpEngine: public AllStatic {
806 public: 952 public:
807 static Handle<FixedArray> Compile(RegExpParseResult* input, 953 static Handle<FixedArray> Compile(RegExpParseResult* input,
808 RegExpNode** node_return, 954 RegExpNode** node_return,
809 bool ignore_case, 955 bool ignore_case,
810 bool multiline); 956 bool multiline);
811 static void DotPrint(const char* label, RegExpNode* node); 957 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
812 }; 958 };
813 959
814 960
815 } } // namespace v8::internal 961 } } // namespace v8::internal
816 962
817 #endif // V8_JSREGEXP_H_ 963 #endif // V8_JSREGEXP_H_
OLDNEW
« no previous file with comments | « src/char-predicates-inl.h ('k') | src/jsregexp.cc » ('j') | test/cctest/test-regexp.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698