20
20
#include < stddef.h>
21
21
#include < stdint.h>
22
22
#include < string.h>
23
+ #include < utility>
23
24
24
25
#include " util/logging.h"
26
+ #include " util/pod_array.h"
25
27
#include " re2/prog.h"
26
28
#include " re2/regexp.h"
27
29
@@ -36,7 +38,6 @@ struct Job {
36
38
class BitState {
37
39
public:
38
40
explicit BitState (Prog* prog);
39
- ~BitState ();
40
41
41
42
// The usual Search prototype.
42
43
// Can only call Search once per BitState.
@@ -47,7 +48,7 @@ class BitState {
47
48
private:
48
49
inline bool ShouldVisit (int id, const char * p);
49
50
void Push (int id, const char * p, int arg);
50
- bool GrowStack ();
51
+ void GrowStack ();
51
52
bool TrySearch (int id, const char * p);
52
53
53
54
// Search parameters
@@ -57,20 +58,15 @@ class BitState {
57
58
bool anchored_; // whether search is anchored at text.begin()
58
59
bool longest_; // whether search wants leftmost-longest match
59
60
bool endmatch_; // whether match must end at text.end()
60
- StringPiece * submatch_; // submatches to fill in
61
+ StringPiece* submatch_; // submatches to fill in
61
62
int nsubmatch_; // # of submatches to fill in
62
63
63
64
// Search state
64
- const char ** cap_; // capture registers
65
- int ncap_;
66
-
67
65
static const int VisitedBits = 32 ;
68
- uint32_t *visited_; // bitmap: (Inst*, char*) pairs already backtracked
69
- size_t nvisited_; // # of words in bitmap
70
-
71
- Job *job_; // stack of text positions to explore
72
- int njob_;
73
- int maxjob_;
66
+ PODArray<uint32_t > visited_; // bitmap: (Inst*, char*) pairs visited
67
+ PODArray<const char *> cap_; // capture registers
68
+ PODArray<Job> job_; // stack of text positions to explore
69
+ int njob_; // stack size
74
70
};
75
71
76
72
BitState::BitState (Prog* prog)
@@ -80,19 +76,7 @@ BitState::BitState(Prog* prog)
80
76
endmatch_(false ),
81
77
submatch_(NULL ),
82
78
nsubmatch_(0 ),
83
- cap_(NULL ),
84
- ncap_(0 ),
85
- visited_(NULL ),
86
- nvisited_(0 ),
87
- job_(NULL ),
88
- njob_(0 ),
89
- maxjob_(0 ) {
90
- }
91
-
92
- BitState::~BitState () {
93
- delete[] visited_;
94
- delete[] job_;
95
- delete[] cap_;
79
+ njob_(0 ) {
96
80
}
97
81
98
82
// Should the search visit the pair ip, p?
@@ -107,24 +91,22 @@ bool BitState::ShouldVisit(int id, const char* p) {
107
91
}
108
92
109
93
// Grow the stack.
110
- bool BitState::GrowStack () {
111
- maxjob_ *= 2 ;
112
- Job* newjob = new Job[maxjob_];
113
- memmove (newjob, job_, njob_*sizeof job_[0 ]);
114
- delete[] job_;
115
- job_ = newjob;
116
- if (njob_ >= maxjob_) {
117
- LOG (DFATAL) << " Job stack overflow." ;
118
- return false ;
119
- }
120
- return true ;
94
+ void BitState::GrowStack () {
95
+ PODArray<Job> tmp (2 *job_.size ());
96
+ memmove (tmp.data (), job_.data (), njob_*sizeof job_[0 ]);
97
+ job_ = std::move (tmp);
121
98
}
122
99
123
100
// Push the triple (id, p, arg) onto the stack, growing it if necessary.
124
101
void BitState::Push (int id, const char * p, int arg) {
125
- if (njob_ >= maxjob_) {
126
- if (!GrowStack ())
102
+ if (njob_ >= job_.size ()) {
103
+ GrowStack ();
104
+ if (njob_ >= job_.size ()) {
105
+ LOG (DFATAL) << " GrowStack() failed: "
106
+ << " njob_ = " << njob_ << " , "
107
+ << " job_.size() = " << job_.size ();
127
108
return ;
109
+ }
128
110
}
129
111
int op = prog_->inst (id)->opcode ();
130
112
if (op == kInstFail )
@@ -234,7 +216,7 @@ bool BitState::TrySearch(int id0, const char* p0) {
234
216
if (!ip->last ())
235
217
Push (id+1 , p, 0 ); // try the next when we're done
236
218
237
- if (0 <= ip->cap () && ip->cap () < ncap_ ) {
219
+ if (0 <= ip->cap () && ip->cap () < cap_. size () ) {
238
220
// Capture p to register, but save old value.
239
221
Push (id, cap_[ip->cap ()], 1 ); // come back when we're done
240
222
cap_[ip->cap ()] = p;
@@ -327,18 +309,19 @@ bool BitState::Search(const StringPiece& text, const StringPiece& context,
327
309
submatch_[i] = StringPiece ();
328
310
329
311
// Allocate scratch space.
330
- nvisited_ = (prog_->size () * (text.size ()+1 ) + VisitedBits-1 ) / VisitedBits;
331
- visited_ = new uint32_t [nvisited_];
332
- memset (visited_, 0 , nvisited_*sizeof visited_[0 ]);
333
-
334
- ncap_ = 2 *nsubmatch;
335
- if (ncap_ < 2 )
336
- ncap_ = 2 ;
337
- cap_ = new const char *[ncap_];
338
- memset (cap_, 0 , ncap_*sizeof cap_[0 ]);
339
-
340
- maxjob_ = 256 ;
341
- job_ = new Job[maxjob_];
312
+ int nvisited = prog_->size () * static_cast <int >(text.size ()+1 );
313
+ nvisited = (nvisited + VisitedBits-1 ) / VisitedBits;
314
+ visited_ = PODArray<uint32_t >(nvisited);
315
+ memset (visited_.data (), 0 , nvisited*sizeof visited_[0 ]);
316
+
317
+ int ncap = 2 *nsubmatch;
318
+ if (ncap < 2 )
319
+ ncap = 2 ;
320
+ cap_ = PODArray<const char *>(ncap);
321
+ memset (cap_.data (), 0 , ncap*sizeof cap_[0 ]);
322
+
323
+ // When sizeof(Job) == 16, we start with a nice round 4KiB. :)
324
+ job_ = PODArray<Job>(256 );
342
325
343
326
// Anchored search must start at text.begin().
344
327
if (anchored_) {
0 commit comments