/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 696 by zherczeg, Sun Sep 18 15:09:49 2011 UTC revision 792 by ph10, Wed Dec 7 16:44:48 2011 UTC
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (pcre_malloc)(size)
56    #define SLJIT_FREE(ptr) (pcre_free)(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
# Line 163  typedef struct executable_function { Line 166  typedef struct executable_function {
166    void *executable_func;    void *executable_func;
167    pcre_jit_callback callback;    pcre_jit_callback callback;
168    void *userdata;    void *userdata;
169      sljit_uw executable_size;
170  } executable_function;  } executable_function;
171    
172  typedef struct jump_list {  typedef struct jump_list {
# Line 276  typedef struct compiler_common { Line 280  typedef struct compiler_common {
280    int bsr_nltype;    int bsr_nltype;
281    int endonly;    int endonly;
282    sljit_w ctypes;    sljit_w ctypes;
283      sljit_uw name_table;
284      sljit_w name_count;
285      sljit_w name_entry_size;
286    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
287    stub_list *stubs;    stub_list *stubs;
288    recurse_entry *entries;    recurse_entry *entries;
# Line 352  enum { Line 359  enum {
359  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
360  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
361  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
362  /* Head of the last recursion. */  /* Head of the last recursion. */
363  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
364  /* Max limit of recursions. */  /* Max limit of recursions. */
365  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
366  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
367  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
368  /* End pointer of the first line. */  /* End pointer of the first line. */
369  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
370  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
371  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
372  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
373  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
374  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
375  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
376  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
377  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 469  switch(*cc) Line 474  switch(*cc)
474    case OP_SKIPZERO:    case OP_SKIPZERO:
475    return cc + 1;    return cc + 1;
476    
477      case OP_ANYBYTE:
478    #ifdef SUPPORT_UTF8
479      if (common->utf8) return NULL;
480    #endif
481      return cc + 1;
482    
483    case OP_CHAR:    case OP_CHAR:
484    case OP_CHARI:    case OP_CHARI:
485    case OP_NOT:    case OP_NOT:
# Line 547  switch(*cc) Line 558  switch(*cc)
558    case OP_REF:    case OP_REF:
559    case OP_REFI:    case OP_REFI:
560    case OP_CREF:    case OP_CREF:
561      case OP_NCREF:
562      case OP_RREF:
563      case OP_NRREF:
564    case OP_CLOSE:    case OP_CLOSE:
565    cc += 3;    cc += 3;
566    return cc;    return cc;
# Line 571  switch(*cc) Line 585  switch(*cc)
585    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
586    case OP_REVERSE:    case OP_REVERSE:
587    case OP_ONCE:    case OP_ONCE:
588      case OP_ONCE_NC:
589    case OP_BRA:    case OP_BRA:
590    case OP_BRAPOS:    case OP_BRAPOS:
591    case OP_COND:    case OP_COND:
# Line 609  while (cc < ccend) Line 624  while (cc < ccend)
624      case OP_ASSERTBACK:      case OP_ASSERTBACK:
625      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
626      case OP_ONCE:      case OP_ONCE:
627        case OP_ONCE_NC:
628      case OP_BRAPOS:      case OP_BRAPOS:
629      case OP_SBRA:      case OP_SBRA:
630      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 654  while (cc < ccend) Line 670  while (cc < ccend)
670      case OP_ASSERTBACK:      case OP_ASSERTBACK:
671      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
672      case OP_ONCE:      case OP_ONCE:
673        case OP_ONCE_NC:
674      case OP_BRAPOS:      case OP_BRAPOS:
675      case OP_SBRA:      case OP_SBRA:
676      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 693  while (cc < ccend) Line 710  while (cc < ccend)
710  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)
711  {  {
712  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 uschar *end;  
713  int length = 0;  int length = 0;
714  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
715  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
716    
717  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
# Line 720  while (cc < ccend) Line 735  while (cc < ccend)
735      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
736      break;      break;
737    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
       {  
       cc = bracketend(cc);  
       break;  
       }  
     /* Check whether a frame must be created. */  
     end = bracketend(cc);  
     while (cc < end)  
       {  
       if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS  
           || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)  
         needs_frame = TRUE;  
       cc = next_opcode(common, cc);  
       SLJIT_ASSERT(cc != NULL);  
       }  
     break;  
   
738      case OP_CBRA:      case OP_CBRA:
739      case OP_CBRAPOS:      case OP_CBRAPOS:
740      case OP_SCBRA:      case OP_SCBRA:
# Line 757  while (cc < ccend) Line 750  while (cc < ccend)
750      }      }
751    
752  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
753  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
754    return -1;    return -1;
755    
756  if (length > 0)  if (length > 0)
757    return length + 2;    return length + 1;
758  return needs_frame ? 0 : -1;  return -1;
759  }  }
760    
761  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)
762  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
763  DEFINE_COMPILER;  DEFINE_COMPILER;
764  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
765  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
766  int offset;  int offset;
767    
768  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
769    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
770    
771  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacktop), TMP1, 0);  
   
772  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
773    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
774  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 804  while (cc < ccend) Line 789  while (cc < ccend)
789      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
790      break;      break;
791    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
792      case OP_CBRA:      case OP_CBRA:
793      case OP_CBRAPOS:      case OP_CBRAPOS:
794      case OP_SCBRA:      case OP_SCBRA:
# Line 836  while (cc < ccend) Line 813  while (cc < ccend)
813      }      }
814    
815  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
816  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
817  }  }
818    
819  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)
# Line 853  while (cc < ccend) Line 830  while (cc < ccend)
830      case OP_ASSERTBACK:      case OP_ASSERTBACK:
831      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
832      case OP_ONCE:      case OP_ONCE:
833        case OP_ONCE_NC:
834      case OP_BRAPOS:      case OP_BRAPOS:
835      case OP_SBRA:      case OP_SBRA:
836      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 955  while (status != end) Line 933  while (status != end)
933        case OP_ASSERTBACK:        case OP_ASSERTBACK:
934        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
935        case OP_ONCE:        case OP_ONCE:
936          case OP_ONCE_NC:
937        case OP_BRAPOS:        case OP_BRAPOS:
938        case OP_SBRA:        case OP_SBRA:
939        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1246  if (topbracket > 1) Line 1225  if (topbracket > 1)
1225    
1226    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1227    loop = LABEL();    loop = LABEL();
1228    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1229    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1230    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1231    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
# Line 1373  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1352  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1352  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1353  if (common->utf8)  if (common->utf8)
1354    {    {
1355    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);  
1356    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1357    JUMPHERE(jump);    JUMPHERE(jump);
1358    }    }
# Line 1395  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1373  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1373  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1374  if (common->utf8)  if (common->utf8)
1375    {    {
1376    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);  
1377    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1378    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1379    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1420  if (common->utf8) Line 1397  if (common->utf8)
1397    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1398    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1399    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1400    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
   jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);  
1401    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1402    JUMPHERE(jump);    JUMPHERE(jump);
1403    return;    return;
# Line 1481  else Line 1457  else
1457  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1458  {  {
1459  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1460  of the character (>= 192). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
1461  DEFINE_COMPILER;  DEFINE_COMPILER;
1462  struct sljit_jump *jump;  struct sljit_jump *jump;
1463    
# Line 1564  sljit_emit_fast_return(compiler, RETURN_ Line 1540  sljit_emit_fast_return(compiler, RETURN_
1540  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1541  {  {
1542  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1543  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1544  DEFINE_COMPILER;  DEFINE_COMPILER;
1545  struct sljit_jump *jump;  struct sljit_jump *jump;
1546  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1590  sljit_emit_fast_return(compiler, RETURN_ Line 1566  sljit_emit_fast_return(compiler, RETURN_
1566  JUMPHERE(jump);  JUMPHERE(jump);
1567    
1568  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1569  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
1570  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1571  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1572  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1635  struct sljit_label *newlinelabel = NULL; Line 1610  struct sljit_label *newlinelabel = NULL;
1610  struct sljit_jump *start;  struct sljit_jump *start;
1611  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1612  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1613    #ifdef SUPPORT_UTF8
1614    struct sljit_jump *singlebyte;
1615    #endif
1616  jump_list *newline = NULL;  jump_list *newline = NULL;
1617  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1618  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1705  if (readbyte) Line 1683  if (readbyte)
1683  if (newlinecheck)  if (newlinecheck)
1684    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
1685    
1686    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1687  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1688  if (common->utf8)  if (common->utf8)
1689    {    {
1690    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1691      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1692    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1693      JUMPHERE(singlebyte);
1694    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
1695  #endif  #endif
1696  JUMPHERE(start);  JUMPHERE(start);
1697    
# Line 1767  else Line 1744  else
1744      }      }
1745    }    }
1746    
1747    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1748  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1749  if (common->utf8)  if (common->utf8)
1750    {    {
1751    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1752      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1753    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1754    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
1755  #endif  #endif
1756  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1757  JUMPHERE(found);  JUMPHERE(found);
# Line 1883  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1858  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1858  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1859  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1860  if (common->utf8)  if (common->utf8)
1861    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1862  #endif  #endif
1863  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1864  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1894  found = JUMP(SLJIT_C_NOT_ZERO); Line 1869  found = JUMP(SLJIT_C_NOT_ZERO);
1869    
1870  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1871  if (common->utf8)  if (common->utf8)
1872    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1873  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1874  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1875    #ifdef SUPPORT_UTF8
1876    if (common->utf8)
1877      {
1878      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1879      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1880      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1881      }
1882  #endif  #endif
1883  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1884  JUMPHERE(found);  JUMPHERE(found);
# Line 1966  return notfound; Line 1946  return notfound;
1946  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1947  {  {
1948  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1949  struct sljit_jump *jump;  struct sljit_jump *jump;
1950  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1951    
1952  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1953  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1954    
1955  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1956  mainloop = LABEL();  mainloop = LABEL();
1957  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1958  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1987  JUMPTO(SLJIT_JUMP, mainloop); Line 1965  JUMPTO(SLJIT_JUMP, mainloop);
1965  JUMPHERE(jump);  JUMPHERE(jump);
1966  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1967  /* End of dropping frames. */  /* End of dropping frames. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
 CMPTO(SLJIT_C_GREATER_EQUAL, TMP1, 0, STACK_TOP, 0, mainloop);  
 JUMPHERE(earlyexit);  
1968  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1969    
1970  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2015  struct sljit_jump *beginend; Line 1989  struct sljit_jump *beginend;
1989  struct sljit_jump *jump;  struct sljit_jump *jump;
1990  #endif  #endif
1991    
1992  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
1993    
1994  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
1995  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2434  uschar *ccbegin; Line 2408  uschar *ccbegin;
2408  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2409  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2410  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2411  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2412    unsigned int typeoffset;
2413  #endif  #endif
2414  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2415    unsigned int charoffset;
2416    
2417  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */
2418  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
# Line 2829  switch(type) Line 2805  switch(type)
2805    if (common->utf8)    if (common->utf8)
2806      {      {
2807      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2808      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2809        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2810        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
2811      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2812        JUMPHERE(jump[0]);
2813      return cc;      return cc;
2814      }      }
2815  #endif  #endif
2816    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2817    return cc;    return cc;
2818    
2819      case OP_ANYBYTE:
2820      check_input_end(common, fallbacks);
2821      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2822      return cc;
2823    
2824  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2825  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2826    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3083  switch(type) Line 3067  switch(type)
3067      if (c <= 127)      if (c <= 127)
3068        {        {
3069        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
       OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
3070        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3071          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3072        else        else
3073          {          {
3074          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3075          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3076          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
3077          }          }
3078        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3079        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3080          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3081          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
3082          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3083          JUMPHERE(jump[0]);
3084        return cc + length;        return cc + length;
3085        }        }
3086      else      else
# Line 3630  while (1) Line 3617  while (1)
3617    if (common->accept != NULL)    if (common->accept != NULL)
3618      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3619    
3620      /* Reset stack. */
3621    if (framesize < 0)    if (framesize < 0)
3622      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3623      else {
3624        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3625          {
3626          /* We don't need to keep the STR_PTR, only the previous localptr. */
3627          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3628          }
3629        else
3630          {
3631          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3632          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3633          }
3634      }
3635    
3636    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3637      {      {
3638      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
3639      if (conditional)      if (conditional)
3640        {        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
       if (framesize < 0)  
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);  
       else  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
         }  
       }  
3641      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3642        {        {
3643        if (framesize < 0)        if (framesize < 0)
3644          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3645        else        else
3646          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3647          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
3648          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
3649          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3661  while (1) Line 3651  while (1)
3651        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3652        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3653        }        }
3654      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3655        {        {
3656        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3657          {        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));  
         }  
3658        }        }
3659      }      }
3660    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3695  if (opcode == OP_ASSERT || opcode == OP_ Line 3681  if (opcode == OP_ASSERT || opcode == OP_
3681    /* Assert is failed. */    /* Assert is failed. */
3682    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3683      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3684    
3685    if (framesize < 0)    if (framesize < 0)
3686      {      {
3687      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3706  if (opcode == OP_ASSERT || opcode == OP_ Line 3693  if (opcode == OP_ASSERT || opcode == OP_
3693    else    else
3694      {      {
3695      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
     if (framesize > 0)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
3696      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3697      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3698        {        {
# Line 3717  if (opcode == OP_ASSERT || opcode == OP_ Line 3702  if (opcode == OP_ASSERT || opcode == OP_
3702      else      else
3703        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3704      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
     if (framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
3705      }      }
3706    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3707    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3741  if (opcode == OP_ASSERT || opcode == OP_ Line 3724  if (opcode == OP_ASSERT || opcode == OP_
3724      }      }
3725    else    else
3726      {      {
3727      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      if (bra == OP_BRA)
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
     if (bra == OP_BRAZERO)  
3728        {        {
3729        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3730        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3731          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3732        }        }
3733      else if (bra == OP_BRAMINZERO)      else
3734        {        {
3735        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3736        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
3737          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3738          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3739        }        }
3740      }      }
3741    
# Line 3788  else Line 3772  else
3772      {      {
3773      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3774      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
     if (framesize > 0)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
3775      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3776      if (bra != OP_BRA)      if (bra != OP_BRA)
3777        {        {
# Line 3799  else Line 3781  else
3781      else      else
3782        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3783      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
     if (framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
3784      }      }
3785    
3786    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3824  common->accept = save_accept; Line 3804  common->accept = save_accept;
3804  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3805  }  }
3806    
3807    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, uschar *name_table)
3808    {
3809    int condition = FALSE;
3810    uschar *slotA = name_table;
3811    uschar *slotB;
3812    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3813    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3814    sljit_w no_capture;
3815    int i;
3816    
3817    locals += OVECTOR_START / sizeof(sljit_w);
3818    no_capture = locals[1];
3819    
3820    for (i = 0; i < name_count; i++)
3821      {
3822      if (GET2(slotA, 0) == refno) break;
3823      slotA += name_entry_size;
3824      }
3825    
3826    if (i < name_count)
3827      {
3828      /* Found a name for the number - there can be only one; duplicate names
3829      for different numbers are allowed, but not vice versa. First scan down
3830      for duplicates. */
3831    
3832      slotB = slotA;
3833      while (slotB > name_table)
3834        {
3835        slotB -= name_entry_size;
3836        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3837          {
3838          condition = locals[GET2(slotB, 0) << 1] != no_capture;
3839          if (condition) break;
3840          }
3841        else break;
3842        }
3843    
3844      /* Scan up for duplicates */
3845      if (!condition)
3846        {
3847        slotB = slotA;
3848        for (i++; i < name_count; i++)
3849          {
3850          slotB += name_entry_size;
3851          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3852            {
3853            condition = locals[GET2(slotB, 0) << 1] != no_capture;
3854            if (condition) break;
3855            }
3856          else break;
3857          }
3858        }
3859      }
3860    return condition;
3861    }
3862    
3863    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table)
3864    {
3865    int condition = FALSE;
3866    uschar *slotA = name_table;
3867    uschar *slotB;
3868    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3869    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3870    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
3871    int i;
3872    
3873    for (i = 0; i < name_count; i++)
3874      {
3875      if (GET2(slotA, 0) == recno) break;
3876      slotA += name_entry_size;
3877      }
3878    
3879    if (i < name_count)
3880      {
3881      /* Found a name for the number - there can be only one; duplicate
3882      names for different numbers are allowed, but not vice versa. First
3883      scan down for duplicates. */
3884    
3885      slotB = slotA;
3886      while (slotB > name_table)
3887        {
3888        slotB -= name_entry_size;
3889        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3890          {
3891          condition = GET2(slotB, 0) == group_num;
3892          if (condition) break;
3893          }
3894        else break;
3895        }
3896    
3897      /* Scan up for duplicates */
3898      if (!condition)
3899        {
3900        slotB = slotA;
3901        for (i++; i < name_count; i++)
3902          {
3903          slotB += name_entry_size;
3904          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3905            {
3906            condition = GET2(slotB, 0) == group_num;
3907            if (condition) break;
3908            }
3909          else break;
3910          }
3911        }
3912      }
3913    return condition;
3914    }
3915    
3916  /*  /*
3917    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
3918    
# Line 3871  return cc + 1 + LINK_SIZE; Line 3960  return cc + 1 + LINK_SIZE;
3960      M - Any values pushed by the current alternative. Can be empty, or anything.      M - Any values pushed by the current alternative. Can be empty, or anything.
3961    
3962    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3963    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3964    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3965    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3966                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3967                                              Or nothing, if trace is unnecessary
3968  */  */
3969    
3970  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)
# Line 3907  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3997  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3997    
3998  opcode = *cc;  opcode = *cc;
3999  ccbegin = cc;  ccbegin = cc;
4000    hotpath = ccbegin + 1 + LINK_SIZE;
4001    
4002  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
4003    {    {
4004    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3918  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4010  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4010  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4011  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
4012  cc += GET(cc, 1);  cc += GET(cc, 1);
4013  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4014    has_alternatives = *cc == OP_ALT;
4015    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4016      {
4017      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4018      if (*hotpath == OP_NRREF)
4019        {
4020        stacksize = GET2(hotpath, 1);
4021        if (common->currententry == NULL || stacksize == RREF_ANY)
4022          has_alternatives = FALSE;
4023        else if (common->currententry->start == 0)
4024          has_alternatives = stacksize != 0;
4025        else
4026          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4027        }
4028      }
4029    
4030  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4031    opcode = OP_SCOND;    opcode = OP_SCOND;
4032    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4033      opcode = OP_ONCE;
4034    
4035  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4036    {    {
# Line 3929  if (opcode == OP_CBRA || opcode == OP_SC Line 4039  if (opcode == OP_CBRA || opcode == OP_SC
4039    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4040    offset <<= 1;    offset <<= 1;
4041    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4042      hotpath += 2;
4043    }    }
4044  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4045    {    {
# Line 4085  else if (has_alternatives) Line 4196  else if (has_alternatives)
4196    }    }
4197    
4198  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4199  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4200    {    {
4201    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4202      {      {
4203        SLJIT_ASSERT(has_alternatives);
4204      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4205        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR((GET2(hotpath, 1) << 1)), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4206      hotpath += 3;      hotpath += 3;
4207      }      }
4208      else if (*hotpath == OP_NCREF)
4209        {
4210        SLJIT_ASSERT(has_alternatives);
4211        stacksize = GET2(hotpath, 1);
4212        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4213    
4214        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4215        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4216        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4217        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4218        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4219        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4220        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4221        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4222        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4223    
4224        JUMPHERE(jump);
4225        hotpath += 3;
4226        }
4227      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4228        {
4229        /* Never has other case. */
4230        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4231    
4232        stacksize = GET2(hotpath, 1);
4233        if (common->currententry == NULL)
4234          stacksize = 0;
4235        else if (stacksize == RREF_ANY)
4236          stacksize = 1;
4237        else if (common->currententry->start == 0)
4238          stacksize = stacksize == 0;
4239        else
4240          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4241    
4242        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4243          {
4244          SLJIT_ASSERT(!has_alternatives);
4245          if (stacksize != 0)
4246            hotpath += 3;
4247          else
4248            {
4249            if (*cc == OP_ALT)
4250              {
4251              hotpath = cc + 1 + LINK_SIZE;
4252              cc += GET(cc, 1);
4253              }
4254            else
4255              hotpath = cc;
4256            }
4257          }
4258        else
4259          {
4260          SLJIT_ASSERT(has_alternatives);
4261    
4262          stacksize = GET2(hotpath, 1);
4263          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4264          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4265          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4266          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4267          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4268          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4269          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4270          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4271          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4272          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4273          hotpath += 3;
4274          }
4275        }
4276    else    else
4277      {      {
4278      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4279      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4280      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4281      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4128  if (opcode == OP_ONCE) Line 4305  if (opcode == OP_ONCE)
4305        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
4306        }        }
4307      }      }
4308    else if (ket == OP_KETRMAX)    else
4309      {      {
4310      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4311      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
4312      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4313          {
4314          /* TMP2 which is set here used by OP_KETRMAX below. */
4315          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4316          }
4317      }      }
4318    }    }
4319    
# Line 4366  while (*cc != OP_KETRPOS) Line 4547  while (*cc != OP_KETRPOS)
4547      {      {
4548      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4549        {        {
4550          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4551        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4552        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4553        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4554        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
# Line 4376  while (*cc != OP_KETRPOS) Line 4556  while (*cc != OP_KETRPOS)
4556      else      else
4557        {        {
4558        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4559          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4560        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4561          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
4562        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
# Line 4384  while (*cc != OP_KETRPOS) Line 4565  while (*cc != OP_KETRPOS)
4565      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4566        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
4567    
     /* TMP2 must be set above. */  
4568      if (!zero)      if (!zero)
4569        {        {
4570        if (framesize < 0)        if (framesize < 0)
4571          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
4572        else        else
4573          OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4574        }        }
4575      }      }
4576    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4412  while (*cc != OP_KETRPOS) Line 4592  while (*cc != OP_KETRPOS)
4592      {      {
4593      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4594        {        {
4595          /* Last alternative. */
4596        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4597          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4598        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
# Line 4785  while (cc < ccend) Line 4966  while (cc < ccend)
4966      case OP_WORDCHAR:      case OP_WORDCHAR:
4967      case OP_ANY:      case OP_ANY:
4968      case OP_ALLANY:      case OP_ALLANY:
4969        case OP_ANYBYTE:
4970      case OP_NOTPROP:      case OP_NOTPROP:
4971      case OP_PROP:      case OP_PROP:
4972      case OP_ANYNL:      case OP_ANYNL:
# Line 4944  while (cc < ccend) Line 5126  while (cc < ccend)
5126      break;      break;
5127    
5128      case OP_ONCE:      case OP_ONCE:
5129        case OP_ONCE_NC:
5130      case OP_BRA:      case OP_BRA:
5131      case OP_CBRA:      case OP_CBRA:
5132      case OP_COND:      case OP_COND:
# Line 5174  static void compile_assert_fallbackpath( Line 5357  static void compile_assert_fallbackpath(
5357  DEFINE_COMPILER;  DEFINE_COMPILER;
5358  uschar *cc = current->cc;  uschar *cc = current->cc;
5359  uschar bra = OP_BRA;  uschar bra = OP_BRA;
 struct sljit_jump *jump;  
5360  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5361    
5362  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5220  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5402  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5402    {    {
5403    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);
5404    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5405      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));
5406    
5407    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5408    }    }
5409  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5410    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);  
   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
   JUMPHERE(jump);  
   }  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));  
5411    
5412  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5413    {    {
# Line 5260  jump_list *jumplistitem = NULL; Line 5435  jump_list *jumplistitem = NULL;
5435  uschar bra = OP_BRA;  uschar bra = OP_BRA;
5436  uschar ket;  uschar ket;
5437  assert_fallback *assert;  assert_fallback *assert;
5438    BOOL has_alternatives;
5439  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5440  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5441  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5275  opcode = *cc; Line 5451  opcode = *cc;
5451  ccbegin = cc;  ccbegin = cc;
5452  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5453  cc += GET(cc, 1);  cc += GET(cc, 1);
5454    has_alternatives = *cc == OP_ALT;
5455    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5456      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5457  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5458    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5459  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5460    opcode = OP_SCOND;    opcode = OP_SCOND;
5461    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5462      opcode = OP_ONCE;
5463    
5464  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5465    {    {
# Line 5321  else if (bra == OP_BRAZERO) Line 5502  else if (bra == OP_BRAZERO)
5502    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5503    }    }
5504    
5505  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5506    {    {
5507    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5508      {      {
# Line 5330  if (opcode == OP_ONCE) Line 5511  if (opcode == OP_ONCE)
5511      }      }
5512    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5513    }    }
5514    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5515      {
5516      if (has_alternatives)
5517        {
5518        /* Always exactly one alternative. */
5519        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5520        free_stack(common, 1);
5521    
5522        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5523        if (SLJIT_UNLIKELY(!jumplistitem))
5524          return;
5525        jumplist = jumplistitem;
5526        jumplistitem->next = NULL;
5527        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5528        }
5529      }
5530  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5531    {    {
5532    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5361  else if (*cc == OP_ALT) Line 5558  else if (*cc == OP_ALT)
5558    
5559    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5560    }    }
 else if (opcode == OP_COND || opcode == OP_SCOND)  
   {  
   /* Always one. */  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
   free_stack(common, 1);  
   
   jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));  
   if (SLJIT_UNLIKELY(!jumplistitem))  
     return;  
   jumplist = jumplistitem;  
   jumplistitem->next = NULL;  
   jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);  
   }  
5561    
5562  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5563  if (current->topfallbacks)  if (current->topfallbacks)
5564    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5565    
5566  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5567    {    {
5568    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5569    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
5570      {      {
5571        SLJIT_ASSERT(has_alternatives);
5572      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5573      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
5574        {        {
# Line 5394  if (opcode == OP_COND || opcode == OP_SC Line 5579  if (opcode == OP_COND || opcode == OP_SC
5579      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5580      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5581      }      }
5582    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5583      {      {
5584        SLJIT_ASSERT(has_alternatives);
5585      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5586      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5587      }      }
5588      else
5589        SLJIT_ASSERT(!has_alternatives);
5590    }    }
5591    
5592  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5593    {    {
5594    count = 1;    count = 1;
5595    do    do
# Line 5429  if (*cc == OP_ALT || opcode == OP_COND | Line 5617  if (*cc == OP_ALT || opcode == OP_COND |
5617      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5618      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5619        {        {
5620        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5621          {          {
5622            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5623            /* TMP2 which is set here used by OP_KETRMAX below. */
5624          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5625              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5626            else if (ket == OP_KETRMIN)
5627            {            {
5628            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5629            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
5630            }            }
5631          }          }
5632        else        else
5633          {          {
5634          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));
         /* The register which is set here used by OP_KETRMAX below. */  
5635          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5636            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5637          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5638            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5639              }
5640          }          }
5641        }        }
5642    
# Line 5506  if (*cc == OP_ALT || opcode == OP_COND | Line 5698  if (*cc == OP_ALT || opcode == OP_COND |
5698      {      {
5699      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
5700      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5701      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT))      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
5702    
5703        {        {
5704        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
5705        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5542  else if (opcode == OP_ONCE) Line 5735  else if (opcode == OP_ONCE)
5735      {      {
5736      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5737      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
     if (CURRENT_AS(bracket_fallback)->u.framesize > 0)  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(stacksize));  
5738      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);
     if (CURRENT_AS(bracket_fallback)->u.framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
5739      }      }
5740    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5741      {      {
# Line 5630  if (current->topfallbacks) Line 5819  if (current->topfallbacks)
5819    {    {
5820    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5821    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5822    /* Drop the stack frame and restore LOCALS_HEAD. */    /* Drop the stack frame. */
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(CURRENT_AS(bracketpos_fallback)->stacksize - CURRENT_AS(bracketpos_fallback)->framesize));  
5823    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
5824    JUMPHERE(jump);    JUMPHERE(jump);
5825    }    }
5826  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));
# Line 5767  while (current) Line 5954  while (current)
5954      break;      break;
5955    
5956      case OP_ONCE:      case OP_ONCE:
5957        case OP_ONCE_NC:
5958      case OP_BRA:      case OP_BRA:
5959      case OP_CBRA:      case OP_CBRA:
5960      case OP_COND:      case OP_COND:
# Line 5838  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 6026  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
6026  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6027  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);
6028  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
6029    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
6030    
6031  if (alternativesize > 0)  if (alternativesize > 0)
6032    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 5878  while (1) Line 6063  while (1)
6063    }    }
6064  /* None of them matched. */  /* None of them matched. */
6065  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
 if (needsframe)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, SLJIT_MEM1(STACK_TOP), STACK(alternativesize));  
6066  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6067    
6068  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5887  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6070  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6070  if (needsframe)  if (needsframe)
6071    {    {
6072    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6073    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (localsize + framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6074    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6075    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (localsize + framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6076    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
6077    }    }
6078  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 5913  struct sljit_compiler *compiler; Line 6096  struct sljit_compiler *compiler;
6096  fallback_common rootfallback;  fallback_common rootfallback;
6097  compiler_common common_data;  compiler_common common_data;
6098  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6099  const unsigned char *tables = re->tables;  const uschar *tables = re->tables;
6100  pcre_study_data *study;  pcre_study_data *study;
6101  uschar *ccend;  uschar *ccend;
6102  executable_function *function;  executable_function *function;
6103  void *executable_func;  void *executable_func;
6104    sljit_uw executable_size;
6105  struct sljit_label *leave;  struct sljit_label *leave;
6106  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6107  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
# Line 5943  common->lcc = (sljit_w)(tables + lcc_off Line 6127  common->lcc = (sljit_w)(tables + lcc_off
6127  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6128  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6129    {    {
6130    case 0:    case 0:
6131    /* Compile-time default */    /* Compile-time default */
6132    switch (NEWLINE)    switch (NEWLINE)
6133      {      {
# Line 5974  else Line 6158  else
6158    }    }
6159  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6160  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6161    common->name_table = (sljit_w)re + re->name_table_offset;
6162    common->name_count = re->name_count;
6163    common->name_entry_size = re->name_entry_size;
6164  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6165  common->stubs = NULL;  common->stubs = NULL;
6166  common->entries = NULL;  common->entries = NULL;
# Line 6029  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6216  sljit_emit_enter(compiler, 1, 5, 5, comm
6216  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6217  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6218    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, SLJIT_IMM, 0);  
6219    
6220  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
6221  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);
# Line 6245  if (common->getucd != NULL) Line 6431  if (common->getucd != NULL)
6431    
6432  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->localptrs);
6433  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
6434    executable_size = sljit_get_generated_code_size(compiler);
6435  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
6436  if (executable_func == NULL)  if (executable_func == NULL)
6437    return;    return;
# Line 6259  if (function == NULL) Line 6446  if (function == NULL)
6446    }    }
6447    
6448  function->executable_func = executable_func;  function->executable_func = executable_func;
6449    function->executable_size = executable_size;
6450  function->callback = NULL;  function->callback = NULL;
6451  function->userdata = NULL;  function->userdata = NULL;
6452  extra->executable_jit = function;  extra->executable_jit = function;
# Line 6347  sljit_free_code(function->executable_fun Line 6535  sljit_free_code(function->executable_fun
6535  SLJIT_FREE(function);  SLJIT_FREE(function);
6536  }  }
6537    
6538    int
6539    _pcre_jit_get_size(void *executable_func)
6540    {
6541    return ((executable_function*)executable_func)->executable_size;
6542    }
6543    
6544  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
6545  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
6546  {  {

Legend:
Removed from v.696  
changed lines
  Added in v.792

  ViewVC Help
Powered by ViewVC 1.1.5