/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

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

revision 678 by ph10, Sun Aug 28 15:23:03 2011 UTC revision 752 by zherczeg, Sat Nov 19 15:28:29 2011 UTC
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (pcre_malloc)(size)
56    #define SLJIT_FREE(ptr) (pcre_free)(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
# Line 119  The generated code will be the following Line 122  The generated code will be the following
122   jump to D hot path   jump to D hot path
123   C fallback path   C fallback path
124   A fallback path   A fallback path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of fallback code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# Line 170  typedef struct jump_list { Line 173  typedef struct jump_list {
173    struct jump_list *next;    struct jump_list *next;
174  } jump_list;  } jump_list;
175    
176  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
177    
178  typedef struct stub_list {  typedef struct stub_list {
179    enum stub_types type;    enum stub_types type;
# Line 276  typedef struct compiler_common { Line 279  typedef struct compiler_common {
279    int bsr_nltype;    int bsr_nltype;
280    int endonly;    int endonly;
281    sljit_w ctypes;    sljit_w ctypes;
282      sljit_uw name_table;
283      sljit_w name_count;
284      sljit_w name_entry_size;
285    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
286    stub_list *stubs;    stub_list *stubs;
287    recurse_entry *entries;    recurse_entry *entries;
# Line 328  typedef struct compare_context { Line 334  typedef struct compare_context {
334    
335  enum {  enum {
336    frame_end = 0,    frame_end = 0,
337    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
338  };  };
339    
340  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
# Line 343  enum { Line 348  enum {
348  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
349  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
350  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
351  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
352  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
353    
354  /* Locals layout. */  /* Locals layout. */
# Line 353  enum { Line 358  enum {
358  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
359  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
360  #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))  
361  /* Head of the last recursion. */  /* Head of the last recursion. */
362  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
 /* Number of recursions. */  
 #define CALL_COUNT       (6 * sizeof(sljit_w))  
363  /* Max limit of recursions. */  /* Max limit of recursions. */
364  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
365  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
366  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
367  /* End pointer of the first line. */  /* End pointer of the first line. */
368  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
369  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
370  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
371  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
372  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
373  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
374  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
375  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
376  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 405  cc += 1 + LINK_SIZE; Line 406  cc += 1 + LINK_SIZE;
406  return cc;  return cc;
407  }  }
408    
409  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
410   next_opcode   next_opcode
411   get_localspace   get_localspace
412   set_localptrs   set_localptrs
# Line 472  switch(*cc) Line 473  switch(*cc)
473    case OP_SKIPZERO:    case OP_SKIPZERO:
474    return cc + 1;    return cc + 1;
475    
476      case OP_ANYBYTE:
477    #ifdef SUPPORT_UTF8
478      if (common->utf8) return NULL;
479    #endif
480      return cc + 1;
481    
482    case OP_CHAR:    case OP_CHAR:
483    case OP_CHARI:    case OP_CHARI:
484    case OP_NOT:    case OP_NOT:
# Line 550  switch(*cc) Line 557  switch(*cc)
557    case OP_REF:    case OP_REF:
558    case OP_REFI:    case OP_REFI:
559    case OP_CREF:    case OP_CREF:
560      case OP_NCREF:
561      case OP_RREF:
562      case OP_NRREF:
563    case OP_CLOSE:    case OP_CLOSE:
564    cc += 3;    cc += 3;
565    return cc;    return cc;
# Line 574  switch(*cc) Line 584  switch(*cc)
584    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
585    case OP_REVERSE:    case OP_REVERSE:
586    case OP_ONCE:    case OP_ONCE:
587      case OP_ONCE_NC:
588    case OP_BRA:    case OP_BRA:
589    case OP_BRAPOS:    case OP_BRAPOS:
590    case OP_COND:    case OP_COND:
# Line 612  while (cc < ccend) Line 623  while (cc < ccend)
623      case OP_ASSERTBACK:      case OP_ASSERTBACK:
624      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
625      case OP_ONCE:      case OP_ONCE:
626        case OP_ONCE_NC:
627      case OP_BRAPOS:      case OP_BRAPOS:
628      case OP_SBRA:      case OP_SBRA:
629      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 657  while (cc < ccend) Line 669  while (cc < ccend)
669      case OP_ASSERTBACK:      case OP_ASSERTBACK:
670      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
671      case OP_ONCE:      case OP_ONCE:
672        case OP_ONCE_NC:
673      case OP_BRAPOS:      case OP_BRAPOS:
674      case OP_SBRA:      case OP_SBRA:
675      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 696  while (cc < ccend) Line 709  while (cc < ccend)
709  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)
710  {  {
711  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 uschar *end;  
712  int length = 0;  int length = 0;
713  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
714  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
715    
716  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
717    {    {
718    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
719    possessive = TRUE;    possessive = TRUE;
720    }    }
721    
# Line 725  while (cc < ccend) Line 734  while (cc < ccend)
734      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
735      break;      break;
736    
     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;  
   
737      case OP_CBRA:      case OP_CBRA:
738      case OP_CBRAPOS:      case OP_CBRAPOS:
739      case OP_SCBRA:      case OP_SCBRA:
740      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
741      length += 3;      length += 3;
742      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + 2;
743      break;      break;
# Line 767  while (cc < ccend) Line 749  while (cc < ccend)
749      }      }
750    
751  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
752  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
753    return -1;    return -1;
754    
755  if (length > 0)  if (length > 0)
756    return length + 2;    return length + 1;
757  return needs_frame ? 0 : -1;  return -1;
758  }  }
759    
760  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)
761  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
762  DEFINE_COMPILER;  DEFINE_COMPILER;
763  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
764  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
765  int offset;  int offset;
766    
767  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
768    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
769    
770  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);  
   
771  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
772    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
773  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 815  while (cc < ccend) Line 788  while (cc < ccend)
788      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
789      break;      break;
790    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
791      case OP_CBRA:      case OP_CBRA:
792      case OP_CBRAPOS:      case OP_CBRAPOS:
793      case OP_SCBRA:      case OP_SCBRA:
794      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;  
       }  
795      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
796      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
797      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 855  while (cc < ccend) Line 812  while (cc < ccend)
812      }      }
813    
814  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
815  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
816  }  }
817    
818  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)
# Line 872  while (cc < ccend) Line 829  while (cc < ccend)
829      case OP_ASSERTBACK:      case OP_ASSERTBACK:
830      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
831      case OP_ONCE:      case OP_ONCE:
832        case OP_ONCE_NC:
833      case OP_BRAPOS:      case OP_BRAPOS:
834      case OP_SBRA:      case OP_SBRA:
835      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 974  while (status != end) Line 932  while (status != end)
932        case OP_ASSERTBACK:        case OP_ASSERTBACK:
933        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
934        case OP_ONCE:        case OP_ONCE:
935          case OP_ONCE_NC:
936        case OP_BRAPOS:        case OP_BRAPOS:
937        case OP_SBRA:        case OP_SBRA:
938        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1170  while (list_item) Line 1129  while (list_item)
1129      case stack_alloc:      case stack_alloc:
1130      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1131      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1132      }      }
1133    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1134    list_item = list_item->next;    list_item = list_item->next;
# Line 1185  static SLJIT_INLINE void decrease_call_c Line 1140  static SLJIT_INLINE void decrease_call_c
1140  {  {
1141  DEFINE_COMPILER;  DEFINE_COMPILER;
1142    
1143  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1144  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1145  }  }
1146    
# Line 1218  struct sljit_label *loop; Line 1173  struct sljit_label *loop;
1173  int i;  int i;
1174  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1175  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  
1176  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);
1177  if (length < 8)  if (length < 8)
1178    {    {
# Line 1236  else Line 1190  else
1190    }    }
1191  }  }
1192    
1193  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1194  {  {
1195  DEFINE_COMPILER;  DEFINE_COMPILER;
1196  struct sljit_label *loop;  struct sljit_label *loop;
1197  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1198    
1199  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1200    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1201    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1202    
1203  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1204  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));
1205  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
# Line 1258  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP Line 1215  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP
1215  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);
1216  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1217  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1218    
1219    /* Calculate the return value, which is the maximum ovector value. */
1220    if (topbracket > 1)
1221      {
1222      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1223      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1224    
1225      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1226      loop = LABEL();
1227      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1228      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1229      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1230      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1231      }
1232    else
1233      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1234  }  }
1235    
1236  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)
# Line 1378  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1351  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1351  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1352  if (common->utf8)  if (common->utf8)
1353    {    {
1354    /* 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);  
1355    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1356    JUMPHERE(jump);    JUMPHERE(jump);
1357    }    }
# Line 1400  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1372  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1372  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1373  if (common->utf8)  if (common->utf8)
1374    {    {
1375    /* 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);  
1376    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1377    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1378    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1425  if (common->utf8) Line 1396  if (common->utf8)
1396    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1397    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1398    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1399    /* 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);  
1400    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1401    JUMPHERE(jump);    JUMPHERE(jump);
1402    return;    return;
# Line 1486  else Line 1456  else
1456  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1457  {  {
1458  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1459  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. */
1460  DEFINE_COMPILER;  DEFINE_COMPILER;
1461  struct sljit_jump *jump;  struct sljit_jump *jump;
1462    
# Line 1569  sljit_emit_fast_return(compiler, RETURN_ Line 1539  sljit_emit_fast_return(compiler, RETURN_
1539  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1540  {  {
1541  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1542  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1543  DEFINE_COMPILER;  DEFINE_COMPILER;
1544  struct sljit_jump *jump;  struct sljit_jump *jump;
1545  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1595  sljit_emit_fast_return(compiler, RETURN_ Line 1565  sljit_emit_fast_return(compiler, RETURN_
1565  JUMPHERE(jump);  JUMPHERE(jump);
1566    
1567  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1568  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);  
1569  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1570  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1571  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1640  struct sljit_label *newlinelabel = NULL; Line 1609  struct sljit_label *newlinelabel = NULL;
1609  struct sljit_jump *start;  struct sljit_jump *start;
1610  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1611  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1612    #ifdef SUPPORT_UTF8
1613    struct sljit_jump *singlebyte;
1614    #endif
1615  jump_list *newline = NULL;  jump_list *newline = NULL;
1616  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1617  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1710  if (readbyte) Line 1682  if (readbyte)
1682  if (newlinecheck)  if (newlinecheck)
1683    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);
1684    
1685    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1686  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1687  if (common->utf8)  if (common->utf8)
1688    {    {
1689    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);
1690      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1691    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1692      JUMPHERE(singlebyte);
1693    }    }
 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);  
1694  #endif  #endif
1695  JUMPHERE(start);  JUMPHERE(start);
1696    
# Line 1772  else Line 1743  else
1743      }      }
1744    }    }
1745    
1746    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1747  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1748  if (common->utf8)  if (common->utf8)
1749    {    {
1750    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);
1751      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1752    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1753    }    }
 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);  
1754  #endif  #endif
1755  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1756  JUMPHERE(found);  JUMPHERE(found);
# Line 1888  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1857  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1857  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1858  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1859  if (common->utf8)  if (common->utf8)
1860    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1861  #endif  #endif
1862  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1863  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1899  found = JUMP(SLJIT_C_NOT_ZERO); Line 1868  found = JUMP(SLJIT_C_NOT_ZERO);
1868    
1869  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1870  if (common->utf8)  if (common->utf8)
1871    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1872  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1873  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1874    #ifdef SUPPORT_UTF8
1875    if (common->utf8)
1876      {
1877      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1878      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1879      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1880      }
1881  #endif  #endif
1882  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1883  JUMPHERE(found);  JUMPHERE(found);
# Line 1971  return notfound; Line 1945  return notfound;
1945  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1946  {  {
1947  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1948  struct sljit_jump *jump;  struct sljit_jump *jump;
1949  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1950    
1951  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);
1952  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1953    
1954  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1955  mainloop = LABEL();  mainloop = LABEL();
1956  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1957  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1992  JUMPTO(SLJIT_JUMP, mainloop); Line 1964  JUMPTO(SLJIT_JUMP, mainloop);
1964  JUMPHERE(jump);  JUMPHERE(jump);
1965  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1966  /* 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);  
1967  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1968    
1969  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);  
1970  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
1971  /* Set max index. */  /* Set string begin. */
1972  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
1973  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));
1974  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
# Line 2027  struct sljit_jump *beginend; Line 1988  struct sljit_jump *beginend;
1988  struct sljit_jump *jump;  struct sljit_jump *jump;
1989  #endif  #endif
1990    
1991  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
1992    
1993  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);
1994  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2384  do Line 2345  do
2345        }        }
2346      context->byteptr = 0;      context->byteptr = 0;
2347      }      }
2348    
2349  #else  #else
2350    
2351    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
# Line 2446  uschar *ccbegin; Line 2407  uschar *ccbegin;
2407  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2408  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2409  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2410  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2411    unsigned int typeoffset;
2412  #endif  #endif
2413  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2414    unsigned int charoffset;
2415    
2416  /* 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. */
2417  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
# Line 2841  switch(type) Line 2804  switch(type)
2804    if (common->utf8)    if (common->utf8)
2805      {      {
2806      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2807      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);
2808        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2809        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
2810      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2811        JUMPHERE(jump[0]);
2812      return cc;      return cc;
2813      }      }
2814  #endif  #endif
2815    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2816    return cc;    return cc;
2817    
2818      case OP_ANYBYTE:
2819      check_input_end(common, fallbacks);
2820      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2821      return cc;
2822    
2823  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2824  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2825    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3095  switch(type) Line 3066  switch(type)
3066      if (c <= 127)      if (c <= 127)
3067        {        {
3068        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);  
3069        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3070          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));
3071        else        else
3072          {          {
3073          /* 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. */
3074          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3075          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));
3076          }          }
3077        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3078        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3079          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3080          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
3081          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3082          JUMPHERE(jump[0]);
3083        return cc + length;        return cc + length;
3084        }        }
3085      else      else
# Line 3232  do Line 3206  do
3206        else if (cc[1] >= 0xc0)        else if (cc[1] >= 0xc0)
3207          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += _pcre_utf8_table4[cc[1] & 0x3f];
3208        }        }
3209      else      else
3210  #endif  #endif
3211      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)
3212        size = 0;        size = 0;
# Line 3642  while (1) Line 3616  while (1)
3616    if (common->accept != NULL)    if (common->accept != NULL)
3617      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3618    
3619      /* Reset stack. */
3620    if (framesize < 0)    if (framesize < 0)
3621      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3622      else {
3623        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3624          {
3625          /* We don't need to keep the STR_PTR, only the previous localptr. */
3626          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3627          }
3628        else
3629          {
3630          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3631          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3632          }
3633      }
3634    
3635    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3636      {      {
3637      /* 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. */
3638      if (conditional)      if (conditional)
3639        {        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));  
         }  
       }  
3640      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3641        {        {
3642        if (framesize < 0)        if (framesize < 0)
3643          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3644        else        else
3645          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3646          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));
3647          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));
3648          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3673  while (1) Line 3650  while (1)
3650        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));
3651        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3652        }        }
3653      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3654        {        {
3655        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3656          {        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));  
         }  
3657        }        }
3658      }      }
3659    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3707  if (opcode == OP_ASSERT || opcode == OP_ Line 3680  if (opcode == OP_ASSERT || opcode == OP_
3680    /* Assert is failed. */    /* Assert is failed. */
3681    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3682      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3683    
3684    if (framesize < 0)    if (framesize < 0)
3685      {      {
3686      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3718  if (opcode == OP_ASSERT || opcode == OP_ Line 3692  if (opcode == OP_ASSERT || opcode == OP_
3692    else    else
3693      {      {
3694      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));  
3695      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3696      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3697        {        {
# Line 3729  if (opcode == OP_ASSERT || opcode == OP_ Line 3701  if (opcode == OP_ASSERT || opcode == OP_
3701      else      else
3702        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3703      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);  
3704      }      }
3705    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3706    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3753  if (opcode == OP_ASSERT || opcode == OP_ Line 3723  if (opcode == OP_ASSERT || opcode == OP_
3723      }      }
3724    else    else
3725      {      {
3726      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)  
3727        {        {
3728        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3729        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));
3730          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3731        }        }
3732      else if (bra == OP_BRAMINZERO)      else
3733        {        {
3734        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3735        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));
3736          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3737          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3738        }        }
3739      }      }
3740    
# Line 3800  else Line 3771  else
3771      {      {
3772      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3773      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));  
3774      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3775      if (bra != OP_BRA)      if (bra != OP_BRA)
3776        {        {
# Line 3811  else Line 3780  else
3780      else      else
3781        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3782      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);  
3783      }      }
3784    
3785    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3836  common->accept = save_accept; Line 3803  common->accept = save_accept;
3803  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3804  }  }
3805    
3806    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, uschar *name_table)
3807    {
3808    int condition = FALSE;
3809    uschar *slotA = name_table;
3810    uschar *slotB;
3811    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3812    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3813    sljit_w no_capture;
3814    int i;
3815    
3816    locals += OVECTOR_START / sizeof(sljit_w);
3817    no_capture = locals[1];
3818    
3819    for (i = 0; i < name_count; i++)
3820      {
3821      if (GET2(slotA, 0) == refno) break;
3822      slotA += name_entry_size;
3823      }
3824    
3825    if (i < name_count)
3826      {
3827      /* Found a name for the number - there can be only one; duplicate names
3828      for different numbers are allowed, but not vice versa. First scan down
3829      for duplicates. */
3830    
3831      slotB = slotA;
3832      while (slotB > name_table)
3833        {
3834        slotB -= name_entry_size;
3835        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3836          {
3837          condition = locals[GET2(slotB, 0) << 1] != no_capture;
3838          if (condition) break;
3839          }
3840        else break;
3841        }
3842    
3843      /* Scan up for duplicates */
3844      if (!condition)
3845        {
3846        slotB = slotA;
3847        for (i++; i < name_count; i++)
3848          {
3849          slotB += name_entry_size;
3850          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3851            {
3852            condition = locals[GET2(slotB, 0) << 1] != no_capture;
3853            if (condition) break;
3854            }
3855          else break;
3856          }
3857        }
3858      }
3859    return condition;
3860    }
3861    
3862    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table)
3863    {
3864    int condition = FALSE;
3865    uschar *slotA = name_table;
3866    uschar *slotB;
3867    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
3868    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
3869    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
3870    int i;
3871    
3872    for (i = 0; i < name_count; i++)
3873      {
3874      if (GET2(slotA, 0) == recno) break;
3875      slotA += name_entry_size;
3876      }
3877    
3878    if (i < name_count)
3879      {
3880      /* Found a name for the number - there can be only one; duplicate
3881      names for different numbers are allowed, but not vice versa. First
3882      scan down for duplicates. */
3883    
3884      slotB = slotA;
3885      while (slotB > name_table)
3886        {
3887        slotB -= name_entry_size;
3888        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3889          {
3890          condition = GET2(slotB, 0) == group_num;
3891          if (condition) break;
3892          }
3893        else break;
3894        }
3895    
3896      /* Scan up for duplicates */
3897      if (!condition)
3898        {
3899        slotB = slotA;
3900        for (i++; i < name_count; i++)
3901          {
3902          slotB += name_entry_size;
3903          if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
3904            {
3905            condition = GET2(slotB, 0) == group_num;
3906            if (condition) break;
3907            }
3908          else break;
3909          }
3910        }
3911      }
3912    return condition;
3913    }
3914    
3915  /*  /*
3916    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
3917    
# Line 3845  return cc + 1 + LINK_SIZE; Line 3921  return cc + 1 + LINK_SIZE;
3921      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
3922          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
3923      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.
3924      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.
3925      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
3926     () - opional values stored on the stack     () - opional values stored on the stack
3927    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3883  return cc + 1 + LINK_SIZE; Line 3959  return cc + 1 + LINK_SIZE;
3959      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.
3960    
3961    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3962    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3963    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3964    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3965                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3966                                              Or nothing, if trace is unnecessary
3967  */  */
3968    
3969  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)
# Line 3919  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3996  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3996    
3997  opcode = *cc;  opcode = *cc;
3998  ccbegin = cc;  ccbegin = cc;
3999    hotpath = ccbegin + 1 + LINK_SIZE;
4000    
4001  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)
4002    {    {
4003    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3930  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4009  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4009  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4010  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)));
4011  cc += GET(cc, 1);  cc += GET(cc, 1);
4012  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4013    has_alternatives = *cc == OP_ALT;
4014    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4015      {
4016      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4017      if (*hotpath == OP_NRREF)
4018        {
4019        stacksize = GET2(hotpath, 1);
4020        if (common->currententry == NULL || stacksize == RREF_ANY)
4021          has_alternatives = FALSE;
4022        else if (common->currententry->start == 0)
4023          has_alternatives = stacksize != 0;
4024        else
4025          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4026        }
4027      }
4028    
4029  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4030    opcode = OP_SCOND;    opcode = OP_SCOND;
4031    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4032      opcode = OP_ONCE;
4033    
4034  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4035    {    {
# Line 3941  if (opcode == OP_CBRA || opcode == OP_SC Line 4038  if (opcode == OP_CBRA || opcode == OP_SC
4038    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4039    offset <<= 1;    offset <<= 1;
4040    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4041      hotpath += 2;
4042    }    }
4043  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4044    {    {
# Line 4072  if (opcode == OP_ONCE) Line 4170  if (opcode == OP_ONCE)
4170  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4171    {    {
4172    /* Saving the previous values. */    /* Saving the previous values. */
4173    allocate_stack(common, 4);    allocate_stack(common, 3);
4174    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4175    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));
4176    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4177    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4178    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);  
4179    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4180    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));  
4181    }    }
4182  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4183    {    {
# Line 4100  else if (has_alternatives) Line 4195  else if (has_alternatives)
4195    }    }
4196    
4197  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4198  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4199    {    {
4200    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4201      {      {
4202        SLJIT_ASSERT(has_alternatives);
4203      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4204        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)));
4205        hotpath += 3;
4206        }
4207      else if (*hotpath == OP_NCREF)
4208        {
4209        SLJIT_ASSERT(has_alternatives);
4210        stacksize = GET2(hotpath, 1);
4211        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4212    
4213        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4214        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4215        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4216        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4217        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4218        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4219        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4220        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4221        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4222    
4223        JUMPHERE(jump);
4224      hotpath += 3;      hotpath += 3;
4225      }      }
4226      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4227        {
4228        /* Never has other case. */
4229        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4230    
4231        stacksize = GET2(hotpath, 1);
4232        if (common->currententry == NULL)
4233          stacksize = 0;
4234        else if (stacksize == RREF_ANY)
4235          stacksize = 1;
4236        else if (common->currententry->start == 0)
4237          stacksize = stacksize == 0;
4238        else
4239          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4240    
4241        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4242          {
4243          SLJIT_ASSERT(!has_alternatives);
4244          if (stacksize != 0)
4245            hotpath += 3;
4246          else
4247            {
4248            if (*cc == OP_ALT)
4249              {
4250              hotpath = cc + 1 + LINK_SIZE;
4251              cc += GET(cc, 1);
4252              }
4253            else
4254              hotpath = cc;
4255            }
4256          }
4257        else
4258          {
4259          SLJIT_ASSERT(has_alternatives);
4260    
4261          stacksize = GET2(hotpath, 1);
4262          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4263          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4264          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4265          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4266          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4267          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4268          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4269          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4270          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4271          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4272          hotpath += 3;
4273          }
4274        }
4275    else    else
4276      {      {
4277      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4278      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4279      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4280      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4143  if (opcode == OP_ONCE) Line 4304  if (opcode == OP_ONCE)
4304        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);
4305        }        }
4306      }      }
4307    else if (ket == OP_KETRMAX)    else
4308      {      {
4309      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4310      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));
4311      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4312          {
4313          /* TMP2 which is set here used by OP_KETRMAX below. */
4314          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4315          }
4316      }      }
4317    }    }
4318    
# Line 4291  framesize = get_framesize(common, cc, FA Line 4456  framesize = get_framesize(common, cc, FA
4456  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4457  if (framesize < 0)  if (framesize < 0)
4458    {    {
4459    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4460    if (!zero)    if (!zero)
4461      stacksize++;      stacksize++;
4462    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4304  if (framesize < 0) Line 4469  if (framesize < 0)
4469      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));
4470      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4471      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);  
4472      }      }
4473    else    else
4474      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 4362  while (*cc != OP_KETRPOS) Line 4526  while (*cc != OP_KETRPOS)
4526        {        {
4527        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4528        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));  
4529        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4530          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4531        }        }
4532      else      else
4533        {        {
# Line 4383  while (*cc != OP_KETRPOS) Line 4546  while (*cc != OP_KETRPOS)
4546      {      {
4547      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4548        {        {
4549          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4550        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);  
4551        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));  
4552        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4553          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4554        }        }
4555      else      else
4556        {        {
4557        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4558          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4559        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4560          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));
4561        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
# Line 4402  while (*cc != OP_KETRPOS) Line 4564  while (*cc != OP_KETRPOS)
4564      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4565        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));
4566    
     /* TMP2 must be set above. */  
4567      if (!zero)      if (!zero)
4568        {        {
4569        if (framesize < 0)        if (framesize < 0)
4570          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);
4571        else        else
4572          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);
4573        }        }
4574      }      }
4575    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4430  while (*cc != OP_KETRPOS) Line 4591  while (*cc != OP_KETRPOS)
4591      {      {
4592      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4593        {        {
4594          /* Last alternative. */
4595        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4596          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4597        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
# Line 4769  return cc + 1; Line 4931  return cc + 1;
4931  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)
4932  {  {
4933  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
4934  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
4935    
4936  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
# Line 4778  if (common->currententry != NULL) Line 4939  if (common->currententry != NULL)
4939    
4940  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));
4941  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
4942  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);
4943  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);  
4944  return cc + 3;  return cc + 3;
4945  }  }
4946    
# Line 4808  while (cc < ccend) Line 4965  while (cc < ccend)
4965      case OP_WORDCHAR:      case OP_WORDCHAR:
4966      case OP_ANY:      case OP_ANY:
4967      case OP_ALLANY:      case OP_ALLANY:
4968        case OP_ANYBYTE:
4969      case OP_NOTPROP:      case OP_NOTPROP:
4970      case OP_PROP:      case OP_PROP:
4971      case OP_ANYNL:      case OP_ANYNL:
# Line 4967  while (cc < ccend) Line 5125  while (cc < ccend)
5125      break;      break;
5126    
5127      case OP_ONCE:      case OP_ONCE:
5128        case OP_ONCE_NC:
5129      case OP_BRA:      case OP_BRA:
5130      case OP_CBRA:      case OP_CBRA:
5131      case OP_COND:      case OP_COND:
# Line 5197  static void compile_assert_fallbackpath( Line 5356  static void compile_assert_fallbackpath(
5356  DEFINE_COMPILER;  DEFINE_COMPILER;
5357  uschar *cc = current->cc;  uschar *cc = current->cc;
5358  uschar bra = OP_BRA;  uschar bra = OP_BRA;
 struct sljit_jump *jump;  
5359  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5360    
5361  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5243  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5401  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5401    {    {
5402    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);
5403    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5404      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));
5405    
5406    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5407    }    }
5408  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5409    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));  
5410    
5411  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5412    {    {
# Line 5283  jump_list *jumplistitem = NULL; Line 5434  jump_list *jumplistitem = NULL;
5434  uschar bra = OP_BRA;  uschar bra = OP_BRA;
5435  uschar ket;  uschar ket;
5436  assert_fallback *assert;  assert_fallback *assert;
5437    BOOL has_alternatives;
5438  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5439  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5440  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5298  opcode = *cc; Line 5450  opcode = *cc;
5450  ccbegin = cc;  ccbegin = cc;
5451  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5452  cc += GET(cc, 1);  cc += GET(cc, 1);
5453    has_alternatives = *cc == OP_ALT;
5454    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5455      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5456  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5457    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5458  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5459    opcode = OP_SCOND;    opcode = OP_SCOND;
5460    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5461      opcode = OP_ONCE;
5462    
5463  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5464    {    {
# Line 5344  else if (bra == OP_BRAZERO) Line 5501  else if (bra == OP_BRAZERO)
5501    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5502    }    }
5503    
5504  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5505    {    {
5506    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5507      {      {
# Line 5353  if (opcode == OP_ONCE) Line 5510  if (opcode == OP_ONCE)
5510      }      }
5511    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5512    }    }
5513    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5514      {
5515      if (has_alternatives)
5516        {
5517        /* Always exactly one alternative. */
5518        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5519        free_stack(common, 1);
5520    
5521        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5522        if (SLJIT_UNLIKELY(!jumplistitem))
5523          return;
5524        jumplist = jumplistitem;
5525        jumplistitem->next = NULL;
5526        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5527        }
5528      }
5529  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5530    {    {
5531    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5384  else if (*cc == OP_ALT) Line 5557  else if (*cc == OP_ALT)
5557    
5558    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5559    }    }
 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);  
   }  
5560    
5561  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5562  if (current->topfallbacks)  if (current->topfallbacks)
5563    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5564    
5565  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5566    {    {
5567    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5568    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)
5569      {      {
5570        SLJIT_ASSERT(has_alternatives);
5571      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5572      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))
5573        {        {
# Line 5417  if (opcode == OP_COND || opcode == OP_SC Line 5578  if (opcode == OP_COND || opcode == OP_SC
5578      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5579      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5580      }      }
5581    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5582      {      {
5583        SLJIT_ASSERT(has_alternatives);
5584      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5585      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5586      }      }
5587      else
5588        SLJIT_ASSERT(!has_alternatives);
5589    }    }
5590    
5591  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5592    {    {
5593    count = 1;    count = 1;
5594    do    do
# Line 5452  if (*cc == OP_ALT || opcode == OP_COND | Line 5616  if (*cc == OP_ALT || opcode == OP_COND |
5616      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5617      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5618        {        {
5619        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5620          {          {
5621            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5622            /* TMP2 which is set here used by OP_KETRMAX below. */
5623          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5624              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5625            else if (ket == OP_KETRMIN)
5626            {            {
5627            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5628            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);
5629            }            }
5630          }          }
5631        else        else
5632          {          {
5633          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. */  
5634          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5635            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5636          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5637            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));
5638              }
5639          }          }
5640        }        }
5641    
# Line 5550  if (offset != 0) Line 5718  if (offset != 0)
5718    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5719    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5720    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);
5721    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));
5722    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);  
5723    }    }
5724  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5725    {    {
# Line 5567  else if (opcode == OP_ONCE) Line 5733  else if (opcode == OP_ONCE)
5733      {      {
5734      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5735      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));  
5736      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);  
5737      }      }
5738    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5739      {      {
# Line 5642  if (CURRENT_AS(bracketpos_fallback)->fra Line 5804  if (CURRENT_AS(bracketpos_fallback)->fra
5804      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5805      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5806      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));  
5807      }      }
5808    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5809    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5656  if (current->topfallbacks) Line 5817  if (current->topfallbacks)
5817    {    {
5818    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5819    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5820    /* 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));  
5821    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);  
5822    JUMPHERE(jump);    JUMPHERE(jump);
5823    }    }
5824  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));
# Line 5793  while (current) Line 5952  while (current)
5952      break;      break;
5953    
5954      case OP_ONCE:      case OP_ONCE:
5955        case OP_ONCE_NC:
5956      case OP_BRA:      case OP_BRA:
5957      case OP_CBRA:      case OP_CBRA:
5958      case OP_COND:      case OP_COND:
# Line 5864  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 6024  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
6024  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6025  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);
6026  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
6027    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
6028    
6029  if (alternativesize > 0)  if (alternativesize > 0)
6030    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 5904  while (1) Line 6061  while (1)
6061    }    }
6062  /* None of them matched. */  /* None of them matched. */
6063  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));  
6064  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6065    
6066  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5913  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6068  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6068  if (needsframe)  if (needsframe)
6069    {    {
6070    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6071    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));
6072    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6073    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));
6074    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
6075    }    }
6076  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 5939  struct sljit_compiler *compiler; Line 6094  struct sljit_compiler *compiler;
6094  fallback_common rootfallback;  fallback_common rootfallback;
6095  compiler_common common_data;  compiler_common common_data;
6096  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6097  const unsigned char *tables = re->tables;  const uschar *tables = re->tables;
6098  pcre_study_data *study = (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0 ? extra->study_data : NULL;  pcre_study_data *study;
6099  uschar *ccend;  uschar *ccend;
6100  executable_function *function;  executable_function *function;
6101  void *executable_func;  void *executable_func;
# Line 5952  struct sljit_jump *alloc_error; Line 6107  struct sljit_jump *alloc_error;
6107  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6108  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6109    
6110    SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
6111    study = extra->study_data;
6112    
6113  if (!tables)  if (!tables)
6114    tables = _pcre_default_tables;    tables = _pcre_default_tables;
6115    
# Line 5966  common->lcc = (sljit_w)(tables + lcc_off Line 6124  common->lcc = (sljit_w)(tables + lcc_off
6124  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6125  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6126    {    {
6127    case 0: common->newline = NEWLINE; break;   /* Compile-time default */    case 0:
6128      /* Compile-time default */
6129      switch (NEWLINE)
6130        {
6131        case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6132        case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6133        default: common->newline = NEWLINE; break;
6134        }
6135      break;
6136    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
6137    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
6138    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
# Line 5989  else Line 6155  else
6155    }    }
6156  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6157  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6158    common->name_table = (sljit_w)re + re->name_table_offset;
6159    common->name_count = re->name_count;
6160    common->name_entry_size = re->name_entry_size;
6161  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6162  common->stubs = NULL;  common->stubs = NULL;
6163  common->entries = NULL;  common->entries = NULL;
# Line 6044  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6213  sljit_emit_enter(compiler, 1, 5, 5, comm
6213  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6214  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6215    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);  
6216    
6217  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
6218  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);
# Line 6071  if ((re->options & PCRE_ANCHORED) == 0) Line 6239  if ((re->options & PCRE_ANCHORED) == 0)
6239  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6240    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);
6241    
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  
6242  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6243  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);
6244  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6245  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, TMP1, 0);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6246    
6247  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6248  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6093  if (common->accept != NULL) Line 6260  if (common->accept != NULL)
6260    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->acceptlabel);
6261    
6262  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6263  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  copy_ovector(common, re->top_bracket + 1);
   
6264  leave = LABEL();  leave = LABEL();
 copy_ovector(common);  
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0);  
6265  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6266    
6267  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6146  if (reqbyte_notfound != NULL) Line 6310  if (reqbyte_notfound != NULL)
6310    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6311  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6312  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));
6313  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6314  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6315    
6316  flush_stubs(common);  flush_stubs(common);
# Line 6199  sljit_emit_fast_return(compiler, SLJIT_M Line 6363  sljit_emit_fast_return(compiler, SLJIT_M
6363  /* Allocation failed. */  /* Allocation failed. */
6364  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6365  /* 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. */
6366  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6367  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6368    
6369  /* Call limit reached. */  /* Call limit reached. */
6370  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
6371  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6372  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6373    
6374  if (common->revertframes != NULL)  if (common->revertframes != NULL)
# Line 6389  pcre_assign_jit_stack(pcre_extra *extra, Line 6553  pcre_assign_jit_stack(pcre_extra *extra,
6553  {  {
6554  executable_function *function;  executable_function *function;
6555  if (extra != NULL &&  if (extra != NULL &&
6556      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6557      extra->executable_jit != NULL)      extra->executable_jit != NULL)
6558    {    {
6559    function = (executable_function*)extra->executable_jit;    function = (executable_function*)extra->executable_jit;
# Line 6400  if (extra != NULL && Line 6564  if (extra != NULL &&
6564    
6565  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
6566    
6567  /* 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
6568  being compiled. */  being compiled. */
6569    
6570  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *

Legend:
Removed from v.678  
changed lines
  Added in v.752

  ViewVC Help
Powered by ViewVC 1.1.5