/[pcre]/code/branches/pcre16/pcre_jit_compile.c
ViewVC logotype

Diff of /code/branches/pcre16/pcre_jit_compile.c

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

revision 669 by ph10, Tue Aug 23 09:56:11 2011 UTC revision 741 by zherczeg, Mon Oct 31 09:31:46 2011 UTC
# Line 53  we just include it. This way we don't ne Line 53  we just include it. This way we don't ne
53  system files. */  system files. */
54    
55  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
56    #define SLJIT_CONFIG_STATIC 1
57  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
58  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
59    
# Line 119  The generated code will be the following Line 120  The generated code will be the following
120   jump to D hot path   jump to D hot path
121   C fallback path   C fallback path
122   A fallback path   A fallback path
123    
124   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
125   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
126   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 152  typedef struct jit_arguments { Line 153  typedef struct jit_arguments {
153    uschar *ptr;    uschar *ptr;
154    /* Everything else after. */    /* Everything else after. */
155    int offsetcount;    int offsetcount;
156      int calllimit;
157    uschar notbol;    uschar notbol;
158    uschar noteol;    uschar noteol;
159    uschar notempty;    uschar notempty;
# Line 169  typedef struct jump_list { Line 171  typedef struct jump_list {
171    struct jump_list *next;    struct jump_list *next;
172  } jump_list;  } jump_list;
173    
174  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
175    
176  typedef struct stub_list {  typedef struct stub_list {
177    enum stub_types type;    enum stub_types type;
# Line 275  typedef struct compiler_common { Line 277  typedef struct compiler_common {
277    int bsr_nltype;    int bsr_nltype;
278    int endonly;    int endonly;
279    sljit_w ctypes;    sljit_w ctypes;
280      sljit_uw name_table;
281      sljit_w name_count;
282      sljit_w name_entry_size;
283    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
284    stub_list *stubs;    stub_list *stubs;
285    recurse_entry *entries;    recurse_entry *entries;
286    recurse_entry *currententry;    recurse_entry *currententry;
287    jump_list *accept;    jump_list *accept;
288      jump_list *calllimit;
289    jump_list *stackalloc;    jump_list *stackalloc;
290    jump_list *revertframes;    jump_list *revertframes;
291    jump_list *wordboundary;    jump_list *wordboundary;
# Line 326  typedef struct compare_context { Line 332  typedef struct compare_context {
332    
333  enum {  enum {
334    frame_end = 0,    frame_end = 0,
335    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
336  };  };
337    
338  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
# Line 341  enum { Line 346  enum {
346  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
347  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
348  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
349  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
350  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
351    
352  /* Locals layout. */  /* Locals layout. */
# Line 351  enum { Line 356  enum {
356  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
357  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
358  #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))  
359  /* Head of the last recursion. */  /* Head of the last recursion. */
360  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
361    /* Max limit of recursions. */
362    #define CALL_LIMIT       (5 * sizeof(sljit_w))
363  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
364  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
365  /* End pointer of the first line. */  /* End pointer of the first line. */
# Line 399  cc += 1 + LINK_SIZE; Line 404  cc += 1 + LINK_SIZE;
404  return cc;  return cc;
405  }  }
406    
407  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
408   next_opcode   next_opcode
409   get_localspace   get_localspace
410   set_localptrs   set_localptrs
# Line 466  switch(*cc) Line 471  switch(*cc)
471    case OP_SKIPZERO:    case OP_SKIPZERO:
472    return cc + 1;    return cc + 1;
473    
474      case OP_ANYBYTE:
475    #ifdef SUPPORT_UTF8
476      if (common->utf8) return NULL;
477    #endif
478      return cc + 1;
479    
480    case OP_CHAR:    case OP_CHAR:
481    case OP_CHARI:    case OP_CHARI:
482    case OP_NOT:    case OP_NOT:
# Line 544  switch(*cc) Line 555  switch(*cc)
555    case OP_REF:    case OP_REF:
556    case OP_REFI:    case OP_REFI:
557    case OP_CREF:    case OP_CREF:
558      case OP_NCREF:
559      case OP_RREF:
560      case OP_NRREF:
561    case OP_CLOSE:    case OP_CLOSE:
562    cc += 3;    cc += 3;
563    return cc;    return cc;
# Line 568  switch(*cc) Line 582  switch(*cc)
582    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
583    case OP_REVERSE:    case OP_REVERSE:
584    case OP_ONCE:    case OP_ONCE:
585      case OP_ONCE_NC:
586    case OP_BRA:    case OP_BRA:
587    case OP_BRAPOS:    case OP_BRAPOS:
588    case OP_COND:    case OP_COND:
# Line 606  while (cc < ccend) Line 621  while (cc < ccend)
621      case OP_ASSERTBACK:      case OP_ASSERTBACK:
622      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
623      case OP_ONCE:      case OP_ONCE:
624        case OP_ONCE_NC:
625      case OP_BRAPOS:      case OP_BRAPOS:
626      case OP_SBRA:      case OP_SBRA:
627      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 651  while (cc < ccend) Line 667  while (cc < ccend)
667      case OP_ASSERTBACK:      case OP_ASSERTBACK:
668      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
669      case OP_ONCE:      case OP_ONCE:
670        case OP_ONCE_NC:
671      case OP_BRAPOS:      case OP_BRAPOS:
672      case OP_SBRA:      case OP_SBRA:
673      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 690  while (cc < ccend) Line 707  while (cc < ccend)
707  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)
708  {  {
709  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 uschar *end;  
710  int length = 0;  int length = 0;
711  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
712  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
713    
714  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
715    {    {
716    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
717    possessive = TRUE;    possessive = TRUE;
718    }    }
719    
# Line 719  while (cc < ccend) Line 732  while (cc < ccend)
732      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
733      break;      break;
734    
     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;  
   
735      case OP_CBRA:      case OP_CBRA:
736      case OP_CBRAPOS:      case OP_CBRAPOS:
737      case OP_SCBRA:      case OP_SCBRA:
738      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
739      length += 3;      length += 3;
740      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + 2;
741      break;      break;
# Line 761  while (cc < ccend) Line 747  while (cc < ccend)
747      }      }
748    
749  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
750  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
751    return -1;    return -1;
752    
753  if (length > 0)  if (length > 0)
754    return length + 2;    return length + 1;
755  return needs_frame ? 0 : -1;  return -1;
756  }  }
757    
758  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)
759  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
760  DEFINE_COMPILER;  DEFINE_COMPILER;
761  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
762  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
763  int offset;  int offset;
764    
765  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
766    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
767    
768  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);  
   
769  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
770    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
771  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 809  while (cc < ccend) Line 786  while (cc < ccend)
786      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
787      break;      break;
788    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
789      case OP_CBRA:      case OP_CBRA:
790      case OP_CBRAPOS:      case OP_CBRAPOS:
791      case OP_SCBRA:      case OP_SCBRA:
792      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;  
       }  
793      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
794      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
795      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 849  while (cc < ccend) Line 810  while (cc < ccend)
810      }      }
811    
812  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
813  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
814  }  }
815    
816  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 866  while (cc < ccend) Line 827  while (cc < ccend)
827      case OP_ASSERTBACK:      case OP_ASSERTBACK:
828      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
829      case OP_ONCE:      case OP_ONCE:
830        case OP_ONCE_NC:
831      case OP_BRAPOS:      case OP_BRAPOS:
832      case OP_SBRA:      case OP_SBRA:
833      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 968  while (status != end) Line 930  while (status != end)
930        case OP_ASSERTBACK:        case OP_ASSERTBACK:
931        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
932        case OP_ONCE:        case OP_ONCE:
933          case OP_ONCE_NC:
934        case OP_BRAPOS:        case OP_BRAPOS:
935        case OP_SBRA:        case OP_SBRA:
936        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1164  while (list_item) Line 1127  while (list_item)
1127      case stack_alloc:      case stack_alloc:
1128      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1129      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1130      }      }
1131    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1132    list_item = list_item->next;    list_item = list_item->next;
# Line 1175  while (list_item) Line 1134  while (list_item)
1134  common->stubs = NULL;  common->stubs = NULL;
1135  }  }
1136    
1137    static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1138    {
1139    DEFINE_COMPILER;
1140    
1141    OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1142    add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1143    }
1144    
1145  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1146  {  {
1147  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
# Line 1204  struct sljit_label *loop; Line 1171  struct sljit_label *loop;
1171  int i;  int i;
1172  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1173  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  
1174  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);
1175  if (length < 8)  if (length < 8)
1176    {    {
# Line 1222  else Line 1188  else
1188    }    }
1189  }  }
1190    
1191  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1192  {  {
1193  DEFINE_COMPILER;  DEFINE_COMPILER;
1194  struct sljit_label *loop;  struct sljit_label *loop;
1195  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1196    
1197  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1198    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1199    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1200    
1201  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1202  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));
1203  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 1244  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP Line 1213  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP
1213  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);
1214  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1215  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1216    
1217    /* Calculate the return value, which is the maximum ovector value. */
1218    if (topbracket > 1)
1219      {
1220      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1221      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1222    
1223      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1224      loop = LABEL();
1225      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1226      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1227      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1228      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1229      }
1230    else
1231      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1232  }  }
1233    
1234  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 1364  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1349  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1349  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1350  if (common->utf8)  if (common->utf8)
1351    {    {
1352    /* 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);  
1353    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1354    JUMPHERE(jump);    JUMPHERE(jump);
1355    }    }
# Line 1386  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1370  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1370  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1371  if (common->utf8)  if (common->utf8)
1372    {    {
1373    /* 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);  
1374    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1375    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1376    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1411  if (common->utf8) Line 1394  if (common->utf8)
1394    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1395    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1396    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1397    /* 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);  
1398    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1399    JUMPHERE(jump);    JUMPHERE(jump);
1400    return;    return;
# Line 1472  else Line 1454  else
1454  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1455  {  {
1456  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1457  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. */
1458  DEFINE_COMPILER;  DEFINE_COMPILER;
1459  struct sljit_jump *jump;  struct sljit_jump *jump;
1460    
# Line 1555  sljit_emit_fast_return(compiler, RETURN_ Line 1537  sljit_emit_fast_return(compiler, RETURN_
1537  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1538  {  {
1539  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1540  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1541  DEFINE_COMPILER;  DEFINE_COMPILER;
1542  struct sljit_jump *jump;  struct sljit_jump *jump;
1543  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1581  sljit_emit_fast_return(compiler, RETURN_ Line 1563  sljit_emit_fast_return(compiler, RETURN_
1563  JUMPHERE(jump);  JUMPHERE(jump);
1564    
1565  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1566  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);  
1567  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1568  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1569  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1626  struct sljit_label *newlinelabel = NULL; Line 1607  struct sljit_label *newlinelabel = NULL;
1607  struct sljit_jump *start;  struct sljit_jump *start;
1608  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1609  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1610    #ifdef SUPPORT_UTF8
1611    struct sljit_jump *singlebyte;
1612    #endif
1613  jump_list *newline = NULL;  jump_list *newline = NULL;
1614  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1615  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1696  if (readbyte) Line 1680  if (readbyte)
1680  if (newlinecheck)  if (newlinecheck)
1681    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);
1682    
1683    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1684  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1685  if (common->utf8)  if (common->utf8)
1686    {    {
1687    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);
1688      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1689    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1690      JUMPHERE(singlebyte);
1691    }    }
 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);  
1692  #endif  #endif
1693  JUMPHERE(start);  JUMPHERE(start);
1694    
# Line 1758  else Line 1741  else
1741      }      }
1742    }    }
1743    
1744    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1745  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1746  if (common->utf8)  if (common->utf8)
1747    {    {
1748    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);
1749      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1750    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1751    }    }
 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);  
1752  #endif  #endif
1753  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1754  JUMPHERE(found);  JUMPHERE(found);
# Line 1874  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1855  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1855  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1856  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1857  if (common->utf8)  if (common->utf8)
1858    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1859  #endif  #endif
1860  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1861  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1885  found = JUMP(SLJIT_C_NOT_ZERO); Line 1866  found = JUMP(SLJIT_C_NOT_ZERO);
1866    
1867  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1868  if (common->utf8)  if (common->utf8)
1869    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1870  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1871  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1872    #ifdef SUPPORT_UTF8
1873    if (common->utf8)
1874      {
1875      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1876      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1877      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1878      }
1879  #endif  #endif
1880  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1881  JUMPHERE(found);  JUMPHERE(found);
# Line 1957  return notfound; Line 1943  return notfound;
1943  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1944  {  {
1945  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1946  struct sljit_jump *jump;  struct sljit_jump *jump;
1947  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1948    
1949  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);
1950  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1951    
1952  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1953  mainloop = LABEL();  mainloop = LABEL();
1954  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1955  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 1978  JUMPTO(SLJIT_JUMP, mainloop); Line 1962  JUMPTO(SLJIT_JUMP, mainloop);
1962  JUMPHERE(jump);  JUMPHERE(jump);
1963  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1964  /* 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);  
1965  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1966    
1967  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);  
1968  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
1969  /* Set max index. */  /* Set string begin. */
1970  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
1971  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));
1972  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 2009  static void check_wordboundary(compiler_ Line 1982  static void check_wordboundary(compiler_
1982  {  {
1983  DEFINE_COMPILER;  DEFINE_COMPILER;
1984  struct sljit_jump *beginend;  struct sljit_jump *beginend;
1985    #ifdef SUPPORT_UTF8
1986  struct sljit_jump *jump;  struct sljit_jump *jump;
1987    #endif
1988    
1989  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
1990    
1991  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);
1992  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2368  do Line 2343  do
2343        }        }
2344      context->byteptr = 0;      context->byteptr = 0;
2345      }      }
2346    
2347  #else  #else
2348    
2349    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
# Line 2430  uschar *ccbegin; Line 2405  uschar *ccbegin;
2405  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2406  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2407  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2408  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2409    unsigned int typeoffset;
2410  #endif  #endif
2411  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2412    unsigned int charoffset;
2413    
2414  /* 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. */
2415  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
# Line 2751  DEFINE_COMPILER; Line 2728  DEFINE_COMPILER;
2728  int length;  int length;
2729  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2730  compare_context context;  compare_context context;
 struct sljit_label *label;  
2731  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
2732  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2733    struct sljit_label *label;
2734  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2735  uschar propdata[5];  uschar propdata[5];
2736  #endif  #endif
# Line 2825  switch(type) Line 2802  switch(type)
2802    if (common->utf8)    if (common->utf8)
2803      {      {
2804      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2805      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);
2806        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2807        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
2808      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2809        JUMPHERE(jump[0]);
2810      return cc;      return cc;
2811      }      }
2812  #endif  #endif
2813    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2814    return cc;    return cc;
2815    
2816      case OP_ANYBYTE:
2817      check_input_end(common, fallbacks);
2818      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2819      return cc;
2820    
2821  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2822  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2823    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3079  switch(type) Line 3064  switch(type)
3064      if (c <= 127)      if (c <= 127)
3065        {        {
3066        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);  
3067        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3068          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));
3069        else        else
3070          {          {
3071          /* 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. */
3072          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3073          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));
3074          }          }
3075        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3076        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3077          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3078          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
3079          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3080          JUMPHERE(jump[0]);
3081        return cc + length;        return cc + length;
3082        }        }
3083      else      else
# Line 3216  do Line 3204  do
3204        else if (cc[1] >= 0xc0)        else if (cc[1] >= 0xc0)
3205          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += _pcre_utf8_table4[cc[1] & 0x3f];
3206        }        }
3207      else      else
3208  #endif  #endif
3209      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)
3210        size = 0;        size = 0;
# Line 3453  if (!minimize) Line 3441  if (!minimize)
3441    
3442    JUMPHERE(zerolength);    JUMPHERE(zerolength);
3443    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3444    
3445      decrease_call_count(common);
3446    return cc;    return cc;
3447    }    }
3448    
# Line 3490  else if (max > 0) Line 3480  else if (max > 0)
3480  if (jump != NULL)  if (jump != NULL)
3481    JUMPHERE(jump);    JUMPHERE(jump);
3482  JUMPHERE(zerolength);  JUMPHERE(zerolength);
3483    
3484    decrease_call_count(common);
3485  return cc;  return cc;
3486  }  }
3487    
# Line 3622  while (1) Line 3614  while (1)
3614    if (common->accept != NULL)    if (common->accept != NULL)
3615      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3616    
3617      /* Reset stack. */
3618    if (framesize < 0)    if (framesize < 0)
3619      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3620      else {
3621        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3622          {
3623          /* We don't need to keep the STR_PTR, only the previous localptr. */
3624          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3625          }
3626        else
3627          {
3628          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3629          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3630          }
3631      }
3632    
3633    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3634      {      {
3635      /* 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. */
3636      if (conditional)      if (conditional)
3637        {        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));  
         }  
       }  
3638      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3639        {        {
3640        if (framesize < 0)        if (framesize < 0)
3641          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3642        else        else
3643          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3644          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));
3645          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));
3646          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3653  while (1) Line 3648  while (1)
3648        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));
3649        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3650        }        }
3651      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3652        {        {
3653        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3654          {        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));  
         }  
3655        }        }
3656      }      }
3657    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3687  if (opcode == OP_ASSERT || opcode == OP_ Line 3678  if (opcode == OP_ASSERT || opcode == OP_
3678    /* Assert is failed. */    /* Assert is failed. */
3679    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3680      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3681    
3682    if (framesize < 0)    if (framesize < 0)
3683      {      {
3684      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3698  if (opcode == OP_ASSERT || opcode == OP_ Line 3690  if (opcode == OP_ASSERT || opcode == OP_
3690    else    else
3691      {      {
3692      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));  
3693      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3694      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3695        {        {
# Line 3709  if (opcode == OP_ASSERT || opcode == OP_ Line 3699  if (opcode == OP_ASSERT || opcode == OP_
3699      else      else
3700        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3701      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);  
3702      }      }
3703    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3704    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3733  if (opcode == OP_ASSERT || opcode == OP_ Line 3721  if (opcode == OP_ASSERT || opcode == OP_
3721      }      }
3722    else    else
3723      {      {
3724      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)  
3725        {        {
3726        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3727        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));
3728          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3729        }        }
3730      else if (bra == OP_BRAMINZERO)      else
3731        {        {
3732        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3733        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));
3734          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3735          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3736        }        }
3737      }      }
3738    
# Line 3780  else Line 3769  else
3769      {      {
3770      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3771      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));  
3772      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3773      if (bra != OP_BRA)      if (bra != OP_BRA)
3774        {        {
# Line 3791  else Line 3778  else
3778      else      else
3779        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3780      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);  
3781      }      }
3782    
3783    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3816  common->accept = save_accept; Line 3801  common->accept = save_accept;
3801  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3802  }  }
3803    
3804    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, uschar *name_table)
3805    {
3806    int condition = FALSE;
3807    uschar *slotA = name_table;
3808    uschar *slotB;
3809    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3810    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3811    sljit_w no_capture;
3812    int i;
3813    
3814    locals += OVECTOR_START / sizeof(sljit_w);
3815    no_capture = locals[1];
3816    
3817    for (i = 0; i < name_count; i++)
3818      {
3819      if (GET2(slotA, 0) == refno) break;
3820      slotA += name_entry_size;
3821      }
3822    
3823    if (i < name_count)
3824      {
3825      /* Found a name for the number - there can be only one; duplicate names
3826      for different numbers are allowed, but not vice versa. First scan down
3827      for duplicates. */
3828    
3829      slotB = slotA;
3830      while (slotB > name_table)
3831        {
3832        slotB -= name_entry_size;
3833        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3834          {
3835          condition = locals[GET2(slotB, 0) << 1] != no_capture;
3836          if (condition) break;
3837          }
3838        else break;
3839        }
3840    
3841      /* Scan up for duplicates */
3842      if (!condition)
3843        {
3844        slotB = slotA;
3845        for (i++; i < name_count; i++)
3846          {
3847          slotB += name_entry_size;
3848          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3849            {
3850            condition = locals[GET2(slotB, 0) << 1] != no_capture;
3851            if (condition) break;
3852            }
3853          else break;
3854          }
3855        }
3856      }
3857    return condition;
3858    }
3859    
3860    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table)
3861    {
3862    int condition = FALSE;
3863    uschar *slotA = name_table;
3864    uschar *slotB;
3865    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3866    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3867    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
3868    int i;
3869    
3870    for (i = 0; i < name_count; i++)
3871      {
3872      if (GET2(slotA, 0) == recno) break;
3873      slotA += name_entry_size;
3874      }
3875    
3876    if (i < name_count)
3877      {
3878      /* Found a name for the number - there can be only one; duplicate
3879      names for different numbers are allowed, but not vice versa. First
3880      scan down for duplicates. */
3881    
3882      slotB = slotA;
3883      while (slotB > name_table)
3884        {
3885        slotB -= name_entry_size;
3886        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3887          {
3888          condition = GET2(slotB, 0) == group_num;
3889          if (condition) break;
3890          }
3891        else break;
3892        }
3893    
3894      /* Scan up for duplicates */
3895      if (!condition)
3896        {
3897        slotB = slotA;
3898        for (i++; i < name_count; i++)
3899          {
3900          slotB += name_entry_size;
3901          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3902            {
3903            condition = GET2(slotB, 0) == group_num;
3904            if (condition) break;
3905            }
3906          else break;
3907          }
3908        }
3909      }
3910    return condition;
3911    }
3912    
3913  /*  /*
3914    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
3915    
# Line 3825  return cc + 1 + LINK_SIZE; Line 3919  return cc + 1 + LINK_SIZE;
3919      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
3920          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
3921      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.
3922      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.
3923      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
3924     () - opional values stored on the stack     () - opional values stored on the stack
3925    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3863  return cc + 1 + LINK_SIZE; Line 3957  return cc + 1 + LINK_SIZE;
3957      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.
3958    
3959    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3960    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3961    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3962    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3963                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3964                                              Or nothing, if trace is unnecessary
3965  */  */
3966    
3967  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 3899  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3994  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3994    
3995  opcode = *cc;  opcode = *cc;
3996  ccbegin = cc;  ccbegin = cc;
3997    hotpath = ccbegin + 1 + LINK_SIZE;
3998    
3999  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)
4000    {    {
4001    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3910  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4007  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4007  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4008  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)));
4009  cc += GET(cc, 1);  cc += GET(cc, 1);
4010  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4011    has_alternatives = *cc == OP_ALT;
4012    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4013      {
4014      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4015      if (*hotpath == OP_NRREF)
4016        {
4017        stacksize = GET2(hotpath, 1);
4018        if (common->currententry == NULL || stacksize == RREF_ANY)
4019          has_alternatives = FALSE;
4020        else if (common->currententry->start == 0)
4021          has_alternatives = stacksize != 0;
4022        else
4023          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4024        }
4025      }
4026    
4027  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4028    opcode = OP_SCOND;    opcode = OP_SCOND;
4029    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4030      opcode = OP_ONCE;
4031    
4032  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4033    {    {
# Line 3921  if (opcode == OP_CBRA || opcode == OP_SC Line 4036  if (opcode == OP_CBRA || opcode == OP_SC
4036    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4037    offset <<= 1;    offset <<= 1;
4038    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4039      hotpath += 2;
4040    }    }
4041  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4042    {    {
# Line 4052  if (opcode == OP_ONCE) Line 4168  if (opcode == OP_ONCE)
4168  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4169    {    {
4170    /* Saving the previous values. */    /* Saving the previous values. */
4171    allocate_stack(common, 4);    allocate_stack(common, 3);
4172    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4173    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));
4174    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4175    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4176    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);  
4177    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4178    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));  
4179    }    }
4180  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4181    {    {
# Line 4080  else if (has_alternatives) Line 4193  else if (has_alternatives)
4193    }    }
4194    
4195  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4196  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4197    {    {
4198    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4199      {      {
4200        SLJIT_ASSERT(has_alternatives);
4201      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4202        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)));
4203        hotpath += 3;
4204        }
4205      else if (*hotpath == OP_NCREF)
4206        {
4207        SLJIT_ASSERT(has_alternatives);
4208        stacksize = GET2(hotpath, 1);
4209        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4210    
4211        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4212        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4213        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4214        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4215        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4216        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4217        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4218        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4219        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4220    
4221        JUMPHERE(jump);
4222      hotpath += 3;      hotpath += 3;
4223      }      }
4224      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4225        {
4226        /* Never has other case. */
4227        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4228    
4229        stacksize = GET2(hotpath, 1);
4230        if (common->currententry == NULL)
4231          stacksize = 0;
4232        else if (stacksize == RREF_ANY)
4233          stacksize = 1;
4234        else if (common->currententry->start == 0)
4235          stacksize = stacksize == 0;
4236        else
4237          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4238    
4239        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4240          {
4241          SLJIT_ASSERT(!has_alternatives);
4242          if (stacksize != 0)
4243            hotpath += 3;
4244          else
4245            {
4246            if (*cc == OP_ALT)
4247              {
4248              hotpath = cc + 1 + LINK_SIZE;
4249              cc += GET(cc, 1);
4250              }
4251            else
4252              hotpath = cc;
4253            }
4254          }
4255        else
4256          {
4257          SLJIT_ASSERT(has_alternatives);
4258    
4259          stacksize = GET2(hotpath, 1);
4260          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4261          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4262          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4263          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4264          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4265          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4266          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4267          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4268          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4269          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4270          hotpath += 3;
4271          }
4272        }
4273    else    else
4274      {      {
4275      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4276      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4277      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4278      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4123  if (opcode == OP_ONCE) Line 4302  if (opcode == OP_ONCE)
4302        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);
4303        }        }
4304      }      }
4305    else if (ket == OP_KETRMAX)    else
4306      {      {
4307      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4308      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));
4309      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4310          {
4311          /* TMP2 which is set here used by OP_KETRMAX below. */
4312          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4313          }
4314      }      }
4315    }    }
4316    
# Line 4210  if (bra == OP_BRAMINZERO) Line 4393  if (bra == OP_BRAMINZERO)
4393    /* Continue to the normal fallback. */    /* Continue to the normal fallback. */
4394    }    }
4395    
4396    if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
4397      decrease_call_count(common);
4398    
4399  /* Skip the other alternatives. */  /* Skip the other alternatives. */
4400  while (*cc == OP_ALT)  while (*cc == OP_ALT)
4401    cc += GET(cc, 1);    cc += GET(cc, 1);
# Line 4268  framesize = get_framesize(common, cc, FA Line 4454  framesize = get_framesize(common, cc, FA
4454  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4455  if (framesize < 0)  if (framesize < 0)
4456    {    {
4457    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4458    if (!zero)    if (!zero)
4459      stacksize++;      stacksize++;
4460    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4281  if (framesize < 0) Line 4467  if (framesize < 0)
4467      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));
4468      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4469      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);  
4470      }      }
4471    else    else
4472      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 4339  while (*cc != OP_KETRPOS) Line 4524  while (*cc != OP_KETRPOS)
4524        {        {
4525        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4526        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));  
4527        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4528          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4529        }        }
4530      else      else
4531        {        {
# Line 4360  while (*cc != OP_KETRPOS) Line 4544  while (*cc != OP_KETRPOS)
4544      {      {
4545      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4546        {        {
4547          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4548        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);  
4549        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));  
4550        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4551          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4552        }        }
4553      else      else
4554        {        {
4555        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4556          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4557        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4558          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));
4559        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 4379  while (*cc != OP_KETRPOS) Line 4562  while (*cc != OP_KETRPOS)
4562      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4563        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));
4564    
     /* TMP2 must be set above. */  
4565      if (!zero)      if (!zero)
4566        {        {
4567        if (framesize < 0)        if (framesize < 0)
4568          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);
4569        else        else
4570          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);
4571        }        }
4572      }      }
4573    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4407  while (*cc != OP_KETRPOS) Line 4589  while (*cc != OP_KETRPOS)
4589      {      {
4590      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4591        {        {
4592          /* Last alternative. */
4593        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4594          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4595        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 4434  if (!zero) Line 4617  if (!zero)
4617    
4618  /* None of them matched. */  /* None of them matched. */
4619  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
4620    decrease_call_count(common);
4621  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4622  }  }
4623    
# Line 4694  switch(opcode) Line 4878  switch(opcode)
4878    break;    break;
4879    }    }
4880    
4881    decrease_call_count(common);
4882  return end;  return end;
4883  }  }
4884    
# Line 4744  return cc + 1; Line 4929  return cc + 1;
4929  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)
4930  {  {
4931  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
4932  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
4933    
4934  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
# Line 4753  if (common->currententry != NULL) Line 4937  if (common->currententry != NULL)
4937    
4938  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));
4939  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
4940  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);
4941  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);  
4942  return cc + 3;  return cc + 3;
4943  }  }
4944    
# Line 4783  while (cc < ccend) Line 4963  while (cc < ccend)
4963      case OP_WORDCHAR:      case OP_WORDCHAR:
4964      case OP_ANY:      case OP_ANY:
4965      case OP_ALLANY:      case OP_ALLANY:
4966        case OP_ANYBYTE:
4967      case OP_NOTPROP:      case OP_NOTPROP:
4968      case OP_PROP:      case OP_PROP:
4969      case OP_ANYNL:      case OP_ANYNL:
# Line 4937  while (cc < ccend) Line 5118  while (cc < ccend)
5118        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
5119        }        }
5120      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
5121        if (cc[1] > OP_ASSERTBACK_NOT)
5122          decrease_call_count(common);
5123      break;      break;
5124    
5125      case OP_ONCE:      case OP_ONCE:
5126        case OP_ONCE_NC:
5127      case OP_BRA:      case OP_BRA:
5128      case OP_CBRA:      case OP_CBRA:
5129      case OP_COND:      case OP_COND:
# Line 5170  static void compile_assert_fallbackpath( Line 5354  static void compile_assert_fallbackpath(
5354  DEFINE_COMPILER;  DEFINE_COMPILER;
5355  uschar *cc = current->cc;  uschar *cc = current->cc;
5356  uschar bra = OP_BRA;  uschar bra = OP_BRA;
 struct sljit_jump *jump;  
5357  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5358    
5359  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5216  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5399  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5399    {    {
5400    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);
5401    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5402      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));
5403    
5404    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5405    }    }
5406  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5407    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));  
5408    
5409  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5410    {    {
# Line 5256  jump_list *jumplistitem = NULL; Line 5432  jump_list *jumplistitem = NULL;
5432  uschar bra = OP_BRA;  uschar bra = OP_BRA;
5433  uschar ket;  uschar ket;
5434  assert_fallback *assert;  assert_fallback *assert;
5435    BOOL has_alternatives;
5436  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5437  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5438  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5271  opcode = *cc; Line 5448  opcode = *cc;
5448  ccbegin = cc;  ccbegin = cc;
5449  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5450  cc += GET(cc, 1);  cc += GET(cc, 1);
5451    has_alternatives = *cc == OP_ALT;
5452    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5453      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5454  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5455    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5456  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5457    opcode = OP_SCOND;    opcode = OP_SCOND;
5458    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5459      opcode = OP_ONCE;
5460    
5461  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5462    {    {
# Line 5317  else if (bra == OP_BRAZERO) Line 5499  else if (bra == OP_BRAZERO)
5499    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5500    }    }
5501    
5502  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5503    {    {
5504    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5505      {      {
# Line 5326  if (opcode == OP_ONCE) Line 5508  if (opcode == OP_ONCE)
5508      }      }
5509    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5510    }    }
5511    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5512      {
5513      if (has_alternatives)
5514        {
5515        /* Always exactly one alternative. */
5516        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5517        free_stack(common, 1);
5518    
5519        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5520        if (SLJIT_UNLIKELY(!jumplistitem))
5521          return;
5522        jumplist = jumplistitem;
5523        jumplistitem->next = NULL;
5524        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5525        }
5526      }
5527  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5528    {    {
5529    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5357  else if (*cc == OP_ALT) Line 5555  else if (*cc == OP_ALT)
5555    
5556    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5557    }    }
 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);  
   }  
5558    
5559  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5560  if (current->topfallbacks)  if (current->topfallbacks)
5561    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5562    
5563  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5564    {    {
5565    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5566    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)
5567      {      {
5568        SLJIT_ASSERT(has_alternatives);
5569      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5570      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))
5571        {        {
# Line 5390  if (opcode == OP_COND || opcode == OP_SC Line 5576  if (opcode == OP_COND || opcode == OP_SC
5576      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5577      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5578      }      }
5579    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5580      {      {
5581        SLJIT_ASSERT(has_alternatives);
5582      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5583      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5584      }      }
5585      else
5586        SLJIT_ASSERT(!has_alternatives);
5587    }    }
5588    
5589  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5590    {    {
5591    count = 1;    count = 1;
5592    do    do
# Line 5425  if (*cc == OP_ALT || opcode == OP_COND | Line 5614  if (*cc == OP_ALT || opcode == OP_COND |
5614      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5615      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5616        {        {
5617        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5618          {          {
5619            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5620            /* TMP2 which is set here used by OP_KETRMAX below. */
5621          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5622              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5623            else if (ket == OP_KETRMIN)
5624            {            {
5625            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5626            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);
5627            }            }
5628          }          }
5629        else        else
5630          {          {
5631          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. */  
5632          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5633            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5634          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5635            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));
5636              }
5637          }          }
5638        }        }
5639    
# Line 5523  if (offset != 0) Line 5716  if (offset != 0)
5716    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5717    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5718    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);
5719    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));
5720    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);  
5721    }    }
5722  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5723    {    {
# Line 5540  else if (opcode == OP_ONCE) Line 5731  else if (opcode == OP_ONCE)
5731      {      {
5732      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5733      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));  
5734      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);  
5735      }      }
5736    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5737      {      {
# Line 5615  if (CURRENT_AS(bracketpos_fallback)->fra Line 5802  if (CURRENT_AS(bracketpos_fallback)->fra
5802      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5803      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5804      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));  
5805      }      }
5806    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5807    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5629  if (current->topfallbacks) Line 5815  if (current->topfallbacks)
5815    {    {
5816    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5817    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5818    /* 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));  
5819    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);  
5820    JUMPHERE(jump);    JUMPHERE(jump);
5821    }    }
5822  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 5766  while (current) Line 5950  while (current)
5950      break;      break;
5951    
5952      case OP_ONCE:      case OP_ONCE:
5953        case OP_ONCE_NC:
5954      case OP_BRA:      case OP_BRA:
5955      case OP_CBRA:      case OP_CBRA:
5956      case OP_COND:      case OP_COND:
# Line 5837  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 6022  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
6022  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6023  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);
6024  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
6025    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
6026    
6027  if (alternativesize > 0)  if (alternativesize > 0)
6028    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 5877  while (1) Line 6059  while (1)
6059    }    }
6060  /* None of them matched. */  /* None of them matched. */
6061  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));  
6062  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6063    
6064  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5886  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6066  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6066  if (needsframe)  if (needsframe)
6067    {    {
6068    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6069    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));
6070    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6071    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));
6072    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
6073    }    }
6074  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 5912  struct sljit_compiler *compiler; Line 6092  struct sljit_compiler *compiler;
6092  fallback_common rootfallback;  fallback_common rootfallback;
6093  compiler_common common_data;  compiler_common common_data;
6094  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6095  const unsigned char *tables = re->tables;  const uschar *tables = re->tables;
6096  pcre_study_data *study = (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0 ? extra->study_data : NULL;  pcre_study_data *study;
6097  uschar *ccend;  uschar *ccend;
6098  executable_function *function;  executable_function *function;
6099  void *executable_func;  void *executable_func;
# Line 5925  struct sljit_jump *alloc_error; Line 6105  struct sljit_jump *alloc_error;
6105  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6106  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6107    
6108    SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
6109    study = extra->study_data;
6110    
6111  if (!tables)  if (!tables)
6112    tables = _pcre_default_tables;    tables = _pcre_default_tables;
6113    
# Line 5939  common->lcc = (sljit_w)(tables + lcc_off Line 6122  common->lcc = (sljit_w)(tables + lcc_off
6122  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6123  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6124    {    {
6125    case 0: common->newline = NEWLINE; break;   /* Compile-time default */    case 0:
6126      /* Compile-time default */
6127      switch (NEWLINE)
6128        {
6129        case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6130        case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6131        default: common->newline = NEWLINE; break;
6132        }
6133      break;
6134    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
6135    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
6136    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
# Line 5962  else Line 6153  else
6153    }    }
6154  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6155  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6156    common->name_table = (sljit_w)re + re->name_table_offset;
6157    common->name_count = re->name_count;
6158    common->name_entry_size = re->name_entry_size;
6159  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6160  common->stubs = NULL;  common->stubs = NULL;
6161  common->entries = NULL;  common->entries = NULL;
6162  common->currententry = NULL;  common->currententry = NULL;
6163  common->accept = NULL;  common->accept = NULL;
6164    common->calllimit = NULL;
6165  common->stackalloc = NULL;  common->stackalloc = NULL;
6166  common->revertframes = NULL;  common->revertframes = NULL;
6167  common->wordboundary = NULL;  common->wordboundary = NULL;
# Line 6016  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6211  sljit_emit_enter(compiler, 1, 5, 5, comm
6211  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6212  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6213    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);  
6214    
6215  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
6216  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);
6217  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6218  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6219  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6220    OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
6221  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
6222  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6223    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6224    
6225  /* Main part of the matching */  /* Main part of the matching */
6226  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
# Line 6043  if ((re->flags & PCRE_REQCHSET) != 0) Line 6239  if ((re->flags & PCRE_REQCHSET) != 0)
6239    
6240  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6241  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);
6242    /* Copy the limit of allowed recursions. */
6243    OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6244    
6245  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6246  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6060  if (common->accept != NULL) Line 6258  if (common->accept != NULL)
6258    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->acceptlabel);
6259    
6260  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6261  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  copy_ovector(common, re->top_bracket + 1);
   
6262  leave = LABEL();  leave = LABEL();
 copy_ovector(common);  
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0);  
6263  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6264    
6265  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6113  if (reqbyte_notfound != NULL) Line 6308  if (reqbyte_notfound != NULL)
6308    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6309  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6310  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));
6311  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6312  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6313    
6314  flush_stubs(common);  flush_stubs(common);
# Line 6143  while (common->currententry != NULL) Line 6338  while (common->currententry != NULL)
6338    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
6339    }    }
6340    
6341  /* Allocating stack, returns with PCRE_ERROR_NOMEMORY if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
6342  /* This is a (really) rare case. */  /* This is a (really) rare case. */
6343  set_jumps(common->stackalloc, LABEL());  set_jumps(common->stackalloc, LABEL());
6344  /* RETURN_ADDR is not a saved register. */  /* RETURN_ADDR is not a saved register. */
# Line 6166  sljit_emit_fast_return(compiler, SLJIT_M Line 6361  sljit_emit_fast_return(compiler, SLJIT_M
6361  /* Allocation failed. */  /* Allocation failed. */
6362  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6363  /* 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. */
6364  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMEMORY);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6365    JUMPTO(SLJIT_JUMP, leave);
6366    
6367    /* Call limit reached. */
6368    set_jumps(common->calllimit, LABEL());
6369    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6370  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6371    
6372  if (common->revertframes != NULL)  if (common->revertframes != NULL)
# Line 6266  return convert_executable_func.call_exec Line 6466  return convert_executable_func.call_exec
6466    
6467  int  int
6468  _pcre_jit_exec(const real_pcre *re, void *executable_func,  _pcre_jit_exec(const real_pcre *re, void *executable_func,
6469    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options,
6470    int offsetcount)    int match_limit, int *offsets, int offsetcount)
6471  {  {
6472  executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
6473  union {  union {
# Line 6283  arguments.stack = NULL; Line 6483  arguments.stack = NULL;
6483  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
6484  arguments.begin = subject;  arguments.begin = subject;
6485  arguments.end = subject + length;  arguments.end = subject + length;
6486    arguments.calllimit = match_limit; /* JIT decreases this value less times. */
6487  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
6488  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
6489  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 6346  sljit_free_stack((struct sljit_stack*)st Line 6547  sljit_free_stack((struct sljit_stack*)st
6547  }  }
6548    
6549  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6550  pcre_assign_jit_callback(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6551  {  {
6552  executable_function *function;  executable_function *function;
6553  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)  if (extra != NULL &&
6554        (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6555        extra->executable_jit != NULL)
6556    {    {
6557    function = (executable_function*)extra->executable_jit;    function = (executable_function*)extra->executable_jit;
6558    function->callback = callback;    function->callback = callback;
# Line 6359  if ((extra->flags & PCRE_EXTRA_EXECUTABL Line 6562  if ((extra->flags & PCRE_EXTRA_EXECUTABL
6562    
6563  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
6564    
6565  /* 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
6566  being compiled. */  being compiled. */
6567    
6568  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
# Line 6377  pcre_jit_stack_free(pcre_jit_stack *stac Line 6580  pcre_jit_stack_free(pcre_jit_stack *stac
6580  }  }
6581    
6582  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6583  pcre_assign_jit_callback(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6584  {  {
6585  (void)extra;  (void)extra;
6586  (void)callback;  (void)callback;

Legend:
Removed from v.669  
changed lines
  Added in v.741

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12