| 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 static TextElement Atom(RegExpAtom* atom); | 425 static TextElement Atom(RegExpAtom* atom); |
| 426 static TextElement CharClass(RegExpCharacterClass* char_class); | 426 static TextElement CharClass(RegExpCharacterClass* char_class); |
| 427 Type type; | 427 Type type; |
| 428 union { | 428 union { |
| 429 RegExpAtom* u_atom; | 429 RegExpAtom* u_atom; |
| 430 RegExpCharacterClass* u_char_class; | 430 RegExpCharacterClass* u_char_class; |
| 431 } data; | 431 } data; |
| 432 }; | 432 }; |
| 433 | 433 |
| 434 | 434 |
| 435 class NodeInfo { | 435 struct NodeInfo { |
| 436 public: | |
| 437 NodeInfo() | 436 NodeInfo() |
| 438 : being_analyzed(false), | 437 : being_analyzed(false), |
| 439 been_analyzed(false), | 438 been_analyzed(false), |
| 440 propagate_word(false), | 439 determine_word(false), |
| 441 propagate_newline(false), | 440 determine_newline(false), |
| 442 propagate_start(false), | 441 determine_start(false), |
| 443 follows_word_interest(false), | 442 follows_word_interest(false), |
| 444 follows_newline_interest(false), | 443 follows_newline_interest(false), |
| 445 follows_start_interest(false) { } | 444 follows_start_interest(false) { } |
| 445 bool SameInterests(NodeInfo* that) { |
| 446 return (follows_word_interest == that->follows_word_interest) |
| 447 && (follows_newline_interest == that->follows_newline_interest) |
| 448 && (follows_start_interest == that->follows_start_interest); |
| 449 } |
| 450 void AdoptInterests(NodeInfo* that) { |
| 451 follows_word_interest = that->follows_word_interest; |
| 452 follows_newline_interest = that->follows_newline_interest; |
| 453 follows_start_interest = that->follows_start_interest; |
| 454 } |
| 455 bool prev_determine_word() { |
| 456 return determine_word || follows_word_interest; |
| 457 } |
| 458 bool prev_determine_newline() { |
| 459 return determine_newline || follows_newline_interest; |
| 460 } |
| 461 bool prev_determine_start() { |
| 462 return determine_start || follows_start_interest; |
| 463 } |
| 446 bool being_analyzed: 1; | 464 bool being_analyzed: 1; |
| 447 bool been_analyzed: 1; | 465 bool been_analyzed: 1; |
| 448 bool propagate_word: 1; | 466 bool determine_word: 1; |
| 449 bool propagate_newline: 1; | 467 bool determine_newline: 1; |
| 450 bool propagate_start: 1; | 468 bool determine_start: 1; |
| 451 bool follows_word_interest: 1; | 469 bool follows_word_interest: 1; |
| 452 bool follows_newline_interest: 1; | 470 bool follows_newline_interest: 1; |
| 453 bool follows_start_interest: 1; | 471 bool follows_start_interest: 1; |
| 454 }; | 472 }; |
| 455 | 473 |
| 456 | 474 |
| 457 STATIC_CHECK(sizeof(NodeInfo) <= sizeof(int)); // NOLINT | 475 STATIC_CHECK(sizeof(NodeInfo) <= sizeof(int)); // NOLINT |
| 458 | 476 |
| 459 | 477 |
| 478 class SiblingList { |
| 479 public: |
| 480 SiblingList() : list_(NULL) { } |
| 481 int length() { |
| 482 return list_ == NULL ? 0 : list_->length(); |
| 483 } |
| 484 void Ensure(RegExpNode* parent) { |
| 485 if (list_ == NULL) { |
| 486 list_ = new ZoneList<RegExpNode*>(2); |
| 487 list_->Add(parent); |
| 488 } |
| 489 } |
| 490 void Add(RegExpNode* node) { list_->Add(node); } |
| 491 RegExpNode* Get(int index) { return list_->at(index); } |
| 492 private: |
| 493 ZoneList<RegExpNode*>* list_; |
| 494 }; |
| 495 |
| 496 |
| 460 class RegExpNode: public ZoneObject { | 497 class RegExpNode: public ZoneObject { |
| 461 public: | 498 public: |
| 462 virtual ~RegExpNode() { } | 499 virtual ~RegExpNode() { } |
| 463 virtual void Accept(NodeVisitor* visitor) = 0; | 500 virtual void Accept(NodeVisitor* visitor) = 0; |
| 464 // Generates a goto to this node or actually generates the code at this point. | 501 // Generates a goto to this node or actually generates the code at this point. |
| 465 // Until the implementation is complete we will return true for success and | 502 // Until the implementation is complete we will return true for success and |
| 466 // false for failure. | 503 // false for failure. |
| 467 bool GoTo(RegExpCompiler* compiler); | 504 bool GoTo(RegExpCompiler* compiler); |
| 468 Label* label(); | 505 Label* label(); |
| 469 | 506 |
| 470 // Until the implementation is complete we will return true for success and | 507 // Until the implementation is complete we will return true for success and |
| 471 // false for failure. | 508 // false for failure. |
| 472 virtual bool Emit(RegExpCompiler* compiler) = 0; | 509 virtual bool Emit(RegExpCompiler* compiler) = 0; |
| 510 virtual RegExpNode* PropagateInterest(NodeInfo* info) = 0; |
| 473 NodeInfo* info() { return &info_; } | 511 NodeInfo* info() { return &info_; } |
| 474 virtual bool IsBacktrack() { return false; } | 512 virtual bool IsBacktrack() { return false; } |
| 513 RegExpNode* GetSibling(NodeInfo* info); |
| 514 void EnsureSiblings() { siblings_.Ensure(this); } |
| 515 void AddSibling(RegExpNode* node) { siblings_.Add(node); } |
| 475 private: | 516 private: |
| 476 Label label_; | 517 Label label_; |
| 477 NodeInfo info_; | 518 NodeInfo info_; |
| 519 SiblingList siblings_; |
| 478 }; | 520 }; |
| 479 | 521 |
| 480 | 522 |
| 481 class SeqRegExpNode: public RegExpNode { | 523 class SeqRegExpNode: public RegExpNode { |
| 482 public: | 524 public: |
| 483 explicit SeqRegExpNode(RegExpNode* on_success) | 525 explicit SeqRegExpNode(RegExpNode* on_success) |
| 484 : on_success_(on_success) { } | 526 : on_success_(on_success) { } |
| 485 RegExpNode* on_success() { return on_success_; } | 527 RegExpNode* on_success() { return on_success_; } |
| 528 void set_on_success(RegExpNode* node) { on_success_ = node; } |
| 486 virtual bool Emit(RegExpCompiler* compiler) { return false; } | 529 virtual bool Emit(RegExpCompiler* compiler) { return false; } |
| 487 private: | 530 private: |
| 488 RegExpNode* on_success_; | 531 RegExpNode* on_success_; |
| 489 }; | 532 }; |
| 490 | 533 |
| 491 | 534 |
| 492 class ActionNode: public SeqRegExpNode { | 535 class ActionNode: public SeqRegExpNode { |
| 493 public: | 536 public: |
| 494 enum Type { | 537 enum Type { |
| 495 STORE_REGISTER, | 538 STORE_REGISTER, |
| 496 INCREMENT_REGISTER, | 539 INCREMENT_REGISTER, |
| 497 STORE_POSITION, | 540 STORE_POSITION, |
| 498 RESTORE_POSITION, | 541 RESTORE_POSITION, |
| 499 BEGIN_SUBMATCH, | 542 BEGIN_SUBMATCH, |
| 500 ESCAPE_SUBMATCH, | 543 ESCAPE_SUBMATCH, |
| 501 END_SUBMATCH | 544 END_SUBMATCH |
| 502 }; | 545 }; |
| 503 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success); | 546 static ActionNode* StoreRegister(int reg, int val, RegExpNode* on_success); |
| 504 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); | 547 static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); |
| 505 static ActionNode* StorePosition(int reg, RegExpNode* on_success); | 548 static ActionNode* StorePosition(int reg, RegExpNode* on_success); |
| 506 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); | 549 static ActionNode* RestorePosition(int reg, RegExpNode* on_success); |
| 507 static ActionNode* BeginSubmatch(RegExpNode* on_success); | 550 static ActionNode* BeginSubmatch(RegExpNode* on_success); |
| 508 static ActionNode* EscapeSubmatch(RegExpNode* on_success); | 551 static ActionNode* EscapeSubmatch(RegExpNode* on_success); |
| 509 static ActionNode* EndSubmatch(RegExpNode* on_success); | 552 static ActionNode* EndSubmatch(RegExpNode* on_success); |
| 510 virtual void Accept(NodeVisitor* visitor); | 553 virtual void Accept(NodeVisitor* visitor); |
| 511 virtual bool Emit(RegExpCompiler* compiler); | 554 virtual bool Emit(RegExpCompiler* compiler); |
| 555 virtual RegExpNode* PropagateInterest(NodeInfo* info); |
| 512 private: | 556 private: |
| 513 union { | 557 union { |
| 514 struct { | 558 struct { |
| 515 int reg; | 559 int reg; |
| 516 int value; | 560 int value; |
| 517 } u_store_register; | 561 } u_store_register; |
| 518 struct { | 562 struct { |
| 519 int reg; | 563 int reg; |
| 520 } u_increment_register; | 564 } u_increment_register; |
| 521 struct { | 565 struct { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 533 class TextNode: public SeqRegExpNode { | 577 class TextNode: public SeqRegExpNode { |
| 534 public: | 578 public: |
| 535 TextNode(ZoneList<TextElement>* elms, | 579 TextNode(ZoneList<TextElement>* elms, |
| 536 RegExpNode* on_success, | 580 RegExpNode* on_success, |
| 537 RegExpNode* on_failure) | 581 RegExpNode* on_failure) |
| 538 : SeqRegExpNode(on_success), | 582 : SeqRegExpNode(on_success), |
| 539 on_failure_(on_failure), | 583 on_failure_(on_failure), |
| 540 elms_(elms) { } | 584 elms_(elms) { } |
| 541 virtual void Accept(NodeVisitor* visitor); | 585 virtual void Accept(NodeVisitor* visitor); |
| 542 virtual bool Emit(RegExpCompiler* compiler) { return false; } | 586 virtual bool Emit(RegExpCompiler* compiler) { return false; } |
| 587 virtual RegExpNode* PropagateInterest(NodeInfo* info); |
| 543 RegExpNode* on_failure() { return on_failure_; } | 588 RegExpNode* on_failure() { return on_failure_; } |
| 544 ZoneList<TextElement>* elements() { return elms_; } | 589 ZoneList<TextElement>* elements() { return elms_; } |
| 545 private: | 590 private: |
| 546 RegExpNode* on_failure_; | 591 RegExpNode* on_failure_; |
| 547 ZoneList<TextElement>* elms_; | 592 ZoneList<TextElement>* elms_; |
| 548 }; | 593 }; |
| 549 | 594 |
| 550 | 595 |
| 551 class BackreferenceNode: public SeqRegExpNode { | 596 class BackreferenceNode: public SeqRegExpNode { |
| 552 public: | 597 public: |
| 553 BackreferenceNode(int start_reg, | 598 BackreferenceNode(int start_reg, |
| 554 int end_reg, | 599 int end_reg, |
| 555 RegExpNode* on_success, | 600 RegExpNode* on_success, |
| 556 RegExpNode* on_failure) | 601 RegExpNode* on_failure) |
| 557 : SeqRegExpNode(on_success), | 602 : SeqRegExpNode(on_success), |
| 558 on_failure_(on_failure), | 603 on_failure_(on_failure), |
| 559 start_reg_(start_reg), | 604 start_reg_(start_reg), |
| 560 end_reg_(end_reg) { } | 605 end_reg_(end_reg) { } |
| 561 virtual void Accept(NodeVisitor* visitor); | 606 virtual void Accept(NodeVisitor* visitor); |
| 562 RegExpNode* on_failure() { return on_failure_; } | 607 RegExpNode* on_failure() { return on_failure_; } |
| 563 int start_register() { return start_reg_; } | 608 int start_register() { return start_reg_; } |
| 564 int end_register() { return end_reg_; } | 609 int end_register() { return end_reg_; } |
| 565 virtual bool Emit(RegExpCompiler* compiler) { return false; } | 610 virtual bool Emit(RegExpCompiler* compiler) { return false; } |
| 611 virtual RegExpNode* PropagateInterest(NodeInfo* info); |
| 566 private: | 612 private: |
| 567 RegExpNode* on_failure_; | 613 RegExpNode* on_failure_; |
| 568 int start_reg_; | 614 int start_reg_; |
| 569 int end_reg_; | 615 int end_reg_; |
| 570 }; | 616 }; |
| 571 | 617 |
| 572 | 618 |
| 573 class EndNode: public RegExpNode { | 619 class EndNode: public RegExpNode { |
| 574 public: | 620 public: |
| 575 enum Action { ACCEPT, BACKTRACK }; | 621 enum Action { ACCEPT, BACKTRACK }; |
| 576 explicit EndNode(Action action) : action_(action) { } | 622 explicit EndNode(Action action) : action_(action) { } |
| 577 virtual void Accept(NodeVisitor* visitor); | 623 virtual void Accept(NodeVisitor* visitor); |
| 578 virtual bool Emit(RegExpCompiler* compiler); | 624 virtual bool Emit(RegExpCompiler* compiler); |
| 625 virtual RegExpNode* PropagateInterest(NodeInfo* info); |
| 579 virtual bool IsBacktrack() { return action_ == BACKTRACK; } | 626 virtual bool IsBacktrack() { return action_ == BACKTRACK; } |
| 580 private: | 627 private: |
| 581 Action action_; | 628 Action action_; |
| 582 }; | 629 }; |
| 583 | 630 |
| 584 | 631 |
| 585 class Guard: public ZoneObject { | 632 class Guard: public ZoneObject { |
| 586 public: | 633 public: |
| 587 enum Relation { LT, GEQ }; | 634 enum Relation { LT, GEQ }; |
| 588 Guard(int reg, Relation op, int value) | 635 Guard(int reg, Relation op, int value) |
| 589 : reg_(reg), | 636 : reg_(reg), |
| 590 op_(op), | 637 op_(op), |
| 591 value_(value) { } | 638 value_(value) { } |
| 592 int reg() { return reg_; } | 639 int reg() { return reg_; } |
| 593 Relation op() { return op_; } | 640 Relation op() { return op_; } |
| 594 int value() { return value_; } | 641 int value() { return value_; } |
| 595 private: | 642 private: |
| 596 int reg_; | 643 int reg_; |
| 597 Relation op_; | 644 Relation op_; |
| 598 int value_; | 645 int value_; |
| 599 }; | 646 }; |
| 600 | 647 |
| 601 | 648 |
| 602 class GuardedAlternative { | 649 class GuardedAlternative { |
| 603 public: | 650 public: |
| 604 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } | 651 explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { } |
| 605 void AddGuard(Guard* guard); | 652 void AddGuard(Guard* guard); |
| 606 RegExpNode* node() { return node_; } | 653 RegExpNode* node() { return node_; } |
| 654 void set_node(RegExpNode* node) { node_ = node; } |
| 607 ZoneList<Guard*>* guards() { return guards_; } | 655 ZoneList<Guard*>* guards() { return guards_; } |
| 608 private: | 656 private: |
| 609 RegExpNode* node_; | 657 RegExpNode* node_; |
| 610 ZoneList<Guard*>* guards_; | 658 ZoneList<Guard*>* guards_; |
| 611 }; | 659 }; |
| 612 | 660 |
| 613 | 661 |
| 614 class ChoiceNode: public RegExpNode { | 662 class ChoiceNode: public RegExpNode { |
| 615 public: | 663 public: |
| 616 explicit ChoiceNode(int expected_size, RegExpNode* on_failure) | 664 explicit ChoiceNode(int expected_size, RegExpNode* on_failure) |
| 617 : on_failure_(on_failure), | 665 : on_failure_(on_failure), |
| 618 alternatives_(new ZoneList<GuardedAlternative>(expected_size)), | 666 alternatives_(new ZoneList<GuardedAlternative>(expected_size)), |
| 619 table_calculated_(false), | 667 table_calculated_(false), |
| 620 being_calculated_(false) { } | 668 being_calculated_(false) { } |
| 621 virtual void Accept(NodeVisitor* visitor); | 669 virtual void Accept(NodeVisitor* visitor); |
| 622 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } | 670 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); } |
| 623 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } | 671 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; } |
| 624 DispatchTable* table() { return &table_; } | 672 DispatchTable* table() { return &table_; } |
| 625 RegExpNode* on_failure() { return on_failure_; } | 673 RegExpNode* on_failure() { return on_failure_; } |
| 626 virtual bool Emit(RegExpCompiler* compiler); | 674 virtual bool Emit(RegExpCompiler* compiler); |
| 675 virtual RegExpNode* PropagateInterest(NodeInfo* info); |
| 627 bool table_calculated() { return table_calculated_; } | 676 bool table_calculated() { return table_calculated_; } |
| 628 void set_table_calculated(bool b) { table_calculated_ = b; } | 677 void set_table_calculated(bool b) { table_calculated_ = b; } |
| 629 bool being_calculated() { return being_calculated_; } | 678 bool being_calculated() { return being_calculated_; } |
| 630 void set_being_calculated(bool b) { being_calculated_ = b; } | 679 void set_being_calculated(bool b) { being_calculated_ = b; } |
| 631 private: | 680 private: |
| 632 void GenerateGuard(RegExpCompiler* compiler, | 681 void GenerateGuard(RegExpCompiler* compiler, |
| 633 Guard *guard, | 682 Guard *guard, |
| 634 Label* on_failure); | 683 Label* on_failure); |
| 635 RegExpNode* on_failure_; | 684 RegExpNode* on_failure_; |
| 636 ZoneList<GuardedAlternative>* alternatives_; | 685 ZoneList<GuardedAlternative>* alternatives_; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 static Handle<FixedArray> Compile(RegExpParseResult* input, | 753 static Handle<FixedArray> Compile(RegExpParseResult* input, |
| 705 RegExpNode** node_return, | 754 RegExpNode** node_return, |
| 706 bool ignore_case); | 755 bool ignore_case); |
| 707 static void DotPrint(const char* label, RegExpNode* node); | 756 static void DotPrint(const char* label, RegExpNode* node); |
| 708 }; | 757 }; |
| 709 | 758 |
| 710 | 759 |
| 711 } } // namespace v8::internal | 760 } } // namespace v8::internal |
| 712 | 761 |
| 713 #endif // V8_JSREGEXP_H_ | 762 #endif // V8_JSREGEXP_H_ |
| OLD | NEW |