Index: src/jsregexp.h |
diff --git a/src/jsregexp.h b/src/jsregexp.h |
index de99dc71ad506eefdc1937151a22ee988065799b..e1e65f6b4e42e77c774bbf986499b0019c2e76f6 100644 |
--- a/src/jsregexp.h |
+++ b/src/jsregexp.h |
@@ -664,6 +664,30 @@ class RegExpNode: public ZoneObject { |
}; |
+// A simple closed interval. |
+class Interval { |
+ public: |
+ Interval() : from_(kNone), to_(kNone) { } |
+ Interval(short from, short to) : from_(from), to_(to) { } |
+ Interval Union(Interval that) { |
+ if (that.from_ == kNone) return *this; |
+ else if (from_ == kNone) return that; |
+ else return Interval(Min(from_, that.from_), Max(to_, that.to_)); |
+ } |
+ bool Contains(int value) { |
+ return (from_ <= value) && (value <= to_); |
+ } |
+ bool is_empty() { return from_ == kNone; } |
+ short from() { return from_; } |
+ short to() { return to_; } |
+ static Interval Empty() { return Interval(); } |
+ static const int kNone = -1; |
+ private: |
+ short from_; |
+ short to_; |
+}; |
+ |
+ |
class SeqRegExpNode: public RegExpNode { |
public: |
explicit SeqRegExpNode(RegExpNode* on_success) |
@@ -683,24 +707,24 @@ class ActionNode: public SeqRegExpNode { |
STORE_POSITION, |
BEGIN_SUBMATCH, |
POSITIVE_SUBMATCH_SUCCESS, |
- EMPTY_MATCH_CHECK |
+ EMPTY_MATCH_CHECK, |
+ CLEAR_CAPTURES |
}; |
static ActionNode* SetRegister(int reg, int val, RegExpNode* on_success); |
static ActionNode* IncrementRegister(int reg, RegExpNode* on_success); |
static ActionNode* StorePosition(int reg, RegExpNode* on_success); |
- static ActionNode* BeginSubmatch( |
- int stack_pointer_reg, |
- int position_reg, |
- RegExpNode* on_success); |
- static ActionNode* PositiveSubmatchSuccess( |
- int stack_pointer_reg, |
- int restore_reg, |
- RegExpNode* on_success); |
- static ActionNode* EmptyMatchCheck( |
- int start_register, |
- int repetition_register, |
- int repetition_limit, |
- RegExpNode* on_success); |
+ static ActionNode* ClearCaptures(Interval range, |
+ RegExpNode* on_success); |
Erik Corry
2009/01/14 09:24:31
This fits on one line.
Christian Plesner Hansen
2009/01/14 11:31:35
Fixed
|
+ static ActionNode* BeginSubmatch(int stack_pointer_reg, |
+ int position_reg, |
+ RegExpNode* on_success); |
+ static ActionNode* PositiveSubmatchSuccess(int stack_pointer_reg, |
+ int restore_reg, |
+ RegExpNode* on_success); |
+ static ActionNode* EmptyMatchCheck(int start_register, |
+ int repetition_register, |
+ int repetition_limit, |
+ RegExpNode* on_success); |
virtual void Accept(NodeVisitor* visitor); |
virtual bool Emit(RegExpCompiler* compiler, GenerationVariant* variant); |
virtual int EatsAtLeast(int recursion_depth); |
@@ -736,6 +760,10 @@ class ActionNode: public SeqRegExpNode { |
int repetition_register; |
int repetition_limit; |
} u_empty_match_check; |
+ struct { |
+ int range_from; |
Erik Corry
2009/01/14 09:24:31
Can't we just have an Interval here?
Christian Plesner Hansen
2009/01/14 11:31:35
I thought so too but it turns out that you can't h
|
+ int range_to; |
+ } u_clear_captures; |
} data_; |
ActionNode(Type type, RegExpNode* on_success) |
: SeqRegExpNode(on_success), |
@@ -980,6 +1008,7 @@ class GenerationVariant { |
DeferredAction(ActionNode::Type type, int reg) |
: type_(type), reg_(reg), next_(NULL) { } |
DeferredAction* next() { return next_; } |
+ bool Mentions(int reg); |
Erik Corry
2009/01/14 09:24:31
It's messy that this is not a private method, sinc
Christian Plesner Hansen
2009/01/14 11:31:35
I'm not sure -- all other operations than the one
|
int reg() { return reg_; } |
ActionNode::Type type() { return type_; } |
private: |
@@ -1010,6 +1039,16 @@ class GenerationVariant { |
int value_; |
}; |
+ class DeferredClearCaptures : public DeferredAction { |
+ public: |
+ DeferredClearCaptures(Interval range) |
+ : DeferredAction(ActionNode::CLEAR_CAPTURES, -1), |
+ range_(range) { } |
+ Interval range() { return range_; } |
+ private: |
+ Interval range_; |
+ }; |
+ |
class DeferredIncrementRegister: public DeferredAction { |
public: |
explicit DeferredIncrementRegister(int reg) |