diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2007-05-04 15:11:14 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2007-05-04 15:11:14 +0000 |
commit | 9d3b898221101517d54cc5cb78d9e035db04cb20 (patch) | |
tree | e5601e610d2f57c17a9d52810a41074b0284ec0b | |
parent | 2ca8a869b498fa8129ab01b9c698656ff8bf57da (diff) | |
download | pcre-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-- | ChangeLog | 5 | ||||
-rwxr-xr-x | RunTest | 35 | ||||
-rw-r--r-- | pcre_exec.c | 232 | ||||
-rw-r--r-- | pcre_internal.h | 11 |
4 files changed, 176 insertions, 107 deletions
@@ -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 @@ -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 |