Skip to content

Commit 686c823

Browse files
authored
Allow match deliver to indicate no need for further delivery (#108)
1 parent 898d662 commit 686c823

File tree

3 files changed

+27
-13
lines changed

3 files changed

+27
-13
lines changed

internal/re2.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,9 @@ func (re *Regexp) findAllSubmatch(alloc *allocation, bsrc []byte, src string, cs
508508

509509
var matches []int
510510
accept := true
511-
readMatches(alloc, cs, matchArr.ptr, nmatch, func(match []int) {
511+
readMatches(alloc, cs, matchArr.ptr, nmatch, func(match []int) bool {
512512
if len(matches) == 0 {
513513
// First match, check if it's an empty match following a match, which we ignore.
514-
// TODO: Don't iterate further when ignoring.
515514
if match[0] == match[1] && match[0] == prevMatchEnd {
516515
accept = false
517516
}
@@ -534,7 +533,12 @@ func (re *Regexp) findAllSubmatch(alloc *allocation, bsrc []byte, src string, cs
534533
}
535534
prevMatchEnd = match[1]
536535
}
537-
matches = append(matches, match...)
536+
if accept {
537+
matches = append(matches, match...)
538+
return true
539+
} else {
540+
return false
541+
}
538542
})
539543
if accept {
540544
deliver(matches)
@@ -564,8 +568,9 @@ func (re *Regexp) FindSubmatch(b []byte) [][]byte {
564568

565569
var matches [][]byte
566570

567-
re.findSubmatch(&alloc, cs, func(match []int) {
571+
re.findSubmatch(&alloc, cs, func(match []int) bool {
568572
matches = append(matches, matchedBytes(b, match))
573+
return true
569574
})
570575

571576
return matches
@@ -584,8 +589,9 @@ func (re *Regexp) FindSubmatchIndex(b []byte) []int {
584589

585590
var matches []int
586591

587-
re.findSubmatch(&alloc, cs, func(match []int) {
592+
re.findSubmatch(&alloc, cs, func(match []int) bool {
588593
matches = append(matches, match...)
594+
return true
589595
})
590596

591597
res := matches
@@ -601,8 +607,9 @@ func (re *Regexp) FindStringSubmatch(s string) []string {
601607

602608
var matches []string
603609

604-
re.findSubmatch(&alloc, cs, func(match []int) {
610+
re.findSubmatch(&alloc, cs, func(match []int) bool {
605611
matches = append(matches, matchedString(s, match))
612+
return true
606613
})
607614

608615
return matches
@@ -621,16 +628,17 @@ func (re *Regexp) FindStringSubmatchIndex(s string) []int {
621628

622629
var matches []int
623630

624-
re.findSubmatch(&alloc, cs, func(match []int) {
631+
re.findSubmatch(&alloc, cs, func(match []int) bool {
625632
matches = append(matches, match...)
633+
return true
626634
})
627635

628636
res := matches
629637
runtime.KeepAlive(s)
630638
return res
631639
}
632640

633-
func (re *Regexp) findSubmatch(alloc *allocation, cs cString, deliver func(match []int)) {
641+
func (re *Regexp) findSubmatch(alloc *allocation, cs cString, deliver func(match []int) bool) {
634642
numGroups := re.numMatches
635643
matchArr := alloc.newCStringArray(numGroups)
636644
defer matchArr.free()

internal/re2_tinygowasm.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,13 @@ func readMatch(_ *allocation, cs cString, matchPtr wasmPtr, dstCap []int) []int
159159
return append(dstCap, int(sIdx), int(sIdx+uintptr(match.length)))
160160
}
161161

162-
func readMatches(alloc *allocation, cs cString, matchesPtr wasmPtr, n int, deliver func([]int)) {
162+
func readMatches(alloc *allocation, cs cString, matchesPtr wasmPtr, n int, deliver func([]int) bool) {
163163
var dstCap [2]int
164164

165165
for i := 0; i < n; i++ {
166166
dst := readMatch(alloc, cs, wasmPtr(unsafe.Add(unsafe.Pointer(matchesPtr), unsafe.Sizeof(cString{})*uintptr(i))), dstCap[:0])
167-
deliver(dst)
167+
if !deliver(dst) {
168+
break
169+
}
168170
}
169171
}

internal/re2_wazero.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,19 +361,23 @@ func readMatch(alloc *allocation, cs cString, matchPtr wasmPtr, dstCap []int) []
361361
return append(dstCap, int(sIdx), int(sIdx+sLen))
362362
}
363363

364-
func readMatches(alloc *allocation, cs cString, matchesPtr wasmPtr, n int, deliver func([]int)) {
364+
func readMatches(alloc *allocation, cs cString, matchesPtr wasmPtr, n int, deliver func([]int) bool) {
365365
var dstCap [2]int
366366

367367
matchesBuf := alloc.read(matchesPtr, 8*n)
368368
for i := 0; i < n; i++ {
369369
subStrPtr := uint32(binary.LittleEndian.Uint32(matchesBuf[8*i:]))
370370
if subStrPtr == 0 {
371-
deliver(append(dstCap[:0], -1, -1))
371+
if !deliver(append(dstCap[:0], -1, -1)) {
372+
break
373+
}
372374
continue
373375
}
374376
sLen := uint32(binary.LittleEndian.Uint32(matchesBuf[8*i+4:]))
375377
sIdx := subStrPtr - uint32(cs.ptr)
376-
deliver(append(dstCap[:0], int(sIdx), int(sIdx+sLen)))
378+
if !deliver(append(dstCap[:0], int(sIdx), int(sIdx+sLen))) {
379+
break
380+
}
377381
}
378382
}
379383

0 commit comments

Comments
 (0)