/[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 688 by ph10, Fri Sep 9 09:35:48 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 119  The generated code will be the following Line 122  The generated code will be the following
122   jump to D hot path   jump to D hot path
123   C fallback path   C fallback path
124   A fallback path   A fallback path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of fallback code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# 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 170  typedef struct jump_list { Line 174  typedef struct jump_list {
174    struct jump_list *next;    struct jump_list *next;
175  } jump_list;  } jump_list;
176    
177  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
178    
179  typedef struct stub_list {  typedef struct stub_list {
180    enum stub_types type;    enum stub_types type;
# 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 328  typedef struct compare_context { Line 335  typedef struct compare_context {
335    
336  enum {  enum {
337    frame_end = 0,    frame_end = 0,
338    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
339  };  };
340    
341  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
# Line 343  enum { Line 349  enum {
349  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
350  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
351  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
352  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
353  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
354    
355  /* Locals layout. */  /* Locals layout. */
# Line 353  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))
 /* Number of recursions. */  
 #define CALL_COUNT       (6 * 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 405  cc += 1 + LINK_SIZE; Line 407  cc += 1 + LINK_SIZE;
407  return cc;  return cc;
408  }  }
409    
410  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
411   next_opcode   next_opcode
412   get_localspace   get_localspace
413   set_localptrs   set_localptrs
# Line 472  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 550  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 574  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 612  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 657  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 696  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;  
 BOOL needs_maxindex = 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))
718    {    {
719    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
720    possessive = TRUE;    possessive = TRUE;
721    }    }
722    
# Line 725  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:
741      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
742      length += 3;      length += 3;
743      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + 2;
744      break;      break;
# Line 767  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);
 BOOL needs_maxindex = FALSE;  
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 815  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:
795      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);  
       stackpos += (int)sizeof(sljit_w);  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
796      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
797      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
798      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 855  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 872  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 974  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 1170  while (list_item) Line 1130  while (list_item)
1130      case stack_alloc:      case stack_alloc:
1131      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1132      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1133      }      }
1134    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1135    list_item = list_item->next;    list_item = list_item->next;
# Line 1185  static SLJIT_INLINE void decrease_call_c Line 1141  static SLJIT_INLINE void decrease_call_c
1141  {  {
1142  DEFINE_COMPILER;  DEFINE_COMPILER;
1143    
1144  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1145  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1146  }  }
1147    
# Line 1218  struct sljit_label *loop; Line 1174  struct sljit_label *loop;
1174  int i;  int i;
1175  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1176  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  
1177  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);
1178  if (length < 8)  if (length < 8)
1179    {    {
# Line 1236  else Line 1191  else
1191    }    }
1192  }  }
1193    
1194  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1195  {  {
1196  DEFINE_COMPILER;  DEFINE_COMPILER;
1197  struct sljit_label *loop;  struct sljit_label *loop;
1198  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1199    
1200  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1201    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1202    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1203    
1204  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1205  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1206  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
# Line 1258  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP Line 1216  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP
1216  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1217  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1218  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1219    
1220    /* Calculate the return value, which is the maximum ovector value. */
1221    if (topbracket > 1)
1222      {
1223      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1224      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1225    
1226      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1227      loop = LABEL();
1228      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);
1230      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);
1232      }
1233    else
1234      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1235  }  }
1236    
1237  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)
# Line 1378  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 1400  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 1425  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 1486  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 1569  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 1595  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 1640  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 1710  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 1772  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 1888  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 1899  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 1971  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 1992  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);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
1971  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
1972  /* Set max index. */  /* Set string begin. */
1973  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
1974  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
1975  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
# Line 2027  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 2384  do Line 2346  do
2346        }        }
2347      context->byteptr = 0;      context->byteptr = 0;
2348      }      }
2349    
2350  #else  #else
2351    
2352    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
# Line 2446  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 2841  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 3095  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 3232  do Line 3207  do
3207        else if (cc[1] >= 0xc0)        else if (cc[1] >= 0xc0)
3208          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += _pcre_utf8_table4[cc[1] & 0x3f];
3209        }        }
3210      else      else
3211  #endif  #endif
3212      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3213        size = 0;        size = 0;
# Line 3642  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 3673  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 3707  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 3718  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 3729  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 3753  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 3800  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 3811  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 3836  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 3845  return cc + 1 + LINK_SIZE; Line 3922  return cc + 1 + LINK_SIZE;
3922      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
3923          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
3924      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.
3925      C - Push the previous OVECTOR(i), OVECTOR(i+1), MAX_INDEX and OVECTOR_PRIV(i) to the stack.      C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
3926      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
3927     () - opional values stored on the stack     () - opional values stored on the stack
3928    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3883  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 3919  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 3930  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 3941  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 4072  if (opcode == OP_ONCE) Line 4171  if (opcode == OP_ONCE)
4171  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4172    {    {
4173    /* Saving the previous values. */    /* Saving the previous values. */
4174    allocate_stack(common, 4);    allocate_stack(common, 3);
4175    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4176    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4177    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4178    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4179    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4180    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4181    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4182    }    }
4183  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4184    {    {
# Line 4100  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;
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;      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 4143  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 4291  framesize = get_framesize(common, cc, FA Line 4457  framesize = get_framesize(common, cc, FA
4457  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4458  if (framesize < 0)  if (framesize < 0)
4459    {    {
4460    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4461    if (!zero)    if (!zero)
4462      stacksize++;      stacksize++;
4463    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4304  if (framesize < 0) Line 4470  if (framesize < 0)
4470      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4471      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4472      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4473      }      }
4474    else    else
4475      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 4362  while (*cc != OP_KETRPOS) Line 4527  while (*cc != OP_KETRPOS)
4527        {        {
4528        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4529        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);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4530        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4531          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4532        }        }
4533      else      else
4534        {        {
# Line 4383  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);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
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);
4555        }        }
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 4402  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 4430  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 4769  return cc + 1; Line 4932  return cc + 1;
4932  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)
4933  {  {
4934  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
4935  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
4936    
4937  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
# Line 4778  if (common->currententry != NULL) Line 4940  if (common->currententry != NULL)
4940    
4941  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
4942  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
4943  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);
4944  offset = (offset >> 1) + 1;  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
 jump = CMP(SLJIT_C_GREATER_EQUAL, MAX_INDEX, 0, SLJIT_IMM, offset);  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, offset);  
 JUMPHERE(jump);  
4945  return cc + 3;  return cc + 3;
4946  }  }
4947    
# Line 4808  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 4967  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 5197  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 5243  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 5283  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 5298  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 5344  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 5353  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 5384  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 5417  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 5452  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 5529  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 5550  if (offset != 0) Line 5720  if (offset != 0)
5720    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5721    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5722    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
5723    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(3));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
5724    OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2));    free_stack(common, 3);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);  
   free_stack(common, 4);  
5725    }    }
5726  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5727    {    {
# Line 5567  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 5642  if (CURRENT_AS(bracketpos_fallback)->fra Line 5806  if (CURRENT_AS(bracketpos_fallback)->fra
5806      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5807      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5808      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
5809      }      }
5810    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5811    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5656  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 5793  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 5864  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 5904  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 5913  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 5939  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 5969  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: common->newline = NEWLINE; break;   /* Compile-time default */    case 0:
6131      /* Compile-time default */
6132      switch (NEWLINE)
6133        {
6134        case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6135        case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6136        default: common->newline = NEWLINE; break;
6137        }
6138      break;
6139    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
6140    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
6141    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
# Line 5992  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 6047  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 6074  if ((re->options & PCRE_ANCHORED) == 0) Line 6242  if ((re->options & PCRE_ANCHORED) == 0)
6242  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6243    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);
6244    
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  
6245  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6246  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6247  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6248  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, TMP1, 0);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6249    
6250  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6251  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6096  if (common->accept != NULL) Line 6263  if (common->accept != NULL)
6263    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->acceptlabel);
6264    
6265  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6266  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  copy_ovector(common, re->top_bracket + 1);
   
6267  leave = LABEL();  leave = LABEL();
 copy_ovector(common);  
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0);  
6268  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6269    
6270  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6149  if (reqbyte_notfound != NULL) Line 6313  if (reqbyte_notfound != NULL)
6313    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6314  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6315  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6316  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6317  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6318    
6319  flush_stubs(common);  flush_stubs(common);
# Line 6202  sljit_emit_fast_return(compiler, SLJIT_M Line 6366  sljit_emit_fast_return(compiler, SLJIT_M
6366  /* Allocation failed. */  /* Allocation failed. */
6367  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6368  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
6369  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6370  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6371    
6372  /* Call limit reached. */  /* Call limit reached. */
6373  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
6374  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6375  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6376    
6377  if (common->revertframes != NULL)  if (common->revertframes != NULL)
# Line 6267  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 6281  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 6369  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  {  {
# Line 6392  pcre_assign_jit_stack(pcre_extra *extra, Line 6564  pcre_assign_jit_stack(pcre_extra *extra,
6564  {  {
6565  executable_function *function;  executable_function *function;
6566  if (extra != NULL &&  if (extra != NULL &&
6567      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6568      extra->executable_jit != NULL)      extra->executable_jit != NULL)
6569    {    {
6570    function = (executable_function*)extra->executable_jit;    function = (executable_function*)extra->executable_jit;
# Line 6403  if (extra != NULL && Line 6575  if (extra != NULL &&
6575    
6576  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
6577    
6578  /* These are dummy functions to avoid linking errors when JIT support is not  /* These are dummy functions to avoid linking errors when JIT support is not
6579  being compiled. */  being compiled. */
6580    
6581  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *

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

  ViewVC Help
Powered by ViewVC 1.1.5