| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 // Returns false if compilation fails. | 71 // Returns false if compilation fails. |
| 72 static Handle<Object> Compile(Handle<JSRegExp> re, | 72 static Handle<Object> Compile(Handle<JSRegExp> re, |
| 73 Handle<String> pattern, | 73 Handle<String> pattern, |
| 74 Handle<String> flags); | 74 Handle<String> flags); |
| 75 | 75 |
| 76 // See ECMA-262 section 15.10.6.2. | 76 // See ECMA-262 section 15.10.6.2. |
| 77 // This function calls the garbage collector if necessary. | 77 // This function calls the garbage collector if necessary. |
| 78 static Handle<Object> Exec(Handle<JSRegExp> regexp, | 78 static Handle<Object> Exec(Handle<JSRegExp> regexp, |
| 79 Handle<String> subject, | 79 Handle<String> subject, |
| 80 int index, | 80 int index, |
| 81 Handle<JSArray> lastMatchInfo); | 81 Handle<JSArray> lastMatchInfo, |
| 82 Zone* zone); |
| 82 | 83 |
| 83 // Prepares a JSRegExp object with Irregexp-specific data. | 84 // Prepares a JSRegExp object with Irregexp-specific data. |
| 84 static void IrregexpInitialize(Handle<JSRegExp> re, | 85 static void IrregexpInitialize(Handle<JSRegExp> re, |
| 85 Handle<String> pattern, | 86 Handle<String> pattern, |
| 86 JSRegExp::Flags flags, | 87 JSRegExp::Flags flags, |
| 87 int capture_register_count); | 88 int capture_register_count); |
| 88 | 89 |
| 89 | 90 |
| 90 static void AtomCompile(Handle<JSRegExp> re, | 91 static void AtomCompile(Handle<JSRegExp> re, |
| 91 Handle<String> pattern, | 92 Handle<String> pattern, |
| 92 JSRegExp::Flags flags, | 93 JSRegExp::Flags flags, |
| 93 Handle<String> match_pattern); | 94 Handle<String> match_pattern); |
| 94 | 95 |
| 95 static Handle<Object> AtomExec(Handle<JSRegExp> regexp, | 96 static Handle<Object> AtomExec(Handle<JSRegExp> regexp, |
| 96 Handle<String> subject, | 97 Handle<String> subject, |
| 97 int index, | 98 int index, |
| 98 Handle<JSArray> lastMatchInfo); | 99 Handle<JSArray> lastMatchInfo); |
| 99 | 100 |
| 100 enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 }; | 101 enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 }; |
| 101 | 102 |
| 102 // Prepare a RegExp for being executed one or more times (using | 103 // Prepare a RegExp for being executed one or more times (using |
| 103 // IrregexpExecOnce) on the subject. | 104 // IrregexpExecOnce) on the subject. |
| 104 // This ensures that the regexp is compiled for the subject, and that | 105 // This ensures that the regexp is compiled for the subject, and that |
| 105 // the subject is flat. | 106 // the subject is flat. |
| 106 // Returns the number of integer spaces required by IrregexpExecOnce | 107 // Returns the number of integer spaces required by IrregexpExecOnce |
| 107 // as its "registers" argument. If the regexp cannot be compiled, | 108 // as its "registers" argument. If the regexp cannot be compiled, |
| 108 // an exception is set as pending, and this function returns negative. | 109 // an exception is set as pending, and this function returns negative. |
| 109 static int IrregexpPrepare(Handle<JSRegExp> regexp, | 110 static int IrregexpPrepare(Handle<JSRegExp> regexp, |
| 110 Handle<String> subject); | 111 Handle<String> subject, |
| 112 Zone* zone); |
| 111 | 113 |
| 112 // Calculate the size of offsets vector for the case of global regexp | 114 // Calculate the size of offsets vector for the case of global regexp |
| 113 // and the number of matches this vector is able to store. | 115 // and the number of matches this vector is able to store. |
| 114 static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp, | 116 static int GlobalOffsetsVectorSize(Handle<JSRegExp> regexp, |
| 115 int registers_per_match, | 117 int registers_per_match, |
| 116 int* max_matches); | 118 int* max_matches); |
| 117 | 119 |
| 118 // Execute a regular expression on the subject, starting from index. | 120 // Execute a regular expression on the subject, starting from index. |
| 119 // If matching succeeds, return the number of matches. This can be larger | 121 // If matching succeeds, return the number of matches. This can be larger |
| 120 // than one in the case of global regular expressions. | 122 // than one in the case of global regular expressions. |
| 121 // The captures and subcaptures are stored into the registers vector. | 123 // The captures and subcaptures are stored into the registers vector. |
| 122 // If matching fails, returns RE_FAILURE. | 124 // If matching fails, returns RE_FAILURE. |
| 123 // If execution fails, sets a pending exception and returns RE_EXCEPTION. | 125 // If execution fails, sets a pending exception and returns RE_EXCEPTION. |
| 124 static int IrregexpExecRaw(Handle<JSRegExp> regexp, | 126 static int IrregexpExecRaw(Handle<JSRegExp> regexp, |
| 125 Handle<String> subject, | 127 Handle<String> subject, |
| 126 int index, | 128 int index, |
| 127 Vector<int> registers); | 129 Vector<int> registers, |
| 130 Zone* zone); |
| 128 | 131 |
| 129 // Execute an Irregexp bytecode pattern. | 132 // Execute an Irregexp bytecode pattern. |
| 130 // On a successful match, the result is a JSArray containing | 133 // On a successful match, the result is a JSArray containing |
| 131 // captured positions. On a failure, the result is the null value. | 134 // captured positions. On a failure, the result is the null value. |
| 132 // Returns an empty handle in case of an exception. | 135 // Returns an empty handle in case of an exception. |
| 133 static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp, | 136 static Handle<Object> IrregexpExec(Handle<JSRegExp> regexp, |
| 134 Handle<String> subject, | 137 Handle<String> subject, |
| 135 int index, | 138 int index, |
| 136 Handle<JSArray> lastMatchInfo); | 139 Handle<JSArray> lastMatchInfo, |
| 140 Zone* zone); |
| 137 | 141 |
| 138 // Array index in the lastMatchInfo array. | 142 // Array index in the lastMatchInfo array. |
| 139 static const int kLastCaptureCount = 0; | 143 static const int kLastCaptureCount = 0; |
| 140 static const int kLastSubject = 1; | 144 static const int kLastSubject = 1; |
| 141 static const int kLastInput = 2; | 145 static const int kLastInput = 2; |
| 142 static const int kFirstCapture = 3; | 146 static const int kFirstCapture = 3; |
| 143 static const int kLastMatchOverhead = 3; | 147 static const int kLastMatchOverhead = 3; |
| 144 | 148 |
| 145 // Direct offset into the lastMatchInfo array. | 149 // Direct offset into the lastMatchInfo array. |
| 146 static const int kLastCaptureCountOffset = | 150 static const int kLastCaptureCountOffset = |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 // total regexp code compiled including code that has subsequently been freed | 195 // total regexp code compiled including code that has subsequently been freed |
| 192 // and the total executable memory at any point. | 196 // and the total executable memory at any point. |
| 193 static const int kRegExpExecutableMemoryLimit = 16 * MB; | 197 static const int kRegExpExecutableMemoryLimit = 16 * MB; |
| 194 static const int kRegWxpCompiledLimit = 1 * MB; | 198 static const int kRegWxpCompiledLimit = 1 * MB; |
| 195 | 199 |
| 196 private: | 200 private: |
| 197 static String* last_ascii_string_; | 201 static String* last_ascii_string_; |
| 198 static String* two_byte_cached_string_; | 202 static String* two_byte_cached_string_; |
| 199 | 203 |
| 200 static bool CompileIrregexp( | 204 static bool CompileIrregexp( |
| 201 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii); | 205 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii, |
| 206 Zone* zone); |
| 202 static inline bool EnsureCompiledIrregexp( | 207 static inline bool EnsureCompiledIrregexp( |
| 203 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii); | 208 Handle<JSRegExp> re, Handle<String> sample_subject, bool is_ascii, |
| 209 Zone* zone); |
| 204 | 210 |
| 205 | 211 |
| 206 // Set the subject cache. The previous string buffer is not deleted, so the | 212 // Set the subject cache. The previous string buffer is not deleted, so the |
| 207 // caller should ensure that it doesn't leak. | 213 // caller should ensure that it doesn't leak. |
| 208 static void SetSubjectCache(String* subject, | 214 static void SetSubjectCache(String* subject, |
| 209 char* utf8_subject, | 215 char* utf8_subject, |
| 210 int uft8_length, | 216 int uft8_length, |
| 211 int character_position, | 217 int character_position, |
| 212 int utf8_position); | 218 int utf8_position); |
| 213 | 219 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 // E.g., if it requires to be at the start of the input, and isn't. | 533 // E.g., if it requires to be at the start of the input, and isn't. |
| 528 bool cannot_match_; | 534 bool cannot_match_; |
| 529 }; | 535 }; |
| 530 | 536 |
| 531 | 537 |
| 532 extern int kUninitializedRegExpNodePlaceHolder; | 538 extern int kUninitializedRegExpNodePlaceHolder; |
| 533 | 539 |
| 534 | 540 |
| 535 class RegExpNode: public ZoneObject { | 541 class RegExpNode: public ZoneObject { |
| 536 public: | 542 public: |
| 537 RegExpNode() : replacement_(NULL), trace_count_(0) { | 543 explicit RegExpNode(Zone* zone) |
| 544 : replacement_(NULL), trace_count_(0), zone_(zone) { |
| 538 bm_info_[0] = bm_info_[1] = NULL; | 545 bm_info_[0] = bm_info_[1] = NULL; |
| 539 } | 546 } |
| 540 virtual ~RegExpNode(); | 547 virtual ~RegExpNode(); |
| 541 virtual void Accept(NodeVisitor* visitor) = 0; | 548 virtual void Accept(NodeVisitor* visitor) = 0; |
| 542 // Generates a goto to this node or actually generates the code at this point. | 549 // Generates a goto to this node or actually generates the code at this point. |
| 543 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; | 550 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; |
| 544 // How many characters must this node consume at a minimum in order to | 551 // How many characters must this node consume at a minimum in order to |
| 545 // succeed. If we have found at least 'still_to_find' characters that | 552 // succeed. If we have found at least 'still_to_find' characters that |
| 546 // must be consumed there is no need to ask any following nodes whether | 553 // must be consumed there is no need to ask any following nodes whether |
| 547 // they are sure to eat any more characters. The not_at_start argument is | 554 // they are sure to eat any more characters. The not_at_start argument is |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 // trace and generating generic code for a node that can be reused by flushing | 625 // trace and generating generic code for a node that can be reused by flushing |
| 619 // the deferred actions in the current trace and generating a goto. | 626 // the deferred actions in the current trace and generating a goto. |
| 620 static const int kMaxCopiesCodeGenerated = 10; | 627 static const int kMaxCopiesCodeGenerated = 10; |
| 621 | 628 |
| 622 NodeInfo* info() { return &info_; } | 629 NodeInfo* info() { return &info_; } |
| 623 | 630 |
| 624 BoyerMooreLookahead* bm_info(bool not_at_start) { | 631 BoyerMooreLookahead* bm_info(bool not_at_start) { |
| 625 return bm_info_[not_at_start ? 1 : 0]; | 632 return bm_info_[not_at_start ? 1 : 0]; |
| 626 } | 633 } |
| 627 | 634 |
| 635 Zone* zone() { return zone_; } |
| 636 |
| 628 protected: | 637 protected: |
| 629 enum LimitResult { DONE, CONTINUE }; | 638 enum LimitResult { DONE, CONTINUE }; |
| 630 RegExpNode* replacement_; | 639 RegExpNode* replacement_; |
| 631 | 640 |
| 632 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); | 641 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); |
| 633 | 642 |
| 634 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { | 643 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { |
| 635 bm_info_[not_at_start ? 1 : 0] = bm; | 644 bm_info_[not_at_start ? 1 : 0] = bm; |
| 636 } | 645 } |
| 637 | 646 |
| 638 private: | 647 private: |
| 639 static const int kFirstCharBudget = 10; | 648 static const int kFirstCharBudget = 10; |
| 640 Label label_; | 649 Label label_; |
| 641 NodeInfo info_; | 650 NodeInfo info_; |
| 642 // This variable keeps track of how many times code has been generated for | 651 // This variable keeps track of how many times code has been generated for |
| 643 // this node (in different traces). We don't keep track of where the | 652 // this node (in different traces). We don't keep track of where the |
| 644 // generated code is located unless the code is generated at the start of | 653 // generated code is located unless the code is generated at the start of |
| 645 // a trace, in which case it is generic and can be reused by flushing the | 654 // a trace, in which case it is generic and can be reused by flushing the |
| 646 // deferred operations in the current trace and generating a goto. | 655 // deferred operations in the current trace and generating a goto. |
| 647 int trace_count_; | 656 int trace_count_; |
| 648 BoyerMooreLookahead* bm_info_[2]; | 657 BoyerMooreLookahead* bm_info_[2]; |
| 658 |
| 659 Zone* zone_; |
| 649 }; | 660 }; |
| 650 | 661 |
| 651 | 662 |
| 652 // A simple closed interval. | 663 // A simple closed interval. |
| 653 class Interval { | 664 class Interval { |
| 654 public: | 665 public: |
| 655 Interval() : from_(kNone), to_(kNone) { } | 666 Interval() : from_(kNone), to_(kNone) { } |
| 656 Interval(int from, int to) : from_(from), to_(to) { } | 667 Interval(int from, int to) : from_(from), to_(to) { } |
| 657 Interval Union(Interval that) { | 668 Interval Union(Interval that) { |
| 658 if (that.from_ == kNone) | 669 if (that.from_ == kNone) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 672 static const int kNone = -1; | 683 static const int kNone = -1; |
| 673 private: | 684 private: |
| 674 int from_; | 685 int from_; |
| 675 int to_; | 686 int to_; |
| 676 }; | 687 }; |
| 677 | 688 |
| 678 | 689 |
| 679 class SeqRegExpNode: public RegExpNode { | 690 class SeqRegExpNode: public RegExpNode { |
| 680 public: | 691 public: |
| 681 explicit SeqRegExpNode(RegExpNode* on_success) | 692 explicit SeqRegExpNode(RegExpNode* on_success) |
| 682 : on_success_(on_success) { } | 693 : RegExpNode(on_success->zone()), on_success_(on_success) { } |
| 683 RegExpNode* on_success() { return on_success_; } | 694 RegExpNode* on_success() { return on_success_; } |
| 684 void set_on_success(RegExpNode* node) { on_success_ = node; } | 695 void set_on_success(RegExpNode* node) { on_success_ = node; } |
| 685 virtual RegExpNode* FilterASCII(int depth); | 696 virtual RegExpNode* FilterASCII(int depth); |
| 686 virtual void FillInBMInfo(int offset, | 697 virtual void FillInBMInfo(int offset, |
| 687 int recursion_depth, | 698 int recursion_depth, |
| 688 BoyerMooreLookahead* bm, | 699 BoyerMooreLookahead* bm, |
| 689 bool not_at_start) { | 700 bool not_at_start) { |
| 690 on_success_->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start); | 701 on_success_->FillInBMInfo(offset, recursion_depth + 1, bm, not_at_start); |
| 691 if (offset == 0) set_bm_info(not_at_start, bm); | 702 if (offset == 0) set_bm_info(not_at_start, bm); |
| 692 } | 703 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 | 798 |
| 788 class TextNode: public SeqRegExpNode { | 799 class TextNode: public SeqRegExpNode { |
| 789 public: | 800 public: |
| 790 TextNode(ZoneList<TextElement>* elms, | 801 TextNode(ZoneList<TextElement>* elms, |
| 791 RegExpNode* on_success) | 802 RegExpNode* on_success) |
| 792 : SeqRegExpNode(on_success), | 803 : SeqRegExpNode(on_success), |
| 793 elms_(elms) { } | 804 elms_(elms) { } |
| 794 TextNode(RegExpCharacterClass* that, | 805 TextNode(RegExpCharacterClass* that, |
| 795 RegExpNode* on_success) | 806 RegExpNode* on_success) |
| 796 : SeqRegExpNode(on_success), | 807 : SeqRegExpNode(on_success), |
| 797 elms_(new ZoneList<TextElement>(1)) { | 808 elms_(new ZoneList<TextElement>(1, zone())) { |
| 798 elms_->Add(TextElement::CharClass(that)); | 809 elms_->Add(TextElement::CharClass(that), zone()); |
| 799 } | 810 } |
| 800 virtual void Accept(NodeVisitor* visitor); | 811 virtual void Accept(NodeVisitor* visitor); |
| 801 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 812 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 802 virtual int EatsAtLeast(int still_to_find, | 813 virtual int EatsAtLeast(int still_to_find, |
| 803 int recursion_depth, | 814 int recursion_depth, |
| 804 bool not_at_start); | 815 bool not_at_start); |
| 805 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 816 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 806 RegExpCompiler* compiler, | 817 RegExpCompiler* compiler, |
| 807 int characters_filled_in, | 818 int characters_filled_in, |
| 808 bool not_at_start); | 819 bool not_at_start); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 | 931 |
| 921 private: | 932 private: |
| 922 int start_reg_; | 933 int start_reg_; |
| 923 int end_reg_; | 934 int end_reg_; |
| 924 }; | 935 }; |
| 925 | 936 |
| 926 | 937 |
| 927 class EndNode: public RegExpNode { | 938 class EndNode: public RegExpNode { |
| 928 public: | 939 public: |
| 929 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; | 940 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; |
| 930 explicit EndNode(Action action) : action_(action) { } | 941 explicit EndNode(Action action, Zone* zone) |
| 942 : RegExpNode(zone), action_(action) { } |
| 931 virtual void Accept(NodeVisitor* visitor); | 943 virtual void Accept(NodeVisitor* visitor); |
| 932 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 944 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 933 virtual int EatsAtLeast(int still_to_find, | 945 virtual int EatsAtLeast(int still_to_find, |
| 934 int recursion_depth, | 946 int recursion_depth, |
| 935 bool not_at_start) { return 0; } | 947 bool not_at_start) { return 0; } |
| 936 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 948 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 937 RegExpCompiler* compiler, | 949 RegExpCompiler* compiler, |
| 938 int characters_filled_in, | 950 int characters_filled_in, |
| 939 bool not_at_start) { | 951 bool not_at_start) { |
| 940 // Returning 0 from EatsAtLeast should ensure we never get here. | 952 // Returning 0 from EatsAtLeast should ensure we never get here. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 951 private: | 963 private: |
| 952 Action action_; | 964 Action action_; |
| 953 }; | 965 }; |
| 954 | 966 |
| 955 | 967 |
| 956 class NegativeSubmatchSuccess: public EndNode { | 968 class NegativeSubmatchSuccess: public EndNode { |
| 957 public: | 969 public: |
| 958 NegativeSubmatchSuccess(int stack_pointer_reg, | 970 NegativeSubmatchSuccess(int stack_pointer_reg, |
| 959 int position_reg, | 971 int position_reg, |
| 960 int clear_capture_count, | 972 int clear_capture_count, |
| 961 int clear_capture_start) | 973 int clear_capture_start, |
| 962 : EndNode(NEGATIVE_SUBMATCH_SUCCESS), | 974 Zone* zone) |
| 975 : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone), |
| 963 stack_pointer_register_(stack_pointer_reg), | 976 stack_pointer_register_(stack_pointer_reg), |
| 964 current_position_register_(position_reg), | 977 current_position_register_(position_reg), |
| 965 clear_capture_count_(clear_capture_count), | 978 clear_capture_count_(clear_capture_count), |
| 966 clear_capture_start_(clear_capture_start) { } | 979 clear_capture_start_(clear_capture_start) { } |
| 967 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 980 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 968 | 981 |
| 969 private: | 982 private: |
| 970 int stack_pointer_register_; | 983 int stack_pointer_register_; |
| 971 int current_position_register_; | 984 int current_position_register_; |
| 972 int clear_capture_count_; | 985 int clear_capture_count_; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 RegExpNode* node_; | 1017 RegExpNode* node_; |
| 1005 ZoneList<Guard*>* guards_; | 1018 ZoneList<Guard*>* guards_; |
| 1006 }; | 1019 }; |
| 1007 | 1020 |
| 1008 | 1021 |
| 1009 class AlternativeGeneration; | 1022 class AlternativeGeneration; |
| 1010 | 1023 |
| 1011 | 1024 |
| 1012 class ChoiceNode: public RegExpNode { | 1025 class ChoiceNode: public RegExpNode { |
| 1013 public: | 1026 public: |
| 1014 explicit ChoiceNode(int expected_size) | 1027 explicit ChoiceNode(int expected_size, Zone* zone) |
| 1015 : alternatives_(new ZoneList<GuardedAlternative>(expected_size)), | 1028 : RegExpNode(zone), |
| 1029 alternatives_(new ZoneList<GuardedAlternative>(expected_size, zone)), |
| 1016 table_(NULL), | 1030 table_(NULL), |
| 1017 not_at_start_(false), | 1031 not_at_start_(false), |
| 1018 being_calculated_(false) { } | 1032 being_calculated_(false) { } |
| 1019 virtual void Accept(NodeVisitor* visitor); | 1033 virtual void Accept(NodeVisitor* visitor); |
| 1020 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } | 1034 void AddAlternative(GuardedAlternative node) { |
| 1035 alternatives()->Add(node, zone()); |
| 1036 } |
| 1021 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } | 1037 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } |
| 1022 DispatchTable* GetTable(bool ignore_case); | 1038 DispatchTable* GetTable(bool ignore_case); |
| 1023 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 1039 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 1024 virtual int EatsAtLeast(int still_to_find, | 1040 virtual int EatsAtLeast(int still_to_find, |
| 1025 int recursion_depth, | 1041 int recursion_depth, |
| 1026 bool not_at_start); | 1042 bool not_at_start); |
| 1027 int EatsAtLeastHelper(int still_to_find, | 1043 int EatsAtLeastHelper(int still_to_find, |
| 1028 int recursion_depth, | 1044 int recursion_depth, |
| 1029 RegExpNode* ignore_this_node, | 1045 RegExpNode* ignore_this_node, |
| 1030 bool not_at_start); | 1046 bool not_at_start); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1065 // If true, this node is never checked at the start of the input. | 1081 // If true, this node is never checked at the start of the input. |
| 1066 // Allows a new trace to start with at_start() set to false. | 1082 // Allows a new trace to start with at_start() set to false. |
| 1067 bool not_at_start_; | 1083 bool not_at_start_; |
| 1068 bool being_calculated_; | 1084 bool being_calculated_; |
| 1069 }; | 1085 }; |
| 1070 | 1086 |
| 1071 | 1087 |
| 1072 class NegativeLookaheadChoiceNode: public ChoiceNode { | 1088 class NegativeLookaheadChoiceNode: public ChoiceNode { |
| 1073 public: | 1089 public: |
| 1074 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, | 1090 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, |
| 1075 GuardedAlternative then_do_this) | 1091 GuardedAlternative then_do_this, |
| 1076 : ChoiceNode(2) { | 1092 Zone* zone) |
| 1093 : ChoiceNode(2, zone) { |
| 1077 AddAlternative(this_must_fail); | 1094 AddAlternative(this_must_fail); |
| 1078 AddAlternative(then_do_this); | 1095 AddAlternative(then_do_this); |
| 1079 } | 1096 } |
| 1080 virtual int EatsAtLeast(int still_to_find, | 1097 virtual int EatsAtLeast(int still_to_find, |
| 1081 int recursion_depth, | 1098 int recursion_depth, |
| 1082 bool not_at_start); | 1099 bool not_at_start); |
| 1083 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1100 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 1084 RegExpCompiler* compiler, | 1101 RegExpCompiler* compiler, |
| 1085 int characters_filled_in, | 1102 int characters_filled_in, |
| 1086 bool not_at_start); | 1103 bool not_at_start); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1097 // starts by loading enough characters for the alternative that takes fewest | 1114 // starts by loading enough characters for the alternative that takes fewest |
| 1098 // characters, but on a negative lookahead the negative branch did not take | 1115 // characters, but on a negative lookahead the negative branch did not take |
| 1099 // part in that calculation (EatsAtLeast) so the assumptions don't hold. | 1116 // part in that calculation (EatsAtLeast) so the assumptions don't hold. |
| 1100 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } | 1117 virtual bool try_to_emit_quick_check_for_alternative(int i) { return i != 0; } |
| 1101 virtual RegExpNode* FilterASCII(int depth); | 1118 virtual RegExpNode* FilterASCII(int depth); |
| 1102 }; | 1119 }; |
| 1103 | 1120 |
| 1104 | 1121 |
| 1105 class LoopChoiceNode: public ChoiceNode { | 1122 class LoopChoiceNode: public ChoiceNode { |
| 1106 public: | 1123 public: |
| 1107 explicit LoopChoiceNode(bool body_can_be_zero_length) | 1124 explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone) |
| 1108 : ChoiceNode(2), | 1125 : ChoiceNode(2, zone), |
| 1109 loop_node_(NULL), | 1126 loop_node_(NULL), |
| 1110 continue_node_(NULL), | 1127 continue_node_(NULL), |
| 1111 body_can_be_zero_length_(body_can_be_zero_length) { } | 1128 body_can_be_zero_length_(body_can_be_zero_length) { } |
| 1112 void AddLoopAlternative(GuardedAlternative alt); | 1129 void AddLoopAlternative(GuardedAlternative alt); |
| 1113 void AddContinueAlternative(GuardedAlternative alt); | 1130 void AddContinueAlternative(GuardedAlternative alt); |
| 1114 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 1131 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 1115 virtual int EatsAtLeast(int still_to_find, | 1132 virtual int EatsAtLeast(int still_to_find, |
| 1116 int recursion_depth, | 1133 int recursion_depth, |
| 1117 bool not_at_start); | 1134 bool not_at_start); |
| 1118 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 1135 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 | 1199 |
| 1183 | 1200 |
| 1184 ContainedInLattice AddRange(ContainedInLattice a, | 1201 ContainedInLattice AddRange(ContainedInLattice a, |
| 1185 const int* ranges, | 1202 const int* ranges, |
| 1186 int ranges_size, | 1203 int ranges_size, |
| 1187 Interval new_range); | 1204 Interval new_range); |
| 1188 | 1205 |
| 1189 | 1206 |
| 1190 class BoyerMoorePositionInfo : public ZoneObject { | 1207 class BoyerMoorePositionInfo : public ZoneObject { |
| 1191 public: | 1208 public: |
| 1192 BoyerMoorePositionInfo() | 1209 explicit BoyerMoorePositionInfo(Zone* zone) |
| 1193 : map_(new ZoneList<bool>(kMapSize)), | 1210 : map_(new ZoneList<bool>(kMapSize, zone)), |
| 1194 map_count_(0), | 1211 map_count_(0), |
| 1195 w_(kNotYet), | 1212 w_(kNotYet), |
| 1196 s_(kNotYet), | 1213 s_(kNotYet), |
| 1197 d_(kNotYet), | 1214 d_(kNotYet), |
| 1198 surrogate_(kNotYet) { | 1215 surrogate_(kNotYet) { |
| 1199 for (int i = 0; i < kMapSize; i++) { | 1216 for (int i = 0; i < kMapSize; i++) { |
| 1200 map_->Add(false); | 1217 map_->Add(false, zone); |
| 1201 } | 1218 } |
| 1202 } | 1219 } |
| 1203 | 1220 |
| 1204 bool& at(int i) { return map_->at(i); } | 1221 bool& at(int i) { return map_->at(i); } |
| 1205 | 1222 |
| 1206 static const int kMapSize = 128; | 1223 static const int kMapSize = 128; |
| 1207 static const int kMask = kMapSize - 1; | 1224 static const int kMask = kMapSize - 1; |
| 1208 | 1225 |
| 1209 int map_count() const { return map_count_; } | 1226 int map_count() const { return map_count_; } |
| 1210 | 1227 |
| 1211 void Set(int character); | 1228 void Set(int character); |
| 1212 void SetInterval(const Interval& interval); | 1229 void SetInterval(const Interval& interval); |
| 1213 void SetAll(); | 1230 void SetAll(); |
| 1214 bool is_non_word() { return w_ == kLatticeOut; } | 1231 bool is_non_word() { return w_ == kLatticeOut; } |
| 1215 bool is_word() { return w_ == kLatticeIn; } | 1232 bool is_word() { return w_ == kLatticeIn; } |
| 1216 | 1233 |
| 1217 private: | 1234 private: |
| 1218 ZoneList<bool>* map_; | 1235 ZoneList<bool>* map_; |
| 1219 int map_count_; // Number of set bits in the map. | 1236 int map_count_; // Number of set bits in the map. |
| 1220 ContainedInLattice w_; // The \w character class. | 1237 ContainedInLattice w_; // The \w character class. |
| 1221 ContainedInLattice s_; // The \s character class. | 1238 ContainedInLattice s_; // The \s character class. |
| 1222 ContainedInLattice d_; // The \d character class. | 1239 ContainedInLattice d_; // The \d character class. |
| 1223 ContainedInLattice surrogate_; // Surrogate UTF-16 code units. | 1240 ContainedInLattice surrogate_; // Surrogate UTF-16 code units. |
| 1224 }; | 1241 }; |
| 1225 | 1242 |
| 1226 | 1243 |
| 1227 class BoyerMooreLookahead : public ZoneObject { | 1244 class BoyerMooreLookahead : public ZoneObject { |
| 1228 public: | 1245 public: |
| 1229 BoyerMooreLookahead(int length, RegExpCompiler* compiler); | 1246 BoyerMooreLookahead(int length, RegExpCompiler* compiler, Zone* zone); |
| 1230 | 1247 |
| 1231 int length() { return length_; } | 1248 int length() { return length_; } |
| 1232 int max_char() { return max_char_; } | 1249 int max_char() { return max_char_; } |
| 1233 RegExpCompiler* compiler() { return compiler_; } | 1250 RegExpCompiler* compiler() { return compiler_; } |
| 1234 | 1251 |
| 1235 int Count(int map_number) { | 1252 int Count(int map_number) { |
| 1236 return bitmaps_->at(map_number)->map_count(); | 1253 return bitmaps_->at(map_number)->map_count(); |
| 1237 } | 1254 } |
| 1238 | 1255 |
| 1239 BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); } | 1256 BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); } |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 Object* code; | 1586 Object* code; |
| 1570 int num_registers; | 1587 int num_registers; |
| 1571 }; | 1588 }; |
| 1572 | 1589 |
| 1573 static CompilationResult Compile(RegExpCompileData* input, | 1590 static CompilationResult Compile(RegExpCompileData* input, |
| 1574 bool ignore_case, | 1591 bool ignore_case, |
| 1575 bool global, | 1592 bool global, |
| 1576 bool multiline, | 1593 bool multiline, |
| 1577 Handle<String> pattern, | 1594 Handle<String> pattern, |
| 1578 Handle<String> sample_subject, | 1595 Handle<String> sample_subject, |
| 1579 bool is_ascii); | 1596 bool is_ascii, Zone* zone); |
| 1580 | 1597 |
| 1581 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); | 1598 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); |
| 1582 }; | 1599 }; |
| 1583 | 1600 |
| 1584 | 1601 |
| 1585 class OffsetsVector { | 1602 class OffsetsVector { |
| 1586 public: | 1603 public: |
| 1587 inline OffsetsVector(int num_registers, Isolate* isolate) | 1604 inline OffsetsVector(int num_registers, Isolate* isolate) |
| 1588 : offsets_vector_length_(num_registers) { | 1605 : offsets_vector_length_(num_registers) { |
| 1589 if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize) { | 1606 if (offsets_vector_length_ > Isolate::kJSRegexpStaticOffsetsVectorSize) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1612 int* vector_; | 1629 int* vector_; |
| 1613 int offsets_vector_length_; | 1630 int offsets_vector_length_; |
| 1614 | 1631 |
| 1615 friend class ExternalReference; | 1632 friend class ExternalReference; |
| 1616 }; | 1633 }; |
| 1617 | 1634 |
| 1618 | 1635 |
| 1619 } } // namespace v8::internal | 1636 } } // namespace v8::internal |
| 1620 | 1637 |
| 1621 #endif // V8_JSREGEXP_H_ | 1638 #endif // V8_JSREGEXP_H_ |
| OLD | NEW |