summaryrefslogtreecommitdiff
path: root/libgo/go/regexp/exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/regexp/exec.go')
-rw-r--r--libgo/go/regexp/exec.go45
1 files changed, 19 insertions, 26 deletions
diff --git a/libgo/go/regexp/exec.go b/libgo/go/regexp/exec.go
index 518272092a..977619cb28 100644
--- a/libgo/go/regexp/exec.go
+++ b/libgo/go/regexp/exec.go
@@ -19,7 +19,7 @@ type queue struct {
// A entry is an entry on a queue.
// It holds both the instruction pc and the actual thread.
// Some queue entries are just place holders so that the machine
-// knows it has considered that pc. Such entries have t == nil.
+// knows it has considered that pc. Such entries have t == nil.
type entry struct {
pc uint32
t *thread
@@ -107,14 +107,6 @@ func (m *machine) alloc(i *syntax.Inst) *thread {
return t
}
-// free returns t to the free pool.
-func (m *machine) free(t *thread) {
- m.inputBytes.str = nil
- m.inputString.str = ""
- m.inputReader.r = nil
- m.pool = append(m.pool, t)
-}
-
// match runs the machine over the input starting at pos.
// It reports whether a match was found.
// If so, m.matchcap holds the submatch information.
@@ -192,7 +184,6 @@ func (m *machine) match(i input, pos int) bool {
func (m *machine) clear(q *queue) {
for _, d := range q.dense {
if d.t != nil {
- // m.free(d.t)
m.pool = append(m.pool, d.t)
}
}
@@ -213,7 +204,6 @@ func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond sy
continue
}
if longest && m.matched && len(t.cap) > 0 && m.matchcap[0] < t.cap[0] {
- // m.free(t)
m.pool = append(m.pool, t)
continue
}
@@ -232,7 +222,6 @@ func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond sy
// First-match mode: cut off all lower-priority threads.
for _, d := range runq.dense[j+1:] {
if d.t != nil {
- // m.free(d.t)
m.pool = append(m.pool, d.t)
}
}
@@ -253,7 +242,6 @@ func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond sy
t = m.add(nextq, i.Out, nextPos, t.cap, nextCond, t)
}
if t != nil {
- // m.free(t)
m.pool = append(m.pool, t)
}
}
@@ -417,14 +405,16 @@ func (m *machine) onepass(i input, pos int) bool {
return m.matched
}
-// empty is a non-nil 0-element slice,
-// so doExecute can avoid an allocation
-// when 0 captures are requested from a successful match.
-var empty = make([]int, 0)
+// doMatch reports whether either r, b or s match the regexp.
+func (re *Regexp) doMatch(r io.RuneReader, b []byte, s string) bool {
+ return re.doExecute(r, b, s, 0, 0, nil) != nil
+}
-// doExecute finds the leftmost match in the input and returns
-// the position of its subexpressions.
-func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap int) []int {
+// doExecute finds the leftmost match in the input, appends the position
+// of its subexpressions to dstCap and returns dstCap.
+//
+// nil is returned if no matches are found and non-nil if matches are found.
+func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap int, dstCap []int) []int {
m := re.get()
var i input
var size int
@@ -457,12 +447,15 @@ func (re *Regexp) doExecute(r io.RuneReader, b []byte, s string, pos int, ncap i
return nil
}
}
- if ncap == 0 {
- re.put(m)
- return empty // empty but not nil
+ dstCap = append(dstCap, m.matchcap...)
+ if dstCap == nil {
+ // Keep the promise of returning non-nil value on match.
+ dstCap = arrayNoInts[:0]
}
- cap := make([]int, len(m.matchcap))
- copy(cap, m.matchcap)
re.put(m)
- return cap
+ return dstCap
}
+
+// arrayNoInts is returned by doExecute match if nil dstCap is passed
+// to it with ncap=0.
+var arrayNoInts [0]int