| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_REGEXP_H_ | 5 #ifndef VM_REGEXP_H_ |
| 6 #define VM_REGEXP_H_ | 6 #define VM_REGEXP_H_ |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 bool Contains(uint16_t i) const { return from_ <= i && i <= to_; } | 44 bool Contains(uint16_t i) const { return from_ <= i && i <= to_; } |
| 45 uint16_t from() const { return from_; } | 45 uint16_t from() const { return from_; } |
| 46 void set_from(uint16_t value) { from_ = value; } | 46 void set_from(uint16_t value) { from_ = value; } |
| 47 uint16_t to() const { return to_; } | 47 uint16_t to() const { return to_; } |
| 48 void set_to(uint16_t value) { to_ = value; } | 48 void set_to(uint16_t value) { to_ = value; } |
| 49 bool is_valid() const { return from_ <= to_; } | 49 bool is_valid() const { return from_ <= to_; } |
| 50 bool IsEverything(uint16_t max) const { return from_ == 0 && to_ >= max; } | 50 bool IsEverything(uint16_t max) const { return from_ == 0 && to_ >= max; } |
| 51 bool IsSingleton() const { return (from_ == to_); } | 51 bool IsSingleton() const { return (from_ == to_); } |
| 52 void AddCaseEquivalents(ZoneGrowableArray<CharacterRange>* ranges, | 52 void AddCaseEquivalents(ZoneGrowableArray<CharacterRange>* ranges, |
| 53 bool is_one_byte, | 53 bool is_one_byte, |
| 54 Isolate* isolate); | 54 Zone* zone); |
| 55 static void Split(ZoneGrowableArray<CharacterRange>* base, | 55 static void Split(ZoneGrowableArray<CharacterRange>* base, |
| 56 GrowableArray<const intptr_t> overlay, | 56 GrowableArray<const intptr_t> overlay, |
| 57 ZoneGrowableArray<CharacterRange>** included, | 57 ZoneGrowableArray<CharacterRange>** included, |
| 58 ZoneGrowableArray<CharacterRange>** excluded, | 58 ZoneGrowableArray<CharacterRange>** excluded, |
| 59 Isolate* isolate); | 59 Zone* zone); |
| 60 // Whether a range list is in canonical form: Ranges ordered by from value, | 60 // Whether a range list is in canonical form: Ranges ordered by from value, |
| 61 // and ranges non-overlapping and non-adjacent. | 61 // and ranges non-overlapping and non-adjacent. |
| 62 static bool IsCanonical(ZoneGrowableArray<CharacterRange>* ranges); | 62 static bool IsCanonical(ZoneGrowableArray<CharacterRange>* ranges); |
| 63 // Convert range list to canonical form. The characters covered by the ranges | 63 // Convert range list to canonical form. The characters covered by the ranges |
| 64 // will still be the same, but no character is in more than one range, and | 64 // will still be the same, but no character is in more than one range, and |
| 65 // adjacent ranges are merged. The resulting list may be shorter than the | 65 // adjacent ranges are merged. The resulting list may be shorter than the |
| 66 // original, but cannot be longer. | 66 // original, but cannot be longer. |
| 67 static void Canonicalize(ZoneGrowableArray<CharacterRange>* ranges); | 67 static void Canonicalize(ZoneGrowableArray<CharacterRange>* ranges); |
| 68 // Negate the contents of a character range in canonical form. | 68 // Negate the contents of a character range in canonical form. |
| 69 static void Negate(ZoneGrowableArray<CharacterRange>* src, | 69 static void Negate(ZoneGrowableArray<CharacterRange>* src, |
| 70 ZoneGrowableArray<CharacterRange>* dst); | 70 ZoneGrowableArray<CharacterRange>* dst); |
| 71 static const intptr_t kStartMarker = (1 << 24); | 71 static const intptr_t kStartMarker = (1 << 24); |
| 72 static const intptr_t kPayloadMask = (1 << 24) - 1; | 72 static const intptr_t kPayloadMask = (1 << 24) - 1; |
| 73 | 73 |
| 74 private: | 74 private: |
| 75 uint16_t from_; | 75 uint16_t from_; |
| 76 uint16_t to_; | 76 uint16_t to_; |
| 77 | 77 |
| 78 DISALLOW_ALLOCATION(); | 78 DISALLOW_ALLOCATION(); |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 | 81 |
| 82 // A set of unsigned integers that behaves especially well on small | 82 // A set of unsigned integers that behaves especially well on small |
| 83 // integers (< 32). May do zone-allocation. | 83 // integers (< 32). May do zone-allocation. |
| 84 class OutSet: public ZoneAllocated { | 84 class OutSet: public ZoneAllocated { |
| 85 public: | 85 public: |
| 86 OutSet() : first_(0), remaining_(NULL), successors_(NULL) { } | 86 OutSet() : first_(0), remaining_(NULL), successors_(NULL) { } |
| 87 OutSet* Extend(unsigned value, Isolate* isolate); | 87 OutSet* Extend(unsigned value, Zone* zone); |
| 88 bool Get(unsigned value) const; | 88 bool Get(unsigned value) const; |
| 89 static const unsigned kFirstLimit = 32; | 89 static const unsigned kFirstLimit = 32; |
| 90 | 90 |
| 91 private: | 91 private: |
| 92 // Destructively set a value in this set. In most cases you want | 92 // Destructively set a value in this set. In most cases you want |
| 93 // to use Extend instead to ensure that only one instance exists | 93 // to use Extend instead to ensure that only one instance exists |
| 94 // that contains the same values. | 94 // that contains the same values. |
| 95 void Set(unsigned value, Isolate* isolate); | 95 void Set(unsigned value, Zone* zone); |
| 96 | 96 |
| 97 // The successors are a list of sets that contain the same values | 97 // The successors are a list of sets that contain the same values |
| 98 // as this set and the one more value that is not present in this | 98 // as this set and the one more value that is not present in this |
| 99 // set. | 99 // set. |
| 100 ZoneGrowableArray<OutSet*>* successors() { return successors_; } | 100 ZoneGrowableArray<OutSet*>* successors() { return successors_; } |
| 101 | 101 |
| 102 OutSet(uint32_t first, ZoneGrowableArray<unsigned>* remaining) | 102 OutSet(uint32_t first, ZoneGrowableArray<unsigned>* remaining) |
| 103 : first_(first), remaining_(remaining), successors_(NULL) { } | 103 : first_(first), remaining_(remaining), successors_(NULL) { } |
| 104 uint32_t first_; | 104 uint32_t first_; |
| 105 ZoneGrowableArray<unsigned>* remaining_; | 105 ZoneGrowableArray<unsigned>* remaining_; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 // If set to true, there is no way this quick check can match at all. | 293 // If set to true, there is no way this quick check can match at all. |
| 294 // E.g., if it requires to be at the start of the input, and isn't. | 294 // E.g., if it requires to be at the start of the input, and isn't. |
| 295 bool cannot_match_; | 295 bool cannot_match_; |
| 296 | 296 |
| 297 DISALLOW_ALLOCATION(); | 297 DISALLOW_ALLOCATION(); |
| 298 }; | 298 }; |
| 299 | 299 |
| 300 | 300 |
| 301 class RegExpNode: public ZoneAllocated { | 301 class RegExpNode: public ZoneAllocated { |
| 302 public: | 302 public: |
| 303 explicit RegExpNode(Isolate* isolate) | 303 explicit RegExpNode(Zone* zone) |
| 304 : replacement_(NULL), trace_count_(0), isolate_(isolate) { | 304 : replacement_(NULL), trace_count_(0), zone_(zone) { |
| 305 bm_info_[0] = bm_info_[1] = NULL; | 305 bm_info_[0] = bm_info_[1] = NULL; |
| 306 } | 306 } |
| 307 virtual ~RegExpNode(); | 307 virtual ~RegExpNode(); |
| 308 virtual void Accept(NodeVisitor* visitor) = 0; | 308 virtual void Accept(NodeVisitor* visitor) = 0; |
| 309 // Generates a goto to this node or actually generates the code at this point. | 309 // Generates a goto to this node or actually generates the code at this point. |
| 310 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; | 310 virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0; |
| 311 // How many characters must this node consume at a minimum in order to | 311 // How many characters must this node consume at a minimum in order to |
| 312 // succeed. If we have found at least 'still_to_find' characters that | 312 // succeed. If we have found at least 'still_to_find' characters that |
| 313 // must be consumed there is no need to ask any following nodes whether | 313 // must be consumed there is no need to ask any following nodes whether |
| 314 // they are sure to eat any more characters. The not_at_start argument is | 314 // they are sure to eat any more characters. The not_at_start argument is |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 // trace and generating generic code for a node that can be reused by flushing | 391 // trace and generating generic code for a node that can be reused by flushing |
| 392 // the deferred actions in the current trace and generating a goto. | 392 // the deferred actions in the current trace and generating a goto. |
| 393 static const intptr_t kMaxCopiesCodeGenerated = 10; | 393 static const intptr_t kMaxCopiesCodeGenerated = 10; |
| 394 | 394 |
| 395 NodeInfo* info() { return &info_; } | 395 NodeInfo* info() { return &info_; } |
| 396 | 396 |
| 397 BoyerMooreLookahead* bm_info(bool not_at_start) { | 397 BoyerMooreLookahead* bm_info(bool not_at_start) { |
| 398 return bm_info_[not_at_start ? 1 : 0]; | 398 return bm_info_[not_at_start ? 1 : 0]; |
| 399 } | 399 } |
| 400 | 400 |
| 401 Isolate* isolate() const { return isolate_; } | 401 Zone* zone() const { return zone_; } |
| 402 | 402 |
| 403 protected: | 403 protected: |
| 404 enum LimitResult { DONE, CONTINUE }; | 404 enum LimitResult { DONE, CONTINUE }; |
| 405 RegExpNode* replacement_; | 405 RegExpNode* replacement_; |
| 406 | 406 |
| 407 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); | 407 LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace); |
| 408 | 408 |
| 409 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { | 409 void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) { |
| 410 bm_info_[not_at_start ? 1 : 0] = bm; | 410 bm_info_[not_at_start ? 1 : 0] = bm; |
| 411 } | 411 } |
| 412 | 412 |
| 413 private: | 413 private: |
| 414 static const intptr_t kFirstCharBudget = 10; | 414 static const intptr_t kFirstCharBudget = 10; |
| 415 BlockLabel label_; | 415 BlockLabel label_; |
| 416 NodeInfo info_; | 416 NodeInfo info_; |
| 417 // This variable keeps track of how many times code has been generated for | 417 // This variable keeps track of how many times code has been generated for |
| 418 // this node (in different traces). We don't keep track of where the | 418 // this node (in different traces). We don't keep track of where the |
| 419 // generated code is located unless the code is generated at the start of | 419 // generated code is located unless the code is generated at the start of |
| 420 // a trace, in which case it is generic and can be reused by flushing the | 420 // a trace, in which case it is generic and can be reused by flushing the |
| 421 // deferred operations in the current trace and generating a goto. | 421 // deferred operations in the current trace and generating a goto. |
| 422 intptr_t trace_count_; | 422 intptr_t trace_count_; |
| 423 BoyerMooreLookahead* bm_info_[2]; | 423 BoyerMooreLookahead* bm_info_[2]; |
| 424 Isolate* isolate_; | 424 Zone* zone_; |
| 425 }; | 425 }; |
| 426 | 426 |
| 427 | 427 |
| 428 // A simple closed interval. | 428 // A simple closed interval. |
| 429 class Interval { | 429 class Interval { |
| 430 public: | 430 public: |
| 431 Interval() : from_(kNone), to_(kNone) { } | 431 Interval() : from_(kNone), to_(kNone) { } |
| 432 Interval(intptr_t from, intptr_t to) : from_(from), to_(to) { } | 432 Interval(intptr_t from, intptr_t to) : from_(from), to_(to) { } |
| 433 | 433 |
| 434 Interval Union(Interval that) { | 434 Interval Union(Interval that) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 453 intptr_t from_; | 453 intptr_t from_; |
| 454 intptr_t to_; | 454 intptr_t to_; |
| 455 | 455 |
| 456 DISALLOW_ALLOCATION(); | 456 DISALLOW_ALLOCATION(); |
| 457 }; | 457 }; |
| 458 | 458 |
| 459 | 459 |
| 460 class SeqRegExpNode: public RegExpNode { | 460 class SeqRegExpNode: public RegExpNode { |
| 461 public: | 461 public: |
| 462 explicit SeqRegExpNode(RegExpNode* on_success) | 462 explicit SeqRegExpNode(RegExpNode* on_success) |
| 463 : RegExpNode(on_success->isolate()), on_success_(on_success) { } | 463 : RegExpNode(on_success->zone()), on_success_(on_success) { } |
| 464 RegExpNode* on_success() { return on_success_; } | 464 RegExpNode* on_success() { return on_success_; } |
| 465 void set_on_success(RegExpNode* node) { on_success_ = node; } | 465 void set_on_success(RegExpNode* node) { on_success_ = node; } |
| 466 virtual RegExpNode* FilterOneByte(intptr_t depth, bool ignore_case); | 466 virtual RegExpNode* FilterOneByte(intptr_t depth, bool ignore_case); |
| 467 virtual void FillInBMInfo(intptr_t offset, | 467 virtual void FillInBMInfo(intptr_t offset, |
| 468 intptr_t budget, | 468 intptr_t budget, |
| 469 BoyerMooreLookahead* bm, | 469 BoyerMooreLookahead* bm, |
| 470 bool not_at_start) { | 470 bool not_at_start) { |
| 471 on_success_->FillInBMInfo(offset, budget - 1, bm, not_at_start); | 471 on_success_->FillInBMInfo(offset, budget - 1, bm, not_at_start); |
| 472 if (offset == 0) set_bm_info(not_at_start, bm); | 472 if (offset == 0) set_bm_info(not_at_start, bm); |
| 473 } | 473 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 | 570 |
| 571 class TextNode: public SeqRegExpNode { | 571 class TextNode: public SeqRegExpNode { |
| 572 public: | 572 public: |
| 573 TextNode(ZoneGrowableArray<TextElement>* elms, | 573 TextNode(ZoneGrowableArray<TextElement>* elms, |
| 574 RegExpNode* on_success) | 574 RegExpNode* on_success) |
| 575 : SeqRegExpNode(on_success), | 575 : SeqRegExpNode(on_success), |
| 576 elms_(elms) { } | 576 elms_(elms) { } |
| 577 TextNode(RegExpCharacterClass* that, | 577 TextNode(RegExpCharacterClass* that, |
| 578 RegExpNode* on_success) | 578 RegExpNode* on_success) |
| 579 : SeqRegExpNode(on_success), | 579 : SeqRegExpNode(on_success), |
| 580 elms_(new(isolate()) ZoneGrowableArray<TextElement>(1)) { | 580 elms_(new(zone()) ZoneGrowableArray<TextElement>(1)) { |
| 581 elms_->Add(TextElement::CharClass(that)); | 581 elms_->Add(TextElement::CharClass(that)); |
| 582 } | 582 } |
| 583 virtual void Accept(NodeVisitor* visitor); | 583 virtual void Accept(NodeVisitor* visitor); |
| 584 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 584 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 585 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, | 585 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, |
| 586 bool not_at_start); | 586 bool not_at_start); |
| 587 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 587 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 588 RegExpCompiler* compiler, | 588 RegExpCompiler* compiler, |
| 589 intptr_t characters_filled_in, | 589 intptr_t characters_filled_in, |
| 590 bool not_at_start); | 590 bool not_at_start); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 class AssertionNode: public SeqRegExpNode { | 625 class AssertionNode: public SeqRegExpNode { |
| 626 public: | 626 public: |
| 627 enum AssertionType { | 627 enum AssertionType { |
| 628 AT_END, | 628 AT_END, |
| 629 AT_START, | 629 AT_START, |
| 630 AT_BOUNDARY, | 630 AT_BOUNDARY, |
| 631 AT_NON_BOUNDARY, | 631 AT_NON_BOUNDARY, |
| 632 AFTER_NEWLINE | 632 AFTER_NEWLINE |
| 633 }; | 633 }; |
| 634 static AssertionNode* AtEnd(RegExpNode* on_success) { | 634 static AssertionNode* AtEnd(RegExpNode* on_success) { |
| 635 return new(on_success->isolate()) AssertionNode(AT_END, on_success); | 635 return new(on_success->zone()) AssertionNode(AT_END, on_success); |
| 636 } | 636 } |
| 637 static AssertionNode* AtStart(RegExpNode* on_success) { | 637 static AssertionNode* AtStart(RegExpNode* on_success) { |
| 638 return new(on_success->isolate()) AssertionNode(AT_START, on_success); | 638 return new(on_success->zone()) AssertionNode(AT_START, on_success); |
| 639 } | 639 } |
| 640 static AssertionNode* AtBoundary(RegExpNode* on_success) { | 640 static AssertionNode* AtBoundary(RegExpNode* on_success) { |
| 641 return new(on_success->isolate()) AssertionNode(AT_BOUNDARY, on_success); | 641 return new(on_success->zone()) AssertionNode(AT_BOUNDARY, on_success); |
| 642 } | 642 } |
| 643 static AssertionNode* AtNonBoundary(RegExpNode* on_success) { | 643 static AssertionNode* AtNonBoundary(RegExpNode* on_success) { |
| 644 return new(on_success->isolate()) AssertionNode(AT_NON_BOUNDARY, | 644 return new(on_success->zone()) AssertionNode(AT_NON_BOUNDARY, |
| 645 on_success); | 645 on_success); |
| 646 } | 646 } |
| 647 static AssertionNode* AfterNewline(RegExpNode* on_success) { | 647 static AssertionNode* AfterNewline(RegExpNode* on_success) { |
| 648 return new(on_success->isolate()) AssertionNode(AFTER_NEWLINE, on_success); | 648 return new(on_success->zone()) AssertionNode(AFTER_NEWLINE, on_success); |
| 649 } | 649 } |
| 650 virtual void Accept(NodeVisitor* visitor); | 650 virtual void Accept(NodeVisitor* visitor); |
| 651 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 651 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 652 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, | 652 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, |
| 653 bool not_at_start); | 653 bool not_at_start); |
| 654 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 654 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 655 RegExpCompiler* compiler, | 655 RegExpCompiler* compiler, |
| 656 intptr_t filled_in, | 656 intptr_t filled_in, |
| 657 bool not_at_start); | 657 bool not_at_start); |
| 658 virtual void FillInBMInfo(intptr_t offset, | 658 virtual void FillInBMInfo(intptr_t offset, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 | 701 |
| 702 private: | 702 private: |
| 703 intptr_t start_reg_; | 703 intptr_t start_reg_; |
| 704 intptr_t end_reg_; | 704 intptr_t end_reg_; |
| 705 }; | 705 }; |
| 706 | 706 |
| 707 | 707 |
| 708 class EndNode: public RegExpNode { | 708 class EndNode: public RegExpNode { |
| 709 public: | 709 public: |
| 710 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; | 710 enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS }; |
| 711 explicit EndNode(Action action, Isolate* isolate) | 711 explicit EndNode(Action action, Zone* zone) |
| 712 : RegExpNode(isolate), action_(action) { } | 712 : RegExpNode(zone), action_(action) { } |
| 713 virtual void Accept(NodeVisitor* visitor); | 713 virtual void Accept(NodeVisitor* visitor); |
| 714 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 714 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 715 virtual intptr_t EatsAtLeast(intptr_t still_to_find, | 715 virtual intptr_t EatsAtLeast(intptr_t still_to_find, |
| 716 intptr_t recursion_depth, | 716 intptr_t recursion_depth, |
| 717 bool not_at_start) { return 0; } | 717 bool not_at_start) { return 0; } |
| 718 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 718 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 719 RegExpCompiler* compiler, | 719 RegExpCompiler* compiler, |
| 720 intptr_t characters_filled_in, | 720 intptr_t characters_filled_in, |
| 721 bool not_at_start) { | 721 bool not_at_start) { |
| 722 // Returning 0 from EatsAtLeast should ensure we never get here. | 722 // Returning 0 from EatsAtLeast should ensure we never get here. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 734 Action action_; | 734 Action action_; |
| 735 }; | 735 }; |
| 736 | 736 |
| 737 | 737 |
| 738 class NegativeSubmatchSuccess: public EndNode { | 738 class NegativeSubmatchSuccess: public EndNode { |
| 739 public: | 739 public: |
| 740 NegativeSubmatchSuccess(intptr_t stack_pointer_reg, | 740 NegativeSubmatchSuccess(intptr_t stack_pointer_reg, |
| 741 intptr_t position_reg, | 741 intptr_t position_reg, |
| 742 intptr_t clear_capture_count, | 742 intptr_t clear_capture_count, |
| 743 intptr_t clear_capture_start, | 743 intptr_t clear_capture_start, |
| 744 Isolate* isolate) | 744 Zone* zone) |
| 745 : EndNode(NEGATIVE_SUBMATCH_SUCCESS, isolate), | 745 : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone), |
| 746 stack_pointer_register_(stack_pointer_reg), | 746 stack_pointer_register_(stack_pointer_reg), |
| 747 current_position_register_(position_reg), | 747 current_position_register_(position_reg), |
| 748 clear_capture_count_(clear_capture_count), | 748 clear_capture_count_(clear_capture_count), |
| 749 clear_capture_start_(clear_capture_start) { } | 749 clear_capture_start_(clear_capture_start) { } |
| 750 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 750 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 751 | 751 |
| 752 private: | 752 private: |
| 753 intptr_t stack_pointer_register_; | 753 intptr_t stack_pointer_register_; |
| 754 intptr_t current_position_register_; | 754 intptr_t current_position_register_; |
| 755 intptr_t clear_capture_count_; | 755 intptr_t clear_capture_count_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 771 private: | 771 private: |
| 772 intptr_t reg_; | 772 intptr_t reg_; |
| 773 Relation op_; | 773 Relation op_; |
| 774 intptr_t value_; | 774 intptr_t value_; |
| 775 }; | 775 }; |
| 776 | 776 |
| 777 | 777 |
| 778 class GuardedAlternative { | 778 class GuardedAlternative { |
| 779 public: | 779 public: |
| 780 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } | 780 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } |
| 781 void AddGuard(Guard* guard, Isolate* isolate); | 781 void AddGuard(Guard* guard, Zone* zone); |
| 782 RegExpNode* node() { return node_; } | 782 RegExpNode* node() { return node_; } |
| 783 void set_node(RegExpNode* node) { node_ = node; } | 783 void set_node(RegExpNode* node) { node_ = node; } |
| 784 ZoneGrowableArray<Guard*>* guards() { return guards_; } | 784 ZoneGrowableArray<Guard*>* guards() { return guards_; } |
| 785 | 785 |
| 786 private: | 786 private: |
| 787 RegExpNode* node_; | 787 RegExpNode* node_; |
| 788 ZoneGrowableArray<Guard*>* guards_; | 788 ZoneGrowableArray<Guard*>* guards_; |
| 789 | 789 |
| 790 DISALLOW_ALLOCATION(); | 790 DISALLOW_ALLOCATION(); |
| 791 }; | 791 }; |
| 792 | 792 |
| 793 | 793 |
| 794 struct AlternativeGeneration; | 794 struct AlternativeGeneration; |
| 795 | 795 |
| 796 | 796 |
| 797 class ChoiceNode: public RegExpNode { | 797 class ChoiceNode: public RegExpNode { |
| 798 public: | 798 public: |
| 799 explicit ChoiceNode(intptr_t expected_size, Isolate* isolate) | 799 explicit ChoiceNode(intptr_t expected_size, Zone* zone) |
| 800 : RegExpNode(isolate), | 800 : RegExpNode(zone), |
| 801 alternatives_(new(isolate) | 801 alternatives_(new(zone) |
| 802 ZoneGrowableArray<GuardedAlternative>(expected_size)), | 802 ZoneGrowableArray<GuardedAlternative>(expected_size)), |
| 803 not_at_start_(false), | 803 not_at_start_(false), |
| 804 being_calculated_(false) { } | 804 being_calculated_(false) { } |
| 805 virtual void Accept(NodeVisitor* visitor); | 805 virtual void Accept(NodeVisitor* visitor); |
| 806 void AddAlternative(GuardedAlternative node) { | 806 void AddAlternative(GuardedAlternative node) { |
| 807 alternatives()->Add(node); | 807 alternatives()->Add(node); |
| 808 } | 808 } |
| 809 ZoneGrowableArray<GuardedAlternative>* alternatives() { | 809 ZoneGrowableArray<GuardedAlternative>* alternatives() { |
| 810 return alternatives_; | 810 return alternatives_; |
| 811 } | 811 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 // Allows a new trace to start with at_start() set to false. | 872 // Allows a new trace to start with at_start() set to false. |
| 873 bool not_at_start_; | 873 bool not_at_start_; |
| 874 bool being_calculated_; | 874 bool being_calculated_; |
| 875 }; | 875 }; |
| 876 | 876 |
| 877 | 877 |
| 878 class NegativeLookaheadChoiceNode: public ChoiceNode { | 878 class NegativeLookaheadChoiceNode: public ChoiceNode { |
| 879 public: | 879 public: |
| 880 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, | 880 explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail, |
| 881 GuardedAlternative then_do_this, | 881 GuardedAlternative then_do_this, |
| 882 Isolate* isolate) | 882 Zone* zone) |
| 883 : ChoiceNode(2, isolate) { | 883 : ChoiceNode(2, zone) { |
| 884 AddAlternative(this_must_fail); | 884 AddAlternative(this_must_fail); |
| 885 AddAlternative(then_do_this); | 885 AddAlternative(then_do_this); |
| 886 } | 886 } |
| 887 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, | 887 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, |
| 888 bool not_at_start); | 888 bool not_at_start); |
| 889 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 889 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 890 RegExpCompiler* compiler, | 890 RegExpCompiler* compiler, |
| 891 intptr_t characters_filled_in, | 891 intptr_t characters_filled_in, |
| 892 bool not_at_start); | 892 bool not_at_start); |
| 893 virtual void FillInBMInfo(intptr_t offset, | 893 virtual void FillInBMInfo(intptr_t offset, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 905 // part in that calculation (EatsAtLeast) so the assumptions don't hold. | 905 // part in that calculation (EatsAtLeast) so the assumptions don't hold. |
| 906 virtual bool try_to_emit_quick_check_for_alternative(bool is_first) { | 906 virtual bool try_to_emit_quick_check_for_alternative(bool is_first) { |
| 907 return !is_first; | 907 return !is_first; |
| 908 } | 908 } |
| 909 virtual RegExpNode* FilterOneByte(intptr_t depth, bool ignore_case); | 909 virtual RegExpNode* FilterOneByte(intptr_t depth, bool ignore_case); |
| 910 }; | 910 }; |
| 911 | 911 |
| 912 | 912 |
| 913 class LoopChoiceNode: public ChoiceNode { | 913 class LoopChoiceNode: public ChoiceNode { |
| 914 public: | 914 public: |
| 915 explicit LoopChoiceNode(bool body_can_be_zero_length, Isolate* isolate) | 915 explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone) |
| 916 : ChoiceNode(2, isolate), | 916 : ChoiceNode(2, zone), |
| 917 loop_node_(NULL), | 917 loop_node_(NULL), |
| 918 continue_node_(NULL), | 918 continue_node_(NULL), |
| 919 body_can_be_zero_length_(body_can_be_zero_length) { } | 919 body_can_be_zero_length_(body_can_be_zero_length) { } |
| 920 void AddLoopAlternative(GuardedAlternative alt); | 920 void AddLoopAlternative(GuardedAlternative alt); |
| 921 void AddContinueAlternative(GuardedAlternative alt); | 921 void AddContinueAlternative(GuardedAlternative alt); |
| 922 virtual void Emit(RegExpCompiler* compiler, Trace* trace); | 922 virtual void Emit(RegExpCompiler* compiler, Trace* trace); |
| 923 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, | 923 virtual intptr_t EatsAtLeast(intptr_t still_to_find, intptr_t budget, |
| 924 bool not_at_start); | 924 bool not_at_start); |
| 925 virtual void GetQuickCheckDetails(QuickCheckDetails* details, | 925 virtual void GetQuickCheckDetails(QuickCheckDetails* details, |
| 926 RegExpCompiler* compiler, | 926 RegExpCompiler* compiler, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 | 989 |
| 990 | 990 |
| 991 ContainedInLattice AddRange(ContainedInLattice a, | 991 ContainedInLattice AddRange(ContainedInLattice a, |
| 992 const intptr_t* ranges, | 992 const intptr_t* ranges, |
| 993 intptr_t ranges_size, | 993 intptr_t ranges_size, |
| 994 Interval new_range); | 994 Interval new_range); |
| 995 | 995 |
| 996 | 996 |
| 997 class BoyerMoorePositionInfo : public ZoneAllocated { | 997 class BoyerMoorePositionInfo : public ZoneAllocated { |
| 998 public: | 998 public: |
| 999 explicit BoyerMoorePositionInfo(Isolate* isolate) | 999 explicit BoyerMoorePositionInfo(Zone* zone) |
| 1000 : map_(new(isolate) ZoneGrowableArray<bool>(kMapSize)), | 1000 : map_(new(zone) ZoneGrowableArray<bool>(kMapSize)), |
| 1001 map_count_(0), | 1001 map_count_(0), |
| 1002 w_(kNotYet), | 1002 w_(kNotYet), |
| 1003 s_(kNotYet), | 1003 s_(kNotYet), |
| 1004 d_(kNotYet), | 1004 d_(kNotYet), |
| 1005 surrogate_(kNotYet) { | 1005 surrogate_(kNotYet) { |
| 1006 for (intptr_t i = 0; i < kMapSize; i++) { | 1006 for (intptr_t i = 0; i < kMapSize; i++) { |
| 1007 map_->Add(false); | 1007 map_->Add(false); |
| 1008 } | 1008 } |
| 1009 } | 1009 } |
| 1010 | 1010 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1027 ContainedInLattice w_; // The \w character class. | 1027 ContainedInLattice w_; // The \w character class. |
| 1028 ContainedInLattice s_; // The \s character class. | 1028 ContainedInLattice s_; // The \s character class. |
| 1029 ContainedInLattice d_; // The \d character class. | 1029 ContainedInLattice d_; // The \d character class. |
| 1030 ContainedInLattice surrogate_; // Surrogate UTF-16 code units. | 1030 ContainedInLattice surrogate_; // Surrogate UTF-16 code units. |
| 1031 }; | 1031 }; |
| 1032 | 1032 |
| 1033 | 1033 |
| 1034 class BoyerMooreLookahead : public ZoneAllocated{ | 1034 class BoyerMooreLookahead : public ZoneAllocated{ |
| 1035 public: | 1035 public: |
| 1036 BoyerMooreLookahead(intptr_t length, RegExpCompiler* compiler, | 1036 BoyerMooreLookahead(intptr_t length, RegExpCompiler* compiler, |
| 1037 Isolate* Isolate); | 1037 Zone* Zone); |
| 1038 | 1038 |
| 1039 intptr_t length() { return length_; } | 1039 intptr_t length() { return length_; } |
| 1040 intptr_t max_char() { return max_char_; } | 1040 intptr_t max_char() { return max_char_; } |
| 1041 RegExpCompiler* compiler() { return compiler_; } | 1041 RegExpCompiler* compiler() { return compiler_; } |
| 1042 | 1042 |
| 1043 intptr_t Count(intptr_t map_number) { | 1043 intptr_t Count(intptr_t map_number) { |
| 1044 return bitmaps_->At(map_number)->map_count(); | 1044 return bitmaps_->At(map_number)->map_count(); |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 BoyerMoorePositionInfo* at(intptr_t i) { return bitmaps_->At(i); } | 1047 BoyerMoorePositionInfo* at(intptr_t i) { return bitmaps_->At(i); } |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 } | 1237 } |
| 1238 void set_bound_checked_up_to(intptr_t to) { bound_checked_up_to_ = to; } | 1238 void set_bound_checked_up_to(intptr_t to) { bound_checked_up_to_ = to; } |
| 1239 void set_flush_budget(intptr_t to) { flush_budget_ = to; } | 1239 void set_flush_budget(intptr_t to) { flush_budget_ = to; } |
| 1240 void set_quick_check_performed(QuickCheckDetails* d) { | 1240 void set_quick_check_performed(QuickCheckDetails* d) { |
| 1241 quick_check_performed_ = *d; | 1241 quick_check_performed_ = *d; |
| 1242 } | 1242 } |
| 1243 void InvalidateCurrentCharacter(); | 1243 void InvalidateCurrentCharacter(); |
| 1244 void AdvanceCurrentPositionInTrace(intptr_t by, RegExpCompiler* compiler); | 1244 void AdvanceCurrentPositionInTrace(intptr_t by, RegExpCompiler* compiler); |
| 1245 | 1245 |
| 1246 private: | 1246 private: |
| 1247 intptr_t FindAffectedRegisters(OutSet* affected_registers, Isolate* isolate); | 1247 intptr_t FindAffectedRegisters(OutSet* affected_registers, Zone* zone); |
| 1248 void PerformDeferredActions(RegExpMacroAssembler* macro, | 1248 void PerformDeferredActions(RegExpMacroAssembler* macro, |
| 1249 intptr_t max_register, | 1249 intptr_t max_register, |
| 1250 const OutSet& affected_registers, | 1250 const OutSet& affected_registers, |
| 1251 OutSet* registers_to_pop, | 1251 OutSet* registers_to_pop, |
| 1252 OutSet* registers_to_clear, | 1252 OutSet* registers_to_clear, |
| 1253 Isolate* isolate); | 1253 Zone* zone); |
| 1254 void RestoreAffectedRegisters(RegExpMacroAssembler* macro, | 1254 void RestoreAffectedRegisters(RegExpMacroAssembler* macro, |
| 1255 intptr_t max_register, | 1255 intptr_t max_register, |
| 1256 const OutSet& registers_to_pop, | 1256 const OutSet& registers_to_pop, |
| 1257 const OutSet& registers_to_clear); | 1257 const OutSet& registers_to_clear); |
| 1258 intptr_t cp_offset_; | 1258 intptr_t cp_offset_; |
| 1259 DeferredAction* actions_; | 1259 DeferredAction* actions_; |
| 1260 BlockLabel* backtrack_; | 1260 BlockLabel* backtrack_; |
| 1261 RegExpNode* stop_node_; | 1261 RegExpNode* stop_node_; |
| 1262 BlockLabel* loop_label_; | 1262 BlockLabel* loop_label_; |
| 1263 intptr_t characters_preloaded_; | 1263 intptr_t characters_preloaded_; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 | 1395 |
| 1396 const char* error_message; | 1396 const char* error_message; |
| 1397 }; | 1397 }; |
| 1398 | 1398 |
| 1399 static CompilationResult Compile( | 1399 static CompilationResult Compile( |
| 1400 RegExpCompileData* input, | 1400 RegExpCompileData* input, |
| 1401 const ParsedFunction* parsed_function, | 1401 const ParsedFunction* parsed_function, |
| 1402 const ZoneGrowableArray<const ICData*>& ic_data_array); | 1402 const ZoneGrowableArray<const ICData*>& ic_data_array); |
| 1403 | 1403 |
| 1404 static RawJSRegExp* CreateJSRegExp( | 1404 static RawJSRegExp* CreateJSRegExp( |
| 1405 Isolate* isolate, | 1405 Zone* zone, |
| 1406 const String& pattern, | 1406 const String& pattern, |
| 1407 bool multi_line, | 1407 bool multi_line, |
| 1408 bool ignore_case); | 1408 bool ignore_case); |
| 1409 | 1409 |
| 1410 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); | 1410 static void DotPrint(const char* label, RegExpNode* node, bool ignore_case); |
| 1411 }; | 1411 }; |
| 1412 | 1412 |
| 1413 } // namespace dart | 1413 } // namespace dart |
| 1414 | 1414 |
| 1415 #endif // VM_REGEXP_H_ | 1415 #endif // VM_REGEXP_H_ |
| OLD | NEW |