summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-05-04 15:11:14 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2007-05-04 15:11:14 +0000
commit9d3b898221101517d54cc5cb78d9e035db04cb20 (patch)
treee5601e610d2f57c17a9d52810a41074b0284ec0b
parent2ca8a869b498fa8129ab01b9c698656ff8bf57da (diff)
downloadpcre-9d3b898221101517d54cc5cb78d9e035db04cb20.tar.gz
Replace longjmp() with gotos when not using stack recursion.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@164 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog5
-rwxr-xr-xRunTest35
-rw-r--r--pcre_exec.c232
-rw-r--r--pcre_internal.h11
4 files changed, 176 insertions, 107 deletions
diff --git a/ChangeLog b/ChangeLog
index b908847..292aea5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,11 @@ Version 7.2 01-May-07
was not 2, because the output contained actual offsets. The recent new
"Z" feature of pcretest means that these can be cut out, making the tests
usable with all link sizes.
+
+ 5. Implemented Stan Switzer's goto replacement for longjmp() when not using
+ stack recursion. This gives a massive performance boost under BSD, but just
+ a small improvement under Linux. However, it saves one field in the frame
+ in all cases.
Version 7.1 24-Apr-07
diff --git a/RunTest b/RunTest
index 4a0751e..a05d35f 100755
--- a/RunTest
+++ b/RunTest
@@ -37,6 +37,7 @@ do6=no
do7=no
do8=no
do9=no
+do10=no
while [ $# -gt 0 ] ; do
case $1 in
@@ -49,7 +50,8 @@ while [ $# -gt 0 ] ; do
7) do7=yes;;
8) do8=yes;;
9) do9=yes;;
- valgrind) valgrind="valgrind -q";;
+ 10) do10=yes;;
+ valgrind) valgrind="valgrind -q";;
*) echo "Unknown test number $1"; exit 1;;
esac
shift
@@ -87,13 +89,24 @@ if [ $ucp -eq 0 ] ; then
echo "Can't run test 9 because Unicode property support is not configured"
exit 1
fi
+ if [ $do10 = yes ] ; then
+ echo "Can't run test 10 because Unicode property support is not configured"
+ exit 1
+ fi
fi
+if [ $link_size -ne 2 ] ; then
+ if [ $do10 = yes ] ; then
+ echo "Can't run test 10 because the link size ($link_size) is not 2"
+ exit 1
+ fi
+fi
+
# If no specific tests were requested, select all that are relevant.
if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \
$do5 = no -a $do6 = no -a $do7 = no -a $do8 = no -a \
- $do9 = no ] ; then
+ $do9 = no -a $do10 = no ] ; then
do1=yes
do2=yes
do3=yes
@@ -103,6 +116,7 @@ if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \
do7=yes
if [ $utf8 -ne 0 ] ; then do8=yes; fi
if [ $utf8 -ne 0 -a $ucp -ne 0 ] ; then do9=yes; fi
+ if [ $link_size -eq 2 ] ; then do10=yes; fi
fi
# Show which release
@@ -253,4 +267,21 @@ if [ $do9 = yes ] ; then
echo "OK"
fi
+# Test of internal offsets and code sizes. This test is run only when there
+# is Unicode property support and the link size is 2. The actual tests are
+# mostly the same as in some of the above, but in this test we inspect some
+# offsets and sizes that require a known link size. This is a doublecheck for
+# the maintainer, just in case something changes unexpectely.
+
+if [ $do10 = yes ] ; then
+ echo "Test 10: Internal offsets and code size tests"
+ $valgrind ./pcretest -q $testdata/testinput10 testtry
+ if [ $? = 0 ] ; then
+ $cf $testdata/testoutput10 testtry
+ if [ $? != 0 ] ; then exit 1; fi
+ else exit 1
+ fi
+ echo "OK"
+fi
+
# End
diff --git a/pcre_exec.c b/pcre_exec.c
index b4d3a46..23351bc 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -188,20 +188,45 @@ calls by keeping local variables that need to be preserved in blocks of memory
obtained from malloc() instead instead of on the stack. Macros are used to
achieve this so that the actual code doesn't look very different to what it
always used to.
+
+The original heap-recursive code used longjmp(). However, it seems that this
+can be very slow on some operating systems. Following a suggestion from Stan
+Switzer, the use of longjmp() has been abolished, at the cost of having to
+provide a unique number for each call to RMATCH. There is no way of generating
+a sequence of numbers at compile time in C. I have given them names, to make
+them stand out more clearly.
+
+Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
+FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
+tests. Furthermore, not using longjmp() means that local dynamic variables
+don't have indeterminate values; this has meant that the frame size can be
+reduced because the result can be "passed back" by straight setting of the
+variable instead of being passed in the frame.
****************************************************************************
***************************************************************************/
+/* Numbers for RMATCH calls */
+
+enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
+ RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
+ RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
+ RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
+ RM41, RM42, RM43, RM44, RM45, RM46, RM47 };
+
+
/* These versions of the macros use the stack, as normal. There are debugging
-versions and production versions. */
+versions and production versions. Note that the "rw" argument of RMATCH isn't
+actuall used in this definition. */
#ifndef NO_RECURSE
#define REGISTER register
+
#ifdef DEBUG
-#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
{ \
printf("match() called in line %d\n", __LINE__); \
- rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \
+ rrc = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \
printf("to line %d\n", __LINE__); \
}
#define RRETURN(ra) \
@@ -210,43 +235,37 @@ versions and production versions. */
return ra; \
}
#else
-#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \
- rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1)
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
+ rrc = match(ra,rb,rc,rd,re,rf,rg,rdepth+1)
#define RRETURN(ra) return ra
#endif
#else
-/* These versions of the macros manage a private stack on the heap. Note
-that the rd argument of RMATCH isn't actually used. It's the md argument of
-match(), which never changes. */
+/* These versions of the macros manage a private stack on the heap. Note that
+the "rd" argument of RMATCH isn't actually used in this definition. It's the md
+argument of match(), which never changes. */
#define REGISTER
-#define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
{\
heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
- if (setjmp(frame->Xwhere) == 0)\
- {\
- newframe->Xeptr = ra;\
- newframe->Xecode = rb;\
- newframe->Xoffset_top = rc;\
- newframe->Xims = re;\
- newframe->Xeptrb = rf;\
- newframe->Xflags = rg;\
- newframe->Xrdepth = frame->Xrdepth + 1;\
- newframe->Xprevframe = frame;\
- frame = newframe;\
- DPRINTF(("restarting from line %d\n", __LINE__));\
- goto HEAP_RECURSE;\
- }\
- else\
- {\
- DPRINTF(("longjumped back to line %d\n", __LINE__));\
- frame = md->thisframe;\
- rx = frame->Xresult;\
- }\
+ frame->Xwhere = rw; \
+ newframe->Xeptr = ra;\
+ newframe->Xecode = rb;\
+ newframe->Xoffset_top = rc;\
+ newframe->Xims = re;\
+ newframe->Xeptrb = rf;\
+ newframe->Xflags = rg;\
+ newframe->Xrdepth = frame->Xrdepth + 1;\
+ newframe->Xprevframe = frame;\
+ frame = newframe;\
+ DPRINTF(("restarting from line %d\n", __LINE__));\
+ goto HEAP_RECURSE;\
+ L_##rw:\
+ DPRINTF(("jumped back to line %d\n", __LINE__));\
}
#define RRETURN(ra)\
@@ -256,9 +275,8 @@ match(), which never changes. */
(pcre_stack_free)(newframe);\
if (frame != NULL)\
{\
- frame->Xresult = ra;\
- md->thisframe = frame;\
- longjmp(frame->Xwhere, 1);\
+ rrc = ra;\
+ goto HEAP_RETURN;\
}\
return ra;\
}
@@ -323,11 +341,10 @@ typedef struct heapframe {
eptrblock Xnewptrb;
- /* Place to pass back result, and where to jump back to */
-
- int Xresult;
- jmp_buf Xwhere;
+ /* Where to jump back to */
+ int Xwhere;
+
} heapframe;
#endif
@@ -545,6 +562,12 @@ defined). However, RMATCH isn't like a function call because it's quite a
complicated macro. It has to be used in one particular way. This shouldn't,
however, impact performance when true recursion is being used. */
+#ifdef SUPPORT_UTF8
+utf8 = md->utf8; /* Local copy of the flag */
+#else
+utf8 = FALSE;
+#endif
+
/* First check that we haven't called match() too many times, or that we
haven't exceeded the recursive call limit. */
@@ -553,12 +576,6 @@ if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
original_ims = ims; /* Save for resetting on ')' */
-#ifdef SUPPORT_UTF8
-utf8 = md->utf8; /* Local copy of the flag */
-#else
-utf8 = FALSE;
-#endif
-
/* At the start of a group with an unlimited repeat that may match an empty
string, the match_cbegroup flag is set. When this is the case, add the current
subject pointer to the chain of such remembered pointers, to be checked when we
@@ -637,8 +654,8 @@ for (;;)
flags = (op == OP_SCBRA)? match_cbegroup : 0;
do
{
- RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
- ims, eptrb, flags);
+ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+ ims, eptrb, flags, RM1);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
md->capture_last = save_capture_last;
ecode += GET(ecode, 1);
@@ -681,8 +698,8 @@ for (;;)
/* For non-final alternatives, continue the loop for a NOMATCH result;
otherwise return. */
- RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
- eptrb, flags);
+ RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
+ eptrb, flags, RM2);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
}
@@ -723,8 +740,8 @@ for (;;)
else
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
- match_condassert);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
+ match_condassert, RM3);
if (rrc == MATCH_MATCH)
{
condition = TRUE;
@@ -802,7 +819,8 @@ for (;;)
case OP_ASSERTBACK:
do
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+ RM4);
if (rrc == MATCH_MATCH) break;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
@@ -828,7 +846,8 @@ for (;;)
case OP_ASSERTBACK_NOT:
do
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+ RM5);
if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode,1);
@@ -957,8 +976,8 @@ for (;;)
flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
do
{
- RMATCH(rrc, eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
- md, ims, eptrb, flags);
+ RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
+ md, ims, eptrb, flags, RM6);
if (rrc == MATCH_MATCH)
{
DPRINTF(("Recursion matched\n"));
@@ -1001,8 +1020,8 @@ for (;;)
do
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
- eptrb, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
+ eptrb, 0, RM7);
if (rrc == MATCH_MATCH) break;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode,1);
@@ -1047,7 +1066,8 @@ for (;;)
if (*ecode == OP_KETRMIN)
{
- RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0,
+ RM8);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode = prev;
flags = match_tail_recursed;
@@ -1055,7 +1075,7 @@ for (;;)
}
else /* OP_KETRMAX */
{
- RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_cbegroup);
+ RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += 1 + LINK_SIZE;
flags = match_tail_recursed;
@@ -1079,7 +1099,7 @@ for (;;)
case OP_BRAZERO:
{
next = ecode+1;
- RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
do next += GET(next,1); while (*next == OP_ALT);
ecode = next + 1 + LINK_SIZE;
@@ -1090,7 +1110,7 @@ for (;;)
{
next = ecode+1;
do next += GET(next, 1); while (*next == OP_ALT);
- RMATCH(rrc, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode++;
}
@@ -1195,7 +1215,8 @@ for (;;)
if (*ecode == OP_KETRMIN)
{
- RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0,
+ RM12);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode = prev;
flags |= match_tail_recursed;
@@ -1203,7 +1224,7 @@ for (;;)
}
else /* OP_KETRMAX */
{
- RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, flags);
+ RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += 1 + LINK_SIZE;
flags = match_tail_recursed;
@@ -1602,7 +1623,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || !match_ref(offset, eptr, length, md, ims))
RRETURN(MATCH_NOMATCH);
@@ -1623,7 +1644,7 @@ for (;;)
}
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr -= length;
}
@@ -1728,7 +1749,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -1748,7 +1769,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
c = *eptr++;
@@ -1785,7 +1806,7 @@ for (;;)
}
for (;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -1804,7 +1825,7 @@ for (;;)
}
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
@@ -1875,7 +1896,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -1899,7 +1920,7 @@ for (;;)
}
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr)
@@ -2086,7 +2107,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
if (memcmp(eptr, charptr, length) == 0) eptr += length;
@@ -2127,7 +2148,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr == pp) RRETURN(MATCH_NOMATCH);
#ifdef SUPPORT_UCP
@@ -2176,7 +2197,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject ||
fc != md->lcc[*eptr++])
@@ -2195,7 +2216,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
@@ -2214,7 +2235,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject || fc != *eptr++)
RRETURN(MATCH_NOMATCH);
@@ -2232,7 +2253,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
@@ -2377,7 +2398,7 @@ for (;;)
register unsigned int d;
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
GETCHARINC(d, eptr);
if (d < 256) d = md->lcc[d];
@@ -2391,7 +2412,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])
RRETURN(MATCH_NOMATCH);
@@ -2423,7 +2444,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -2441,7 +2462,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
@@ -2486,7 +2507,7 @@ for (;;)
register unsigned int d;
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
GETCHARINC(d, eptr);
if (fi >= max || eptr >= md->end_subject || fc == d)
@@ -2499,7 +2520,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject || fc == *eptr++)
RRETURN(MATCH_NOMATCH);
@@ -2530,7 +2551,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -2548,7 +2569,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
@@ -2945,7 +2966,7 @@ for (;;)
case PT_ANY:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2956,7 +2977,7 @@ for (;;)
case PT_LAMP:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2971,7 +2992,7 @@ for (;;)
case PT_GC:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2984,7 +3005,7 @@ for (;;)
case PT_PC:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -2997,7 +3018,7 @@ for (;;)
case PT_SC:
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINC(c, eptr);
@@ -3019,7 +3040,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
GETCHARINCTEST(c, eptr);
@@ -3048,7 +3069,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject ||
(ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&
@@ -3122,7 +3143,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max || eptr >= md->end_subject ||
((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))
@@ -3268,7 +3289,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -3304,7 +3325,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
for (;;) /* Move back over one extended */
@@ -3488,7 +3509,7 @@ for (;;)
if (possessive) continue;
for(;;)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (eptr-- == pp) break; /* Stop if tried at original pos */
BACKCHAR(eptr);
@@ -3602,7 +3623,7 @@ for (;;)
if (possessive) continue;
while (eptr >= pp)
{
- RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
+ RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
@@ -3628,6 +3649,29 @@ for (;;)
} /* End of main loop */
/* Control never reaches here */
+
+
+/* When compiling to use the heap rather than the stack for recursive calls to
+match(), the RRETURN() macro jumps here. The number that is saved in
+frame->Xwhere indicates which label we actually want to return to. */
+
+#ifdef NO_RECURSE
+#define LBL(val) case val: goto L_RM##val;
+HEAP_RETURN:
+switch (frame->Xwhere)
+ {
+ LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
+ LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)
+ LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)
+ LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)
+ LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) LBL(38) LBL(39) LBL(40)
+ LBL(41) LBL(42) LBL(43) LBL(44) LBL(45) LBL(46) LBL(47)
+ default:
+ DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
+ return PCRE_ERROR_INTERNAL;
+ }
+#undef LBL
+#endif /* NO_RECURSE */
}
diff --git a/pcre_internal.h b/pcre_internal.h
index 8a7ad5d..7ce6079 100644
--- a/pcre_internal.h
+++ b/pcre_internal.h
@@ -949,16 +949,6 @@ typedef struct recursion_info {
int saved_max; /* Number of saved offsets */
} recursion_info;
-/* When compiling in a mode that doesn't use recursive calls to match(),
-a structure is used to remember local variables on the heap. It is defined in
-pcre_exec.c, close to the match() function, so that it is easy to keep it in
-step with any changes of local variable. However, the pointer to the current
-frame must be saved in some "static" place over a longjmp(). We declare the
-structure here so that we can put a pointer in the match_data structure. NOTE:
-This isn't used for a "normal" compilation of pcre. */
-
-struct heapframe;
-
/* Structure for building a chain of data for holding the values of the subject
pointer at the start of each subpattern, so as to detect when an empty string
has been matched by a subpattern - to break infinite loops. */
@@ -1004,7 +994,6 @@ typedef struct match_data {
int eptrn; /* Next free eptrblock */
recursion_info *recursive; /* Linked list of recursion data */
void *callout_data; /* To pass back to callouts */
- struct heapframe *thisframe; /* Used only when compiling for no recursion */
} match_data;
/* A similar structure is used for the same purpose by the DFA matching