summaryrefslogtreecommitdiff
path: root/deps/v8/src/regexp/jsregexp.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/regexp/jsregexp.h')
-rw-r--r--deps/v8/src/regexp/jsregexp.h153
1 files changed, 90 insertions, 63 deletions
diff --git a/deps/v8/src/regexp/jsregexp.h b/deps/v8/src/regexp/jsregexp.h
index 23dc8fac4b..021c59d3e4 100644
--- a/deps/v8/src/regexp/jsregexp.h
+++ b/deps/v8/src/regexp/jsregexp.h
@@ -7,6 +7,7 @@
#include "src/allocation.h"
#include "src/assembler.h"
+#include "src/objects/js-regexp.h"
#include "src/regexp/regexp-ast.h"
#include "src/regexp/regexp-macro-assembler.h"
@@ -20,6 +21,36 @@ class RegExpNode;
class RegExpTree;
class BoyerMooreLookahead;
+inline bool IgnoreCase(JSRegExp::Flags flags) {
+ return (flags & JSRegExp::kIgnoreCase) != 0;
+}
+
+inline bool IsUnicode(JSRegExp::Flags flags) {
+ return (flags & JSRegExp::kUnicode) != 0;
+}
+
+inline bool IsSticky(JSRegExp::Flags flags) {
+ return (flags & JSRegExp::kSticky) != 0;
+}
+
+inline bool IsGlobal(JSRegExp::Flags flags) {
+ return (flags & JSRegExp::kGlobal) != 0;
+}
+
+inline bool DotAll(JSRegExp::Flags flags) {
+ return (flags & JSRegExp::kDotAll) != 0;
+}
+
+inline bool Multiline(JSRegExp::Flags flags) {
+ return (flags & JSRegExp::kMultiline) != 0;
+}
+
+inline bool NeedsUnicodeCaseEquivalents(JSRegExp::Flags flags) {
+ // Both unicode and ignore_case flags are set. We need to use ICU to find
+ // the closure over case equivalents.
+ return IsUnicode(flags) && IgnoreCase(flags);
+}
+
class RegExpImpl {
public:
// Whether V8 is compiled with native regexp support or not.
@@ -105,7 +136,8 @@ class RegExpImpl {
Handle<JSRegExp> regexp, Handle<String> subject, int index,
Handle<RegExpMatchInfo> last_match_info);
- // Set last match info. If match is NULL, then setting captures is omitted.
+ // Set last match info. If match is nullptr, then setting captures is
+ // omitted.
static Handle<RegExpMatchInfo> SetLastMatchInfo(
Handle<RegExpMatchInfo> last_match_info, Handle<String> subject,
int capture_count, int32_t* match);
@@ -119,9 +151,9 @@ class RegExpImpl {
INLINE(~GlobalCache());
// Fetch the next entry in the cache for global regexp match results.
- // This does not set the last match info. Upon failure, NULL is returned.
- // The cause can be checked with Result(). The previous
- // result is still in available in memory when a failure happens.
+ // This does not set the last match info. Upon failure, nullptr is
+ // returned. The cause can be checked with Result(). The previous result is
+ // still in available in memory when a failure happens.
INLINE(int32_t* FetchNext());
INLINE(int32_t* LastSuccessfulMatch());
@@ -184,7 +216,7 @@ enum ElementInSetsRelation {
// integers (< 32). May do zone-allocation.
class OutSet: public ZoneObject {
public:
- OutSet() : first_(0), remaining_(NULL), successors_(NULL) { }
+ OutSet() : first_(0), remaining_(nullptr), successors_(nullptr) {}
OutSet* Extend(unsigned value, Zone* zone);
bool Get(unsigned value) const;
static const unsigned kFirstLimit = 32;
@@ -201,7 +233,7 @@ class OutSet: public ZoneObject {
ZoneList<OutSet*>* successors(Zone* zone) { return successors_; }
OutSet(uint32_t first, ZoneList<unsigned>* remaining)
- : first_(first), remaining_(remaining), successors_(NULL) { }
+ : first_(first), remaining_(remaining), successors_(nullptr) {}
uint32_t first_;
ZoneList<unsigned>* remaining_;
ZoneList<OutSet*>* successors_;
@@ -217,7 +249,7 @@ class DispatchTable : public ZoneObject {
class Entry {
public:
- Entry() : from_(0), to_(0), out_set_(NULL) { }
+ Entry() : from_(0), to_(0), out_set_(nullptr) {}
Entry(uc32 from, uc32 to, OutSet* out_set)
: from_(from), to_(to), out_set_(out_set) {
DCHECK(from <= to);
@@ -433,8 +465,11 @@ extern int kUninitializedRegExpNodePlaceHolder;
class RegExpNode: public ZoneObject {
public:
explicit RegExpNode(Zone* zone)
- : replacement_(NULL), on_work_list_(false), trace_count_(0), zone_(zone) {
- bm_info_[0] = bm_info_[1] = NULL;
+ : replacement_(nullptr),
+ on_work_list_(false),
+ trace_count_(0),
+ zone_(zone) {
+ bm_info_[0] = bm_info_[1] = nullptr;
}
virtual ~RegExpNode();
virtual void Accept(NodeVisitor* visitor) = 0;
@@ -472,7 +507,7 @@ class RegExpNode: public ZoneObject {
// character and that has no guards on it.
virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
RegExpCompiler* compiler) {
- return NULL;
+ return nullptr;
}
// Collects information on the possible code units (mod 128) that can match if
@@ -489,10 +524,8 @@ class RegExpNode: public ZoneObject {
// If we know that the input is one-byte then there are some nodes that can
// never match. This method returns a node that can be substituted for
- // itself, or NULL if the node can never match.
- virtual RegExpNode* FilterOneByte(int depth, bool ignore_case) {
- return this;
- }
+ // itself, or nullptr if the node can never match.
+ virtual RegExpNode* FilterOneByte(int depth) { return this; }
// Helper for FilterOneByte.
RegExpNode* replacement() {
DCHECK(info()->replacement_calculated);
@@ -564,7 +597,7 @@ class SeqRegExpNode: public RegExpNode {
: RegExpNode(on_success->zone()), on_success_(on_success) { }
RegExpNode* on_success() { return on_success_; }
void set_on_success(RegExpNode* node) { on_success_ = node; }
- virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+ virtual RegExpNode* FilterOneByte(int depth);
virtual void FillInBMInfo(Isolate* isolate, int offset, int budget,
BoyerMooreLookahead* bm, bool not_at_start) {
on_success_->FillInBMInfo(isolate, offset, budget - 1, bm, not_at_start);
@@ -572,7 +605,7 @@ class SeqRegExpNode: public RegExpNode {
}
protected:
- RegExpNode* FilterSuccessor(int depth, bool ignore_case);
+ RegExpNode* FilterSuccessor(int depth);
private:
RegExpNode* on_success_;
@@ -677,13 +710,15 @@ class TextNode: public SeqRegExpNode {
static TextNode* CreateForCharacterRanges(Zone* zone,
ZoneList<CharacterRange>* ranges,
bool read_backward,
- RegExpNode* on_success);
+ RegExpNode* on_success,
+ JSRegExp::Flags flags);
// Create TextNode for a surrogate pair with a range given for the
// lead and the trail surrogate each.
static TextNode* CreateForSurrogatePair(Zone* zone, CharacterRange lead,
CharacterRange trail,
bool read_backward,
- RegExpNode* on_success);
+ RegExpNode* on_success,
+ JSRegExp::Flags flags);
virtual void Accept(NodeVisitor* visitor);
virtual void Emit(RegExpCompiler* compiler, Trace* trace);
virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start);
@@ -700,7 +735,7 @@ class TextNode: public SeqRegExpNode {
virtual void FillInBMInfo(Isolate* isolate, int offset, int budget,
BoyerMooreLookahead* bm, bool not_at_start);
void CalculateOffsets();
- virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+ virtual RegExpNode* FilterOneByte(int depth);
private:
enum TextEmitPassType {
@@ -710,7 +745,7 @@ class TextNode: public SeqRegExpNode {
CASE_CHARACTER_MATCH, // Case-independent single character check.
CHARACTER_CLASS_MATCH // Character class.
};
- static bool SkipPass(int pass, bool ignore_case);
+ static bool SkipPass(TextEmitPassType pass, bool ignore_case);
static const int kFirstRealPass = SIMPLE_CHARACTER_MATCH;
static const int kLastPass = CHARACTER_CLASS_MATCH;
void TextEmitPass(RegExpCompiler* compiler,
@@ -774,11 +809,12 @@ class AssertionNode: public SeqRegExpNode {
class BackReferenceNode: public SeqRegExpNode {
public:
- BackReferenceNode(int start_reg, int end_reg, bool read_backward,
- RegExpNode* on_success)
+ BackReferenceNode(int start_reg, int end_reg, JSRegExp::Flags flags,
+ bool read_backward, RegExpNode* on_success)
: SeqRegExpNode(on_success),
start_reg_(start_reg),
end_reg_(end_reg),
+ flags_(flags),
read_backward_(read_backward) {}
virtual void Accept(NodeVisitor* visitor);
int start_register() { return start_reg_; }
@@ -800,6 +836,7 @@ class BackReferenceNode: public SeqRegExpNode {
private:
int start_reg_;
int end_reg_;
+ JSRegExp::Flags flags_;
bool read_backward_;
};
@@ -873,7 +910,8 @@ class Guard: public ZoneObject {
class GuardedAlternative {
public:
- explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { }
+ explicit GuardedAlternative(RegExpNode* node)
+ : node_(node), guards_(nullptr) {}
void AddGuard(Guard* guard, Zone* zone);
RegExpNode* node() { return node_; }
void set_node(RegExpNode* node) { node_ = node; }
@@ -892,11 +930,11 @@ class ChoiceNode: public RegExpNode {
public:
explicit ChoiceNode(int expected_size, Zone* zone)
: RegExpNode(zone),
- alternatives_(new(zone)
- ZoneList<GuardedAlternative>(expected_size, zone)),
- table_(NULL),
+ alternatives_(new (zone)
+ ZoneList<GuardedAlternative>(expected_size, zone)),
+ table_(nullptr),
not_at_start_(false),
- being_calculated_(false) { }
+ being_calculated_(false) {}
virtual void Accept(NodeVisitor* visitor);
void AddAlternative(GuardedAlternative node) {
alternatives()->Add(node, zone());
@@ -923,7 +961,7 @@ class ChoiceNode: public RegExpNode {
virtual bool try_to_emit_quick_check_for_alternative(bool is_first) {
return true;
}
- virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+ virtual RegExpNode* FilterOneByte(int depth);
virtual bool read_backward() { return false; }
protected:
@@ -995,7 +1033,7 @@ class NegativeLookaroundChoiceNode : public ChoiceNode {
virtual bool try_to_emit_quick_check_for_alternative(bool is_first) {
return !is_first;
}
- virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+ virtual RegExpNode* FilterOneByte(int depth);
};
@@ -1003,8 +1041,8 @@ class LoopChoiceNode: public ChoiceNode {
public:
LoopChoiceNode(bool body_can_be_zero_length, bool read_backward, Zone* zone)
: ChoiceNode(2, zone),
- loop_node_(NULL),
- continue_node_(NULL),
+ loop_node_(nullptr),
+ continue_node_(nullptr),
body_can_be_zero_length_(body_can_be_zero_length),
read_backward_(read_backward) {}
void AddLoopAlternative(GuardedAlternative alt);
@@ -1022,7 +1060,7 @@ class LoopChoiceNode: public ChoiceNode {
bool body_can_be_zero_length() { return body_can_be_zero_length_; }
virtual bool read_backward() { return read_backward_; }
virtual void Accept(NodeVisitor* visitor);
- virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+ virtual RegExpNode* FilterOneByte(int depth);
private:
// AddAlternative is made private for loop nodes because alternatives
@@ -1201,7 +1239,7 @@ class Trace {
class DeferredAction {
public:
DeferredAction(ActionNode::ActionType action_type, int reg)
- : action_type_(action_type), reg_(reg), next_(NULL) { }
+ : action_type_(action_type), reg_(reg), next_(nullptr) {}
DeferredAction* next() { return next_; }
bool Mentions(int reg);
int reg() { return reg_; }
@@ -1255,14 +1293,14 @@ class Trace {
Trace()
: cp_offset_(0),
- actions_(NULL),
- backtrack_(NULL),
- stop_node_(NULL),
- loop_label_(NULL),
+ actions_(nullptr),
+ backtrack_(nullptr),
+ stop_node_(nullptr),
+ loop_label_(nullptr),
characters_preloaded_(0),
bound_checked_up_to_(0),
flush_budget_(100),
- at_start_(UNKNOWN) { }
+ at_start_(UNKNOWN) {}
// End the trace. This involves flushing the deferred actions in the trace
// and pushing a backtrack location onto the backtrack stack. Once this is
@@ -1282,13 +1320,9 @@ class Trace {
// a trivial trace is recorded in a label in the node so that gotos can be
// generated to that code.
bool is_trivial() {
- return backtrack_ == NULL &&
- actions_ == NULL &&
- cp_offset_ == 0 &&
- characters_preloaded_ == 0 &&
- bound_checked_up_to_ == 0 &&
- quick_check_performed_.characters() == 0 &&
- at_start_ == UNKNOWN;
+ return backtrack_ == nullptr && actions_ == nullptr && cp_offset_ == 0 &&
+ characters_preloaded_ == 0 && bound_checked_up_to_ == 0 &&
+ quick_check_performed_.characters() == 0 && at_start_ == UNKNOWN;
}
TriBool at_start() { return at_start_; }
void set_at_start(TriBool at_start) { at_start_ = at_start; }
@@ -1307,7 +1341,7 @@ class Trace {
// These set methods and AdvanceCurrentPositionInTrace should be used only on
// new traces - the intention is that traces are immutable after creation.
void add_action(DeferredAction* new_action) {
- DCHECK(new_action->next_ == NULL);
+ DCHECK(new_action->next_ == nullptr);
new_action->next_ = actions_;
actions_ = new_action;
}
@@ -1433,11 +1467,8 @@ FOR_EACH_NODE_TYPE(DECLARE_VISIT)
// +-------+ +------------+
class Analysis: public NodeVisitor {
public:
- Analysis(Isolate* isolate, JSRegExp::Flags flags, bool is_one_byte)
- : isolate_(isolate),
- flags_(flags),
- is_one_byte_(is_one_byte),
- error_message_(NULL) {}
+ Analysis(Isolate* isolate, bool is_one_byte)
+ : isolate_(isolate), is_one_byte_(is_one_byte), error_message_(nullptr) {}
void EnsureAnalyzed(RegExpNode* node);
#define DECLARE_VISIT(Type) \
@@ -1446,9 +1477,9 @@ FOR_EACH_NODE_TYPE(DECLARE_VISIT)
#undef DECLARE_VISIT
virtual void VisitLoopChoice(LoopChoiceNode* that);
- bool has_failed() { return error_message_ != NULL; }
+ bool has_failed() { return error_message_ != nullptr; }
const char* error_message() {
- DCHECK(error_message_ != NULL);
+ DCHECK(error_message_ != nullptr);
return error_message_;
}
void fail(const char* error_message) {
@@ -1457,12 +1488,8 @@ FOR_EACH_NODE_TYPE(DECLARE_VISIT)
Isolate* isolate() const { return isolate_; }
- bool ignore_case() const { return (flags_ & JSRegExp::kIgnoreCase) != 0; }
- bool unicode() const { return (flags_ & JSRegExp::kUnicode) != 0; }
-
private:
Isolate* isolate_;
- JSRegExp::Flags flags_;
bool is_one_byte_;
const char* error_message_;
@@ -1472,11 +1499,11 @@ FOR_EACH_NODE_TYPE(DECLARE_VISIT)
struct RegExpCompileData {
RegExpCompileData()
- : tree(NULL),
- node(NULL),
- simple(true),
- contains_anchor(false),
- capture_count(0) { }
+ : tree(nullptr),
+ node(nullptr),
+ simple(true),
+ contains_anchor(false),
+ capture_count(0) {}
RegExpTree* tree;
RegExpNode* node;
bool simple;
@@ -1495,7 +1522,7 @@ class RegExpEngine: public AllStatic {
code(isolate->heap()->the_hole_value()),
num_registers(0) {}
CompilationResult(Object* code, int registers)
- : error_message(NULL), code(code), num_registers(registers) {}
+ : error_message(nullptr), code(code), num_registers(registers) {}
const char* error_message;
Object* code;
int num_registers;