| 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 static TextElement CharClass(RegExpCharacterClass* char_class); | 430 static TextElement CharClass(RegExpCharacterClass* char_class); |
| 431 Type type; | 431 Type type; |
| 432 union { | 432 union { |
| 433 RegExpAtom* u_atom; | 433 RegExpAtom* u_atom; |
| 434 RegExpCharacterClass* u_char_class; | 434 RegExpCharacterClass* u_char_class; |
| 435 } data; | 435 } data; |
| 436 }; | 436 }; |
| 437 | 437 |
| 438 | 438 |
| 439 struct NodeInfo { | 439 struct NodeInfo { |
| 440 enum PrecedingInfo { |
| 441 UNKNOWN = -1, FALSE = 0, TRUE = 1 |
| 442 }; |
| 443 |
| 440 NodeInfo() | 444 NodeInfo() |
| 441 : being_analyzed(false), | 445 : being_analyzed(false), |
| 442 been_analyzed(false), | 446 been_analyzed(false), |
| 443 determine_word(false), | 447 determine_word(false), |
| 444 determine_newline(false), | 448 determine_newline(false), |
| 445 determine_start(false), | 449 determine_start(false), |
| 446 follows_word_interest(false), | 450 follows_word_interest(false), |
| 447 follows_newline_interest(false), | 451 follows_newline_interest(false), |
| 448 follows_start_interest(false) { } | 452 follows_start_interest(false), |
| 449 bool SameInterests(NodeInfo* that) { | 453 at_end(false), |
| 450 return (follows_word_interest == that->follows_word_interest) | 454 follows_word(UNKNOWN), |
| 455 follows_newline(UNKNOWN), |
| 456 follows_start(UNKNOWN) { } |
| 457 |
| 458 bool HasSameForwardInterests(NodeInfo* that) { |
| 459 return (at_end == that->at_end) |
| 460 && (follows_word_interest == that->follows_word_interest) |
| 451 && (follows_newline_interest == that->follows_newline_interest) | 461 && (follows_newline_interest == that->follows_newline_interest) |
| 452 && (follows_start_interest == that->follows_start_interest); | 462 && (follows_start_interest == that->follows_start_interest); |
| 453 } | 463 } |
| 454 void AdoptInterests(NodeInfo* that) { | 464 |
| 455 follows_word_interest = that->follows_word_interest; | 465 // Updates the interests of this node given the interests of the |
| 456 follows_newline_interest = that->follows_newline_interest; | 466 // node preceding it. |
| 457 follows_start_interest = that->follows_start_interest; | 467 void AddFromPreceding(NodeInfo* that) { |
| 468 at_end |= that->at_end; |
| 469 follows_word_interest |= that->follows_word_interest; |
| 470 follows_newline_interest |= that->follows_newline_interest; |
| 471 follows_start_interest |= that->follows_start_interest; |
| 458 } | 472 } |
| 459 bool prev_determine_word() { | 473 |
| 460 return determine_word || follows_word_interest; | 474 // Sets the interests of this node to include the interests of the |
| 475 // following node. |
| 476 void AddFromFollowing(NodeInfo* that) { |
| 477 follows_word_interest |= that->follows_word_interest; |
| 478 follows_newline_interest |= that->follows_newline_interest; |
| 479 follows_start_interest |= that->follows_start_interest; |
| 461 } | 480 } |
| 462 bool prev_determine_newline() { | 481 |
| 463 return determine_newline || follows_newline_interest; | |
| 464 } | |
| 465 bool prev_determine_start() { | |
| 466 return determine_start || follows_start_interest; | |
| 467 } | |
| 468 bool being_analyzed: 1; | 482 bool being_analyzed: 1; |
| 469 bool been_analyzed: 1; | 483 bool been_analyzed: 1; |
| 484 |
| 485 // These bits are set if this node must propagate forward information |
| 486 // about the last character it consumed (or, in the case of 'start', |
| 487 // if it is at the start of the input). |
| 470 bool determine_word: 1; | 488 bool determine_word: 1; |
| 471 bool determine_newline: 1; | 489 bool determine_newline: 1; |
| 472 bool determine_start: 1; | 490 bool determine_start: 1; |
| 491 |
| 492 // These bits are set of this node has to know what the preceding |
| 493 // character was. |
| 473 bool follows_word_interest: 1; | 494 bool follows_word_interest: 1; |
| 474 bool follows_newline_interest: 1; | 495 bool follows_newline_interest: 1; |
| 475 bool follows_start_interest: 1; | 496 bool follows_start_interest: 1; |
| 497 |
| 498 bool at_end: 1; |
| 499 |
| 500 // These bits are set if the node can make assumptions about what |
| 501 // the previous character was. |
| 502 PrecedingInfo follows_word: 2; |
| 503 PrecedingInfo follows_newline: 2; |
| 504 PrecedingInfo follows_start: 2; |
| 476 }; | 505 }; |
| 477 | 506 |
| 478 | 507 |
| 479 STATIC_CHECK(sizeof(NodeInfo) <= sizeof(int)); // NOLINT | 508 STATIC_CHECK(sizeof(NodeInfo) <= sizeof(int)); // NOLINT |
| 480 | 509 |
| 481 | 510 |
| 482 class SiblingList { | 511 class SiblingList { |
| 483 public: | 512 public: |
| 484 SiblingList() : list_(NULL) { } | 513 SiblingList() : list_(NULL) { } |
| 485 int length() { | 514 int length() { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 504 virtual void Accept(NodeVisitor* visitor) = 0; | 533 virtual void Accept(NodeVisitor* visitor) = 0; |
| 505 // Generates a goto to this node or actually generates the code at this point. | 534 // Generates a goto to this node or actually generates the code at this point. |
| 506 // Until the implementation is complete we will return true for success and | 535 // Until the implementation is complete we will return true for success and |
| 507 // false for failure. | 536 // false for failure. |
| 508 virtual bool GoTo(RegExpCompiler* compiler); | 537 virtual bool GoTo(RegExpCompiler* compiler); |
| 509 Label* label(); | 538 Label* label(); |
| 510 | 539 |
| 511 // Until the implementation is complete we will return true for success and | 540 // Until the implementation is complete we will return true for success and |
| 512 // false for failure. | 541 // false for failure. |
| 513 virtual bool Emit(RegExpCompiler* compiler) = 0; | 542 virtual bool Emit(RegExpCompiler* compiler) = 0; |
| 514 virtual RegExpNode* PropagateInterest(NodeInfo* info) = 0; | 543 |
| 544 // Propagates the given interest information forward. When seeing |
| 545 // \bfoo for instance, the \b is implemented by propagating forward |
| 546 // to the 'foo' string that it should only succeed if its first |
| 547 // character is a letter xor the previous character was a letter. |
| 548 virtual RegExpNode* PropagateForward(NodeInfo* info) = 0; |
| 549 |
| 515 NodeInfo* info() { return &info_; } | 550 NodeInfo* info() { return &info_; } |
| 516 virtual bool IsBacktrack() { return false; } | 551 virtual bool IsBacktrack() { return false; } |
| 517 RegExpNode* GetSibling(NodeInfo* info); | 552 RegExpNode* GetSibling(NodeInfo* info); |
| 518 void EnsureSiblings() { siblings_.Ensure(this); } | 553 void EnsureSiblings() { siblings_.Ensure(this); } |
| 519 void AddSibling(RegExpNode* node) { siblings_.Add(node); } | 554 void AddSibling(RegExpNode* node) { siblings_.Add(node); } |
| 520 protected: | 555 protected: |
| 521 inline void Bind(RegExpMacroAssembler* macro); | 556 inline void Bind(RegExpMacroAssembler* macro); |
| 522 private: | 557 private: |
| 523 Label label_; | 558 Label label_; |
| 524 NodeInfo info_; | 559 NodeInfo info_; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 551 }; | 586 }; |
| 552 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success); | 587 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success); |
| 553 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); | 588 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); |
| 554 static ActionNode* StorePosition(int reg, RegExpNode* on_success); | 589 static ActionNode* StorePosition(int reg, RegExpNode* on_success); |
| 555 static ActionNode* SavePosition(int reg, RegExpNode* on_success); | 590 static ActionNode* SavePosition(int reg, RegExpNode* on_success); |
| 556 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); | 591 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); |
| 557 static ActionNode* BeginSubmatch(int reg, RegExpNode* on_success); | 592 static ActionNode* BeginSubmatch(int reg, RegExpNode* on_success); |
| 558 static ActionNode* EscapeSubmatch(int reg, RegExpNode* on_success); | 593 static ActionNode* EscapeSubmatch(int reg, RegExpNode* on_success); |
| 559 virtual void Accept(NodeVisitor* visitor); | 594 virtual void Accept(NodeVisitor* visitor); |
| 560 virtual bool Emit(RegExpCompiler* compiler); | 595 virtual bool Emit(RegExpCompiler* compiler); |
| 561 virtual RegExpNode* PropagateInterest(NodeInfo* info); | 596 virtual RegExpNode* PropagateForward(NodeInfo* info); |
| 562 private: | 597 private: |
| 563 union { | 598 union { |
| 564 struct { | 599 struct { |
| 565 int reg; | 600 int reg; |
| 566 int value; | 601 int value; |
| 567 } u_store_register; | 602 } u_store_register; |
| 568 struct { | 603 struct { |
| 569 int reg; | 604 int reg; |
| 570 } u_increment_register; | 605 } u_increment_register; |
| 571 struct { | 606 struct { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 585 | 620 |
| 586 class TextNode: public SeqRegExpNode { | 621 class TextNode: public SeqRegExpNode { |
| 587 public: | 622 public: |
| 588 TextNode(ZoneList<TextElement>* elms, | 623 TextNode(ZoneList<TextElement>* elms, |
| 589 RegExpNode* on_success, | 624 RegExpNode* on_success, |
| 590 RegExpNode* on_failure) | 625 RegExpNode* on_failure) |
| 591 : SeqRegExpNode(on_success), | 626 : SeqRegExpNode(on_success), |
| 592 on_failure_(on_failure), | 627 on_failure_(on_failure), |
| 593 elms_(elms) { } | 628 elms_(elms) { } |
| 594 virtual void Accept(NodeVisitor* visitor); | 629 virtual void Accept(NodeVisitor* visitor); |
| 595 virtual RegExpNode* PropagateInterest(NodeInfo* info); | 630 virtual RegExpNode* PropagateForward(NodeInfo* info); |
| 596 RegExpNode* on_failure() { return on_failure_; } | 631 RegExpNode* on_failure() { return on_failure_; } |
| 597 virtual bool Emit(RegExpCompiler* compiler); | 632 virtual bool Emit(RegExpCompiler* compiler); |
| 598 ZoneList<TextElement>* elements() { return elms_; } | 633 ZoneList<TextElement>* elements() { return elms_; } |
| 599 void MakeCaseIndependent(); | 634 void MakeCaseIndependent(); |
| 600 private: | 635 private: |
| 601 RegExpNode* on_failure_; | 636 RegExpNode* on_failure_; |
| 602 ZoneList<TextElement>* elms_; | 637 ZoneList<TextElement>* elms_; |
| 603 }; | 638 }; |
| 604 | 639 |
| 605 | 640 |
| 606 class BackReferenceNode: public SeqRegExpNode { | 641 class BackReferenceNode: public SeqRegExpNode { |
| 607 public: | 642 public: |
| 608 BackReferenceNode(int start_reg, | 643 BackReferenceNode(int start_reg, |
| 609 int end_reg, | 644 int end_reg, |
| 610 RegExpNode* on_success, | 645 RegExpNode* on_success, |
| 611 RegExpNode* on_failure) | 646 RegExpNode* on_failure) |
| 612 : SeqRegExpNode(on_success), | 647 : SeqRegExpNode(on_success), |
| 613 on_failure_(on_failure), | 648 on_failure_(on_failure), |
| 614 start_reg_(start_reg), | 649 start_reg_(start_reg), |
| 615 end_reg_(end_reg) { } | 650 end_reg_(end_reg) { } |
| 616 virtual void Accept(NodeVisitor* visitor); | 651 virtual void Accept(NodeVisitor* visitor); |
| 617 RegExpNode* on_failure() { return on_failure_; } | 652 RegExpNode* on_failure() { return on_failure_; } |
| 618 int start_register() { return start_reg_; } | 653 int start_register() { return start_reg_; } |
| 619 int end_register() { return end_reg_; } | 654 int end_register() { return end_reg_; } |
| 620 virtual bool Emit(RegExpCompiler* compiler); | 655 virtual bool Emit(RegExpCompiler* compiler); |
| 621 virtual RegExpNode* PropagateInterest(NodeInfo* info); | 656 virtual RegExpNode* PropagateForward(NodeInfo* info); |
| 622 private: | 657 private: |
| 623 RegExpNode* on_failure_; | 658 RegExpNode* on_failure_; |
| 624 int start_reg_; | 659 int start_reg_; |
| 625 int end_reg_; | 660 int end_reg_; |
| 626 }; | 661 }; |
| 627 | 662 |
| 628 | 663 |
| 629 class EndNode: public RegExpNode { | 664 class EndNode: public RegExpNode { |
| 630 public: | 665 public: |
| 631 enum Action { ACCEPT, BACKTRACK }; | 666 enum Action { ACCEPT, BACKTRACK }; |
| 632 explicit EndNode(Action action) : action_(action) { } | 667 explicit EndNode(Action action) : action_(action) { } |
| 633 virtual void Accept(NodeVisitor* visitor); | 668 virtual void Accept(NodeVisitor* visitor); |
| 634 virtual bool Emit(RegExpCompiler* compiler); | 669 virtual bool Emit(RegExpCompiler* compiler); |
| 635 virtual RegExpNode* PropagateInterest(NodeInfo* info); | 670 virtual RegExpNode* PropagateForward(NodeInfo* info); |
| 636 virtual bool IsBacktrack() { return action_ == BACKTRACK; } | 671 virtual bool IsBacktrack() { return action_ == BACKTRACK; } |
| 637 virtual bool GoTo(RegExpCompiler* compiler); | 672 virtual bool GoTo(RegExpCompiler* compiler); |
| 638 private: | 673 private: |
| 639 Action action_; | 674 Action action_; |
| 640 }; | 675 }; |
| 641 | 676 |
| 642 | 677 |
| 643 class Guard: public ZoneObject { | 678 class Guard: public ZoneObject { |
| 644 public: | 679 public: |
| 645 enum Relation { LT, GEQ }; | 680 enum Relation { LT, GEQ }; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 676 : on_failure_(on_failure), | 711 : on_failure_(on_failure), |
| 677 alternatives_(new ZoneList<GuardedAlternative>(expected_size)), | 712 alternatives_(new ZoneList<GuardedAlternative>(expected_size)), |
| 678 table_calculated_(false), | 713 table_calculated_(false), |
| 679 being_calculated_(false) { } | 714 being_calculated_(false) { } |
| 680 virtual void Accept(NodeVisitor* visitor); | 715 virtual void Accept(NodeVisitor* visitor); |
| 681 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } | 716 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } |
| 682 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } | 717 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } |
| 683 DispatchTable* table() { return &table_; } | 718 DispatchTable* table() { return &table_; } |
| 684 RegExpNode* on_failure() { return on_failure_; } | 719 RegExpNode* on_failure() { return on_failure_; } |
| 685 virtual bool Emit(RegExpCompiler* compiler); | 720 virtual bool Emit(RegExpCompiler* compiler); |
| 686 virtual RegExpNode* PropagateInterest(NodeInfo* info); | 721 virtual RegExpNode* PropagateForward(NodeInfo* info); |
| 687 bool table_calculated() { return table_calculated_; } | 722 bool table_calculated() { return table_calculated_; } |
| 688 void set_table_calculated(bool b) { table_calculated_ = b; } | 723 void set_table_calculated(bool b) { table_calculated_ = b; } |
| 689 bool being_calculated() { return being_calculated_; } | 724 bool being_calculated() { return being_calculated_; } |
| 690 void set_being_calculated(bool b) { being_calculated_ = b; } | 725 void set_being_calculated(bool b) { being_calculated_ = b; } |
| 691 private: | 726 private: |
| 692 void GenerateGuard(RegExpMacroAssembler* macro_assembler, | 727 void GenerateGuard(RegExpMacroAssembler* macro_assembler, |
| 693 Guard *guard, | 728 Guard *guard, |
| 694 Label* on_failure); | 729 Label* on_failure); |
| 695 RegExpNode* on_failure_; | 730 RegExpNode* on_failure_; |
| 696 ZoneList<GuardedAlternative>* alternatives_; | 731 ZoneList<GuardedAlternative>* alternatives_; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 bool has_character_escapes; | 798 bool has_character_escapes; |
| 764 Handle<String> error; | 799 Handle<String> error; |
| 765 int capture_count; | 800 int capture_count; |
| 766 }; | 801 }; |
| 767 | 802 |
| 768 | 803 |
| 769 class RegExpEngine: public AllStatic { | 804 class RegExpEngine: public AllStatic { |
| 770 public: | 805 public: |
| 771 static Handle<FixedArray> Compile(RegExpParseResult* input, | 806 static Handle<FixedArray> Compile(RegExpParseResult* input, |
| 772 RegExpNode** node_return, | 807 RegExpNode** node_return, |
| 773 bool ignore_case); | 808 bool ignore_case, |
| 809 bool multiline); |
| 774 static void DotPrint(const char* label, RegExpNode* node); | 810 static void DotPrint(const char* label, RegExpNode* node); |
| 775 }; | 811 }; |
| 776 | 812 |
| 777 | 813 |
| 778 } } // namespace v8::internal | 814 } } // namespace v8::internal |
| 779 | 815 |
| 780 #endif // V8_JSREGEXP_H_ | 816 #endif // V8_JSREGEXP_H_ |
| OLD | NEW |