[Pcre-svn] [941] code/trunk: (COMMIT*) is now supported by t…

Startseite
Nachricht löschen
Autor: Subversion repository
Datum:  
To: pcre-svn
Betreff: [Pcre-svn] [941] code/trunk: (COMMIT*) is now supported by the JIT compiler
Revision: 941
          http://vcs.pcre.org/viewvc?view=rev&revision=941
Author:   zherczeg
Date:     2012-02-28 11:33:34 +0000 (Tue, 28 Feb 2012)


Log Message:
-----------
(COMMIT*) is now supported by the JIT compiler

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/pcre_exec.c
    code/trunk/pcre_internal.h
    code/trunk/pcre_jit_compile.c
    code/trunk/pcre_jit_test.c
    code/trunk/testdata/testinput12
    code/trunk/testdata/testoutput12


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/ChangeLog    2012-02-28 11:33:34 UTC (rev 941)
@@ -63,7 +63,9 @@
 15. It is now possible to link pcretest with libedit as an alternative to 
     libreadline.


+16. (*COMMIT) control verb is now supported by the JIT compiler.

+
Version 8.30 04-February-2012
-----------------------------


Modified: code/trunk/pcre_exec.c
===================================================================
--- code/trunk/pcre_exec.c    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/pcre_exec.c    2012-02-28 11:33:34 UTC (rev 941)
@@ -6469,11 +6469,8 @@
                     PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
                     PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
   {
-  rc = PRIV(jit_exec)(re, extra_data->executable_jit,
-    (const pcre_uchar *)subject, length, start_offset, options,
-    ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
-    ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount,
-    ((extra_data->flags & PCRE_EXTRA_MARK) != 0) ? extra_data->mark : NULL);
+  rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,
+       start_offset, options, offsets, offsetcount);


/* PCRE_ERROR_NULL means that the selected normal or partial matching
mode is not compiled. In this case we simply fallback to interpreter. */

Modified: code/trunk/pcre_internal.h
===================================================================
--- code/trunk/pcre_internal.h    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/pcre_internal.h    2012-02-28 11:33:34 UTC (rev 941)
@@ -2296,10 +2296,10 @@
 extern BOOL              PRIV(xclass)(int, const pcre_uchar *, BOOL);


 #ifdef SUPPORT_JIT
-extern void              PRIV(jit_compile)(const REAL_PCRE *, PUBL(extra) *, int);
-extern int               PRIV(jit_exec)(const REAL_PCRE *, void *,
-                           const pcre_uchar *, int, int, int, int, int *, int,
-                           pcre_uchar **);
+extern void              PRIV(jit_compile)(const REAL_PCRE *,
+                           PUBL(extra) *, int);
+extern int               PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *,
+                           const pcre_uchar *, int, int, int, int *, int);
 extern void              PRIV(jit_free)(void *);
 extern int               PRIV(jit_get_size)(void *);
 extern const char*       PRIV(jit_get_target)(void);


Modified: code/trunk/pcre_jit_compile.c
===================================================================
--- code/trunk/pcre_jit_compile.c    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/pcre_jit_compile.c    2012-02-28 11:33:34 UTC (rev 941)
@@ -307,11 +307,13 @@


/* Labels and jump lists. */
struct sljit_label *partialmatchlabel;
+ struct sljit_label *leavelabel;
struct sljit_label *acceptlabel;
stub_list *stubs;
recurse_entry *entries;
recurse_entry *currententry;
jump_list *partialmatch;
+ jump_list *leave;
jump_list *accept;
jump_list *calllimit;
jump_list *stackalloc;
@@ -517,6 +519,7 @@
case OP_BRAZERO:
case OP_BRAMINZERO:
case OP_BRAPOSZERO:
+ case OP_COMMIT:
case OP_FAIL:
case OP_ACCEPT:
case OP_ASSERT_ACCEPT:
@@ -4159,7 +4162,7 @@
}
else if (common->has_set_som || common->mark_ptr != 0)
{
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
allocate_stack(common, 1);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
}
@@ -4186,10 +4189,12 @@
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
jump_list **found;
/* Saving previous accept variables. */
+struct sljit_label *save_leavelabel = common->leavelabel;
struct sljit_label *save_acceptlabel = common->acceptlabel;
+jump_list *save_leave = common->leave;
+jump_list *save_accept = common->accept;
struct sljit_jump *jump;
struct sljit_jump *brajump = NULL;
-jump_list *save_accept = common->accept;

if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
{
@@ -4234,6 +4239,8 @@
}

 memset(&altfallback, 0, sizeof(fallback_common));
+common->leavelabel = NULL;
+common->leave = NULL;
 while (1)
   {
   common->acceptlabel = NULL;
@@ -4248,7 +4255,9 @@
   compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {
+    common->leavelabel = save_leavelabel;
     common->acceptlabel = save_acceptlabel;
+    common->leave = save_leave;
     common->accept = save_accept;
     return NULL;
     }
@@ -4301,7 +4310,9 @@
   compile_fallbackpath(common, altfallback.top);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {
+    common->leavelabel = save_leavelabel;
     common->acceptlabel = save_acceptlabel;
+    common->leave = save_leave;
     common->accept = save_accept;
     return NULL;
     }
@@ -4314,6 +4325,8 @@
   cc += GET(cc, 1);
   }
 /* None of them matched. */
+if (common->leave != NULL)
+  set_jumps(common->leave, LABEL());


 if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
   {
@@ -4438,7 +4451,9 @@
     }
   }


+common->leavelabel = save_leavelabel;
 common->acceptlabel = save_acceptlabel;
+common->leave = save_leave;
 common->accept = save_accept;
 return cc + 1 + LINK_SIZE;
 }
@@ -5810,6 +5825,11 @@
     cc += 1 + 2 + cc[1];
     break;


+    case OP_COMMIT:
+    PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
+    cc += 1;
+    break;
+
     case OP_FAIL:
     case OP_ACCEPT:
     case OP_ASSERT_ACCEPT:
@@ -6016,7 +6036,7 @@
   {
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
   free_stack(common, 1);
-  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr, TMP2, 0);
+  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
   }
 }


@@ -6659,6 +6679,14 @@
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
     break;


+    case OP_COMMIT:
+    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+    if (common->leavelabel == NULL)
+      add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
+    else
+      JUMPTO(SLJIT_JUMP, common->leavelabel);
+    break;
+
     case OP_FAIL:
     case OP_ACCEPT:
     case OP_ASSERT_ACCEPT:
@@ -6684,6 +6712,8 @@
 int alternativesize;
 BOOL needsframe;
 fallback_common altfallback;
+struct sljit_label *save_leavelabel = common->leavelabel;
+jump_list *save_leave = common->leave;
 struct sljit_jump *jump;


SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
@@ -6708,7 +6738,9 @@
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);

memset(&altfallback, 0, sizeof(fallback_common));
+common->leavelabel = NULL;
common->acceptlabel = NULL;
+common->leave = NULL;
common->accept = NULL;
altfallback.cc = ccbegin;
cc += GET(cc, 1);
@@ -6722,13 +6754,21 @@

   compile_hotpath(common, altfallback.cc, cc, &altfallback);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+    {
+    common->leavelabel = save_leavelabel;
+    common->leave = save_leave;
     return;
+    }


add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));

   compile_fallbackpath(common, altfallback.top);
   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+    {
+    common->leavelabel = save_leavelabel;
+    common->leave = save_leave;
     return;
+    }
   set_jumps(altfallback.topfallbacks, LABEL());


if (*cc != OP_ALT)
@@ -6738,6 +6778,9 @@
cc += GET(cc, 1);
}
/* None of them matched. */
+if (common->leave != NULL)
+ set_jumps(common->leave, LABEL());
+
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
jump = JUMP(SLJIT_JUMP);

@@ -6758,6 +6801,9 @@
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
+
+common->leavelabel = save_leavelabel;
+common->leave = save_leave;
}

#undef COMPILE_FALLBACKPATH
@@ -6776,7 +6822,6 @@
executable_functions *functions;
void *executable_func;
sljit_uw executable_size;
-struct sljit_label *leave;
struct sljit_label *mainloop = NULL;
struct sljit_label *empty_match_found;
struct sljit_label *empty_match_fallback;
@@ -6967,14 +7012,16 @@

/* This means we have a match. Update the ovector. */
copy_ovector(common, re->top_bracket + 1);
-leave = LABEL();
+common->leavelabel = LABEL();
+if (common->leave != NULL)
+ set_jumps(common->leave, common->leavelabel);
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);

if (mode != JIT_COMPILE)
{
common->partialmatchlabel = LABEL();
set_jumps(common->partialmatch, common->partialmatchlabel);
- return_with_partial_match(common, leave);
+ return_with_partial_match(common, common->leavelabel);
}

empty_match_fallback = LABEL();
@@ -7038,7 +7085,7 @@
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);

OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
-JUMPTO(SLJIT_JUMP, leave);
+JUMPTO(SLJIT_JUMP, common->leavelabel);

flush_stubs(common);

@@ -7091,12 +7138,12 @@
JUMPHERE(jump);
/* We break the return address cache here, but this is a really rare case. */
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
-JUMPTO(SLJIT_JUMP, leave);
+JUMPTO(SLJIT_JUMP, common->leavelabel);

/* Call limit reached. */
set_jumps(common->calllimit, LABEL());
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
-JUMPTO(SLJIT_JUMP, leave);
+JUMPTO(SLJIT_JUMP, common->leavelabel);

if (common->revertframes != NULL)
{
@@ -7203,11 +7250,10 @@
}

 int
-PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,
-  const pcre_uchar *subject, int length, int start_offset, int options,
-  int match_limit, int *offsets, int offsetcount, pcre_uchar **mark_ptr)
+PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
+  int length, int start_offset, int options, int *offsets, int offsetcount)
 {
-executable_functions *functions = (executable_functions *)executable_funcs;
+executable_functions *functions = (executable_functions *)extra_data->executable_jit;
 union {
    void* executable_func;
    jit_function call_executable_func;
@@ -7232,7 +7278,7 @@
 arguments.end = subject + length;
 arguments.mark_ptr = NULL;
 /* JIT decreases this value less frequently than the interpreter. */
-arguments.calllimit = match_limit;
+arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
 arguments.notbol = (options & PCRE_NOTBOL) != 0;
 arguments.noteol = (options & PCRE_NOTEOL) != 0;
 arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
@@ -7267,8 +7313,8 @@


if (retval * 2 > offsetcount)
retval = 0;
-if (mark_ptr != NULL)
- *mark_ptr = arguments.mark_ptr;
+if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = arguments.mark_ptr;

return retval;
}

Modified: code/trunk/pcre_jit_test.c
===================================================================
--- code/trunk/pcre_jit_test.c    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/pcre_jit_test.c    2012-02-28 11:33:34 UTC (rev 941)
@@ -679,6 +679,13 @@
     { MUA, 0, "(a\\K(*:aa)){0}(?:b(?1)b)+", "babba" },
     { MUA, 0 | F_NOMATCH, "(a\\K(*:aa)){0}(?:b(?1)b)+", "ba" },


+    /* (*COMMIT) verb. */
+    { MUA, 0 | F_NOMATCH, "a(*COMMIT)b", "ac" },
+    { MUA, 0, "aa(*COMMIT)b", "xaxaab" },
+    { MUA, 0 | F_NOMATCH, "a(*COMMIT)(*:msg)b|ac", "ac" },
+    { MUA, 0, "(?=a(*COMMIT)b|ac)ac|(*:m)(a)c", "ac" },
+    { MUA, 0, "(?!a(*COMMIT)(*:msg)b)a(c)|cd", "acd" },
+
     /* Deep recursion. */
     { MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " },
     { MUA, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " },


Modified: code/trunk/testdata/testinput12
===================================================================
--- code/trunk/testdata/testinput12    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/testdata/testinput12    2012-02-28 11:33:34 UTC (rev 941)
@@ -4,7 +4,7 @@


/abc/S+I

-/ab(*COMMIT)/S+I
+/ab(*THEN)/S+I

/abc/S+I>testsavedregex


Modified: code/trunk/testdata/testoutput12
===================================================================
--- code/trunk/testdata/testoutput12    2012-02-28 10:30:51 UTC (rev 940)
+++ code/trunk/testdata/testoutput12    2012-02-28 11:33:34 UTC (rev 941)
@@ -11,7 +11,7 @@
 No set of starting bytes
 JIT study was successful


-/ab(*COMMIT)/S+I
+/ab(*THEN)/S+I
Capturing subpattern count = 0
No options
First char = 'a'