Re: [pcre-dev] External memory allocator interface

Top Page
Delete this message
Author: Roman Rybalko
Date:  
To: pcre-dev
Subject: Re: [pcre-dev] External memory allocator interface
Philip Hazel wrote:
> On Mon, 9 Jun 2008, Roman Rybalko wrote:
>
>> I'll place them in additional pcre_mm.h file.
>> Will it be suitable?
>>
> It sounds reasonable. I will look at it when you have done it and see
> what I think.
>

Here it is. (just a draft)

I've ported pcre_compile* and pcre_exec, but NO_RECURSE is broken now,
at least because I don't know yet how to deal with it in the new
context. Probably I should add stack_malloc/stack_free methods to struct
pcre_mm.

Generally, I see all this as a new MM layer on top of existing.

--
WBR,
Roman Rybalko

diff -uN pcre-7.7.orig/Makefile.am pcre-7.7/Makefile.am
--- pcre-7.7.orig/Makefile.am    2008-01-23 20:58:28.000000000 +0300
+++ pcre-7.7/Makefile.am    2008-06-09 15:21:27.000000000 +0400
@@ -184,7 +184,9 @@
   pcre_xclass.c \
   ucp.h \
   ucpinternal.h \
-  ucptable.h
+  ucptable.h \
+  pcre_mm.c \
+  pcre_mm.h


 ## This file is generated as part of the building process, so don't distribute.
 nodist_libpcre_la_SOURCES = \
diff -uN pcre-7.7.orig/pcre_compile.c pcre-7.7/pcre_compile.c
--- pcre-7.7.orig/pcre_compile.c    2008-04-28 19:06:46.000000000 +0400
+++ pcre-7.7/pcre_compile.c    2008-06-10 12:02:51.000000000 +0400
@@ -5953,9 +5953,30 @@



PCRE_EXP_DEFN pcre *
+pcre_mm_compile(const pcre_mm *mm, const char *pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+{
+return pcre_mm_compile2(mm, pattern, options, NULL, errorptr, erroroffset, tables);
+}
+
+
+PCRE_EXP_DEFN pcre *
pcre_compile2(const char *pattern, int options, int *errorcodeptr,
const char **errorptr, int *erroroffset, const unsigned char *tables)
{
+pcre_mm a_mm;
+memset(&a_mm, 0, sizeof(a_mm));
+a_mm.malloc = _pcre_default_malloc;
+a_mm.free = _pcre_default_free;
+
+return pcre_mm_compile2(&a_mm, pattern, options, errorcodeptr, errorptr, erroroffset, tables);
+}
+
+
+PCRE_EXP_DEFN pcre *
+pcre_mm_compile2(const pcre_mm *mm, const char *pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+{
real_pcre *re;
int length = 1; /* For final END opcode */
int firstbyte, reqbyte, newline;
@@ -6181,7 +6202,7 @@
cd->name_entry_size. */

size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
-re = (real_pcre *)(pcre_malloc)(size);
+re = (real_pcre *)pcre_mm_malloc(mm, size);

if (re == NULL)
{
@@ -6277,7 +6298,7 @@

if (errorcode != 0)
{
- (pcre_free)(re);
+ pcre_mm_free(mm, re);
PCRE_EARLY_ERROR_RETURN:
*erroroffset = ptr - (const uschar *)pattern;
PCRE_EARLY_ERROR_RETURN2:
@@ -6365,7 +6386,7 @@

 if (code - codestart > length)
   {
-  (pcre_free)(re);
+  pcre_mm_free(mm, re);
   *errorptr = find_error_text(ERR23);
   *erroroffset = ptr - (uschar *)pattern;
   if (errorcodeptr != NULL) *errorcodeptr = ERR23;
diff -uN pcre-7.7.orig/pcre_exec.c pcre-7.7/pcre_exec.c
--- pcre-7.7.orig/pcre_exec.c    2008-04-28 19:06:46.000000000 +0400
+++ pcre-7.7/pcre_exec.c    2008-06-10 12:03:06.000000000 +0400
@@ -229,10 +229,10 @@
 #define REGISTER register


#ifdef DEBUG
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
+#define RMATCH(mm,ra,rb,rc,rd,re,rf,rg,rw) \
{ \
printf("match() called in line %d\n", __LINE__); \
- rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \
+ rrc = match(mm,ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \
printf("to line %d\n", __LINE__); \
}
#define RRETURN(ra) \
@@ -241,8 +241,8 @@
return ra; \
}
#else
-#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
- rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)
+#define RMATCH(mm,ra,rb,rc,rd,re,rf,rg,rw) \
+ rrc = match(mm,ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)
#define RRETURN(ra) return ra
#endif

@@ -399,7 +399,7 @@
*/

 static int
-match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,
+match(const pcre_mm *mm, REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,
   int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
   int flags, unsigned int rdepth)
 {
@@ -624,26 +624,26 @@
     RRETURN(MATCH_NOMATCH);


     case OP_PRUNE:
-    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+    RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
       ims, eptrb, flags, RM51);
     if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     RRETURN(MATCH_PRUNE);


     case OP_COMMIT:
-    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+    RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
       ims, eptrb, flags, RM52);
     if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     RRETURN(MATCH_COMMIT);


     case OP_SKIP:
-    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+    RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
       ims, eptrb, flags, RM53);
     if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     md->start_match_ptr = eptr;   /* Pass back current position */
     RRETURN(MATCH_SKIP);


     case OP_THEN:
-    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+    RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
       ims, eptrb, flags, RM54);
     if (rrc != MATCH_NOMATCH) RRETURN(rrc);
     RRETURN(MATCH_THEN);
@@ -687,7 +687,7 @@
       flags = (op == OP_SCBRA)? match_cbegroup : 0;
       do
         {
-        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+        RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
           ims, eptrb, flags, RM1);
         if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
         md->capture_last = save_capture_last;
@@ -738,7 +738,7 @@


         /* Possibly empty group; can't use tail recursion. */


-        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
+        RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
           eptrb, flags, RM48);
         RRETURN(rrc);
         }
@@ -746,7 +746,7 @@
       /* For non-final alternatives, continue the loop for a NOMATCH result;
       otherwise return. */


-      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
+      RMATCH(mm, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
         eptrb, flags, RM2);
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
       ecode += GET(ecode, 1);
@@ -788,7 +788,7 @@


     else
       {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
+      RMATCH(mm, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
           match_condassert, RM3);
       if (rrc == MATCH_MATCH)
         {
@@ -817,7 +817,7 @@
       ecode += 1 + LINK_SIZE;
       if (op == OP_SCOND)        /* Possibly empty group */
         {
-        RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
+        RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
         RRETURN(rrc);
         }
       else                       /* Group must match something */
@@ -879,7 +879,7 @@
     case OP_ASSERTBACK:
     do
       {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+      RMATCH(mm, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
         RM4);
       if (rrc == MATCH_MATCH) break;
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
@@ -906,7 +906,7 @@
     case OP_ASSERTBACK_NOT:
     do
       {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+      RMATCH(mm, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
         RM5);
       if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
@@ -1020,7 +1020,7 @@
       else
         {
         new_recursive.offset_save =
-          (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));
+          (int *)pcre_mm_malloc(mm, new_recursive.saved_max * sizeof(int));
         if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
         }


@@ -1036,14 +1036,14 @@
       flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
       do
         {
-        RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
+        RMATCH(mm, eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
           md, ims, eptrb, flags, RM6);
         if (rrc == MATCH_MATCH)
           {
           DPRINTF(("Recursion matched\n"));
           md->recursive = new_recursive.prevrec;
           if (new_recursive.offset_save != stacksave)
-            (pcre_free)(new_recursive.offset_save);
+            pcre_mm_free(mm, new_recursive.offset_save);
           RRETURN(MATCH_MATCH);
           }
         else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
@@ -1062,7 +1062,7 @@
       DPRINTF(("Recursion didn't match\n"));
       md->recursive = new_recursive.prevrec;
       if (new_recursive.offset_save != stacksave)
-        (pcre_free)(new_recursive.offset_save);
+        pcre_mm_free(mm, new_recursive.offset_save);
       RRETURN(MATCH_NOMATCH);
       }
     /* Control never reaches here */
@@ -1080,7 +1080,7 @@


     do
       {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
+      RMATCH(mm, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
       if (rrc == MATCH_MATCH) break;
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
       ecode += GET(ecode,1);
@@ -1125,7 +1125,7 @@


     if (*ecode == OP_KETRMIN)
       {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
+      RMATCH(mm, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       ecode = prev;
       flags = 0;
@@ -1133,7 +1133,7 @@
       }
     else  /* OP_KETRMAX */
       {
-      RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
+      RMATCH(mm, eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       ecode += 1 + LINK_SIZE;
       flags = 0;
@@ -1157,7 +1157,7 @@
     case OP_BRAZERO:
       {
       next = ecode+1;
-      RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
+      RMATCH(mm, 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;
@@ -1168,7 +1168,7 @@
       {
       next = ecode+1;
       do next += GET(next, 1); while (*next == OP_ALT);
-      RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
+      RMATCH(mm, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       ecode++;
       }
@@ -1282,11 +1282,11 @@


     if (*ecode == OP_KETRMIN)
       {
-      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
+      RMATCH(mm, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       if (flags != 0)    /* Could match an empty string */
         {
-        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
+        RMATCH(mm, eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
         RRETURN(rrc);
         }
       ecode = prev;
@@ -1294,7 +1294,7 @@
       }
     else  /* OP_KETRMAX */
       {
-      RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
+      RMATCH(mm, eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       ecode += 1 + LINK_SIZE;
       flags = 0;
@@ -1808,7 +1808,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
+          RMATCH(mm, 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);
@@ -1829,7 +1829,7 @@
           }
         while (eptr >= pp)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
+          RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           eptr -= length;
           }
@@ -1934,7 +1934,7 @@
           {
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
+            RMATCH(mm, 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);
@@ -1954,7 +1954,7 @@
           {
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
+            RMATCH(mm, 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++;
@@ -1991,7 +1991,7 @@
             }
           for (;;)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
+            RMATCH(mm, 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);
@@ -2010,7 +2010,7 @@
             }
           while (eptr >= pp)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
+            RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
             eptr--;
             }
@@ -2081,7 +2081,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
+          RMATCH(mm, 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);
@@ -2105,7 +2105,7 @@
           }
         for(;;)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
+          RMATCH(mm, 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 */
           if (utf8) BACKCHAR(eptr);
@@ -2292,7 +2292,7 @@
           {
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
+            RMATCH(mm, 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;
@@ -2333,7 +2333,7 @@
           if (possessive) continue;
           for(;;)
            {
-           RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
+           RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
            if (eptr == pp) RRETURN(MATCH_NOMATCH);
 #ifdef SUPPORT_UCP
@@ -2382,7 +2382,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
+          RMATCH(mm, 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++])
@@ -2401,7 +2401,7 @@
         if (possessive) continue;
         while (eptr >= pp)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
+          RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
           eptr--;
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           }
@@ -2420,7 +2420,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
+          RMATCH(mm, 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);
@@ -2438,7 +2438,7 @@
         if (possessive) continue;
         while (eptr >= pp)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
+          RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
           eptr--;
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           }
@@ -2583,7 +2583,7 @@
           register unsigned int d;
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
+            RMATCH(mm, 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];
@@ -2597,7 +2597,7 @@
           {
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
+            RMATCH(mm, 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);
@@ -2629,7 +2629,7 @@
         if (possessive) continue;
         for(;;)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
+            RMATCH(mm, 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);
@@ -2647,7 +2647,7 @@
           if (possessive) continue;
           while (eptr >= pp)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
+            RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
             eptr--;
             }
@@ -2692,7 +2692,7 @@
           register unsigned int d;
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
+            RMATCH(mm, 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)
@@ -2705,7 +2705,7 @@
           {
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
+            RMATCH(mm, 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);
@@ -2736,7 +2736,7 @@
           if (possessive) continue;
           for(;;)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
+            RMATCH(mm, 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);
@@ -2754,7 +2754,7 @@
           if (possessive) continue;
           while (eptr >= pp)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
+            RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
             if (rrc != MATCH_NOMATCH) RRETURN(rrc);
             eptr--;
             }
@@ -3334,7 +3334,7 @@
           case PT_ANY:
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
+            RMATCH(mm, 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);
@@ -3345,7 +3345,7 @@
           case PT_LAMP:
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
+            RMATCH(mm, 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);
@@ -3360,7 +3360,7 @@
           case PT_GC:
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
+            RMATCH(mm, 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);
@@ -3373,7 +3373,7 @@
           case PT_PC:
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
+            RMATCH(mm, 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);
@@ -3386,7 +3386,7 @@
           case PT_SC:
           for (fi = min;; fi++)
             {
-            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
+            RMATCH(mm, 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);
@@ -3408,7 +3408,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
+          RMATCH(mm, 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);
@@ -3437,7 +3437,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
+          RMATCH(mm, 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 && IS_NEWLINE(eptr)))
@@ -3596,7 +3596,7 @@
         {
         for (fi = min;; fi++)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
+          RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           if (fi >= max || eptr >= md->end_subject ||
                (ctype == OP_ANY && IS_NEWLINE(eptr)))
@@ -3793,7 +3793,7 @@
         if (possessive) continue;
         for(;;)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
+          RMATCH(mm, 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 */
           if (utf8) BACKCHAR(eptr);
@@ -3829,7 +3829,7 @@
         if (possessive) continue;
         for(;;)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
+          RMATCH(mm, 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 */
@@ -4065,7 +4065,7 @@
         if (possessive) continue;
         for(;;)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
+          RMATCH(mm, 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);
@@ -4220,7 +4220,7 @@
         if (possessive) continue;
         while (eptr >= pp)
           {
-          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
+          RMATCH(mm, eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
           eptr--;
           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
           }
@@ -4365,6 +4365,19 @@
   PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
   int offsetcount)
 {
+pcre_mm a_mm;
+memset(&a_mm, 0, sizeof(a_mm));
+a_mm.malloc = _pcre_default_malloc;
+a_mm.free = _pcre_default_free;
+return pcre_mm_exec(&a_mm, argument_re, extra_data, subject, length, start_offset, options, offsets, offsetcount);
+}
+
+
+PCRE_EXP_DEFN int
+pcre_mm_exec(const pcre_mm *mm, const pcre *argument_re, const pcre_extra *extra_data,
+  PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
+  int offsetcount)
+{
 int rc, resetcount, ocount;
 int first_byte = -1;
 int req_byte = -1;
@@ -4583,7 +4596,7 @@
 if (re->top_backref > 0 && re->top_backref >= ocount/3)
   {
   ocount = re->top_backref * 3 + 3;
-  md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
+  md->offset_vector = (int *)pcre_mm_malloc(mm, ocount * sizeof(int));
   if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
   using_temporary_offsets = TRUE;
   DPRINTF(("Got memory to hold back references\n"));
@@ -4797,7 +4810,7 @@


md->start_match_ptr = start_match;
md->match_call_count = 0;
- rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);
+ rc = match(mm, start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);

   switch(rc)
     {
@@ -4902,7 +4915,7 @@
       }
     if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
     DPRINTF(("Freeing temporary memory\n"));
-    (pcre_free)(md->offset_vector);
+    pcre_mm_free(mm, md->offset_vector);
     }


/* Set the return code to the number of captured strings, or 0 if there are
@@ -4930,7 +4943,7 @@
if (using_temporary_offsets)
{
DPRINTF(("Freeing temporary memory\n"));
- (pcre_free)(md->offset_vector);
+ pcre_mm_free(mm, md->offset_vector);
}

 if (rc != MATCH_NOMATCH)
diff -uN pcre-7.7.orig/pcre_internal.h pcre-7.7/pcre_internal.h
--- pcre-7.7.orig/pcre_internal.h    2008-04-28 19:06:46.000000000 +0400
+++ pcre-7.7/pcre_internal.h    2008-06-10 12:02:16.000000000 +0400
@@ -230,6 +230,7 @@
 values. */


#include "pcre.h"
+#include "pcre_mm.h"
#include "ucp.h"

 /* When compiling for use with the Virtual Pascal compiler, these functions
@@ -1133,6 +1134,10 @@
                       int *, BOOL);
 extern BOOL         _pcre_xclass(int, const uschar *);


+/* Default mm system wtappers */
+void *_pcre_default_malloc(void *_stub_ctx, size_t);
+void _pcre_default_free(void *_stub_ctx, void *);
+
#endif

 /* End of pcre_internal.h */
diff -uN pcre-7.7.orig/pcre_mm.c pcre-7.7/pcre_mm.c
--- pcre-7.7.orig/pcre_mm.c    1970-01-01 03:00:00.000000000 +0300
+++ pcre-7.7/pcre_mm.c    2008-06-10 12:01:37.000000000 +0400
@@ -0,0 +1,81 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2008 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains mm functions. */
+
+
+#ifndef DFTABLES
+#  ifdef HAVE_CONFIG_H
+#  include "config.h"
+#  endif
+#  include "pcre_internal.h"
+#endif
+
+#include <assert.h>
+
+void *_pcre_default_malloc(void *_stub_ctx, size_t size)
+{
+return pcre_malloc(size);
+}
+
+
+void _pcre_default_free(void *_stub_ctx, void *ptr)
+{
+return pcre_free(ptr);
+}
+
+
+PCRE_EXP_DECL void *pcre_mm_malloc(const pcre_mm *mm, size_t size)
+{
+assert(mm);
+assert(mm->malloc);
+return (mm->malloc)(mm->ctx, size);
+}
+
+
+PCRE_EXP_DECL void pcre_mm_free(const pcre_mm *mm, void *ptr)
+{
+assert(mm);
+assert(mm->free);
+return (mm->free)(mm->ctx, ptr);
+}
+
+
+/* End of pcre_mm.c */
diff -uN pcre-7.7.orig/pcre_mm.h pcre-7.7/pcre_mm.h
--- pcre-7.7.orig/pcre_mm.h    1970-01-01 03:00:00.000000000 +0300
+++ pcre-7.7/pcre_mm.h    2008-06-09 16:35:21.000000000 +0400
@@ -0,0 +1,98 @@
+/*************************************************
+*       Perl-Compatible Regular Expressions      *
+*************************************************/
+
+/* This is the public header file for the PCRE library, to be #included by
+applications that call the PCRE functions.
+
+           Copyright (c) 1997-2008 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef _PCRE_MM_H
+#define _PCRE_MM_H
+
+#include "pcre.h"
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Types */
+
+/* The structure with memory management functions */
+
+typedef struct pcre_mm {
+  void *(*malloc)(void *ctx, size_t);
+  void  (*free)(void *ctx, void*);
+  void *ctx;
+} pcre_mm;
+
+
+/* Memory management functions */
+
+PCRE_EXP_DECL void *pcre_mm_malloc(const pcre_mm *, size_t);
+PCRE_EXP_DECL void  pcre_mm_free(const pcre_mm *, void *);
+//PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
+//PCRE_EXP_DECL void  (*pcre_stack_free)(void *);
+
+/* Exported PCRE functions */
+
+PCRE_EXP_DECL pcre *pcre_mm_compile(const pcre_mm *, const char *, int, const char **, int *,
+                  const unsigned char *);
+PCRE_EXP_DECL pcre *pcre_mm_compile2(const pcre_mm *, const char *, int, int *, const char **,
+                  int *, const unsigned char *);
+/*PCRE_EXP_DECL int  pcre_mm_copy_named_substring(const pcre_mm *, const pcre *, const char *,
+                  int *, int, const char *, char *, int);*/
+/*PCRE_EXP_DECL int  pcre_mm_copy_substring(const pcre_mm *, const char *, int *, int, int, char *,
+                  int);*/
+/*PCRE_EXP_DECL int  pcre_mm_dfa_exec(const pcre_mm *, const pcre *, const pcre_extra *,
+                  const char *, int, int, int, int *, int , int *, int);*/
+PCRE_EXP_DECL int  pcre_mm_exec(const pcre_mm *, const pcre *, const pcre_extra *, PCRE_SPTR,
+                   int, int, int, int *, int);
+/*PCRE_EXP_DECL void pcre_mm_free_substring(const pcre_mm *, const pcre *, const char *);*/
+/*PCRE_EXP_DECL void pcre_mm_free_substring_list(const pcre_mm *, const pcre *, const char **);*/
+/*PCRE_EXP_DECL int  pcre_mm_fullinfo(const pcre_mm *, const pcre *, const pcre_extra *, int,
+                  void *);*/
+/*PCRE_EXP_DECL int  pcre_mm_get_named_substring(const pcre_mm *, const pcre *, const char *,
+                  int *, int, const char *, const char **);*/
+/*PCRE_EXP_DECL int  pcre_mm_get_stringnumber(const pcre_mm *, const pcre *, const char *);*/
+/*PCRE_EXP_DECL int  pcre_mm_get_stringtable_entries(const pcre_mm *, const pcre *, const char *,
+                  char **, char **);*/
+/*PCRE_EXP_DECL const unsigned char *pcre_maketables(pcre_mm *);*/
+/*PCRE_EXP_DECL pcre_extra *pcre_study(const pcre_mm *, const pcre *, int, const char **);*/
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* _PCRE_MM_H */