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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 695 by zherczeg, Sat Sep 17 06:05:38 2011 UTC revision 726 by zherczeg, Sun Oct 9 18:53:25 2011 UTC
# Line 170  typedef struct jump_list { Line 170  typedef struct jump_list {
170    struct jump_list *next;    struct jump_list *next;
171  } jump_list;  } jump_list;
172    
173  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
174    
175  typedef struct stub_list {  typedef struct stub_list {
176    enum stub_types type;    enum stub_types type;
# Line 328  typedef struct compare_context { Line 328  typedef struct compare_context {
328    
329  enum {  enum {
330    frame_end = 0,    frame_end = 0,
331    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
332  };  };
333    
334  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
# Line 353  enum { Line 352  enum {
352  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
353  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
354  #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))  
355  /* Head of the last recursion. */  /* Head of the last recursion. */
356  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
 /* Number of recursions. */  
 #define MAX_INDEX        (6 * sizeof(sljit_w))  
357  /* Max limit of recursions. */  /* Max limit of recursions. */
358  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
359  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
360  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
361  /* End pointer of the first line. */  /* End pointer of the first line. */
362  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
363  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
364  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
365  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
366  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. */
367  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
368  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
369  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
370  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 574  switch(*cc) Line 569  switch(*cc)
569    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
570    case OP_REVERSE:    case OP_REVERSE:
571    case OP_ONCE:    case OP_ONCE:
572      case OP_ONCE_NC:
573    case OP_BRA:    case OP_BRA:
574    case OP_BRAPOS:    case OP_BRAPOS:
575    case OP_COND:    case OP_COND:
# Line 612  while (cc < ccend) Line 608  while (cc < ccend)
608      case OP_ASSERTBACK:      case OP_ASSERTBACK:
609      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
610      case OP_ONCE:      case OP_ONCE:
611        case OP_ONCE_NC:
612      case OP_BRAPOS:      case OP_BRAPOS:
613      case OP_SBRA:      case OP_SBRA:
614      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 657  while (cc < ccend) Line 654  while (cc < ccend)
654      case OP_ASSERTBACK:      case OP_ASSERTBACK:
655      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
656      case OP_ONCE:      case OP_ONCE:
657        case OP_ONCE_NC:
658      case OP_BRAPOS:      case OP_BRAPOS:
659      case OP_SBRA:      case OP_SBRA:
660      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 696  while (cc < ccend) Line 694  while (cc < ccend)
694  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)
695  {  {
696  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 uschar *end;  
697  int length = 0;  int length = 0;
698  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
699  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
700    
701  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
702    {    {
703    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
704    possessive = TRUE;    possessive = TRUE;
705    }    }
706    
# Line 725  while (cc < ccend) Line 719  while (cc < ccend)
719      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
720      break;      break;
721    
     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;  
   
722      case OP_CBRA:      case OP_CBRA:
723      case OP_CBRAPOS:      case OP_CBRAPOS:
724      case OP_SCBRA:      case OP_SCBRA:
725      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
726      length += 3;      length += 3;
727      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + 2;
728      break;      break;
# Line 767  while (cc < ccend) Line 734  while (cc < ccend)
734      }      }
735    
736  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
737  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
738    return -1;    return -1;
739    
740  if (length > 0)  if (length > 0)
741    return length + 2;    return length + 1;
742  return needs_frame ? 0 : -1;  return -1;
743  }  }
744    
745  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)
746  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
747  DEFINE_COMPILER;  DEFINE_COMPILER;
748  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
749  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
750  int offset;  int offset;
751    
752  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
753    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
754    
755  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);  
   
756  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
757    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
758  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 815  while (cc < ccend) Line 773  while (cc < ccend)
773      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
774      break;      break;
775    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
776      case OP_CBRA:      case OP_CBRA:
777      case OP_CBRAPOS:      case OP_CBRAPOS:
778      case OP_SCBRA:      case OP_SCBRA:
779      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
       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, TMP1, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
780      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
781      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
782      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 856  while (cc < ccend) Line 797  while (cc < ccend)
797      }      }
798    
799  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
800  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
801  }  }
802    
803  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 873  while (cc < ccend) Line 814  while (cc < ccend)
814      case OP_ASSERTBACK:      case OP_ASSERTBACK:
815      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
816      case OP_ONCE:      case OP_ONCE:
817        case OP_ONCE_NC:
818      case OP_BRAPOS:      case OP_BRAPOS:
819      case OP_SBRA:      case OP_SBRA:
820      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 975  while (status != end) Line 917  while (status != end)
917        case OP_ASSERTBACK:        case OP_ASSERTBACK:
918        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
919        case OP_ONCE:        case OP_ONCE:
920          case OP_ONCE_NC:
921        case OP_BRAPOS:        case OP_BRAPOS:
922        case OP_SBRA:        case OP_SBRA:
923        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1171  while (list_item) Line 1114  while (list_item)
1114      case stack_alloc:      case stack_alloc:
1115      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1116      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, list_item->data);  
     break;  
1117      }      }
1118    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1119    list_item = list_item->next;    list_item = list_item->next;
# Line 1219  struct sljit_label *loop; Line 1158  struct sljit_label *loop;
1158  int i;  int i;
1159  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1160  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, 1);  
1161  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);
1162  if (length < 8)  if (length < 8)
1163    {    {
# Line 1237  else Line 1175  else
1175    }    }
1176  }  }
1177    
1178  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1179  {  {
1180  DEFINE_COMPILER;  DEFINE_COMPILER;
1181  struct sljit_label *loop;  struct sljit_label *loop;
1182  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1183    
1184  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1185    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1186    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1187    
1188  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1189  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));
1190  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 1259  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP Line 1200  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP
1200  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);
1201  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1202  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1203    
1204    /* Calculate the return value, which is the maximum ovector value. */
1205    if (topbracket > 1)
1206      {
1207      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1208      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1209    
1210      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1211      loop = LABEL();
1212      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1213      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1214      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1215      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1216      }
1217    else
1218      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1219  }  }
1220    
1221  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 1972  return notfound; Line 1929  return notfound;
1929  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1930  {  {
1931  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1932  struct sljit_jump *jump;  struct sljit_jump *jump;
1933  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1934    
1935  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);
1936  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1937    
1938  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1939  mainloop = LABEL();  mainloop = LABEL();
1940  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1941  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 1993  JUMPTO(SLJIT_JUMP, mainloop); Line 1948  JUMPTO(SLJIT_JUMP, mainloop);
1948  JUMPHERE(jump);  JUMPHERE(jump);
1949  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1950  /* 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);  
1951  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1952    
1953  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
1954  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
1955  /* Set max index. */  /* Set string begin. */
1956  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
1957  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));
1958  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 2448  uschar *ccbegin; Line 2391  uschar *ccbegin;
2391  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2392  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2393  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2394  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2395    unsigned int typeoffset;
2396  #endif  #endif
2397  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2398    unsigned int charoffset;
2399    
2400  /* 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. */
2401  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
# Line 3644  while (1) Line 3589  while (1)
3589    if (common->accept != NULL)    if (common->accept != NULL)
3590      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3591    
3592      /* Reset stack. */
3593    if (framesize < 0)    if (framesize < 0)
3594      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3595      else {
3596        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3597          {
3598          /* We don't need to keep the STR_PTR, only the previous localptr. */
3599          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3600          }
3601        else
3602          {
3603          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3604          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3605          }
3606      }
3607    
3608    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3609      {      {
3610      /* 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. */
3611      if (conditional)      if (conditional)
3612        {        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));  
         }  
       }  
3613      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3614        {        {
3615        if (framesize < 0)        if (framesize < 0)
3616          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3617        else        else
3618          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3619          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));
3620          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));
3621          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3675  while (1) Line 3623  while (1)
3623        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));
3624        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3625        }        }
3626      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3627        {        {
3628        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3629          {        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));  
         }  
3630        }        }
3631      }      }
3632    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3709  if (opcode == OP_ASSERT || opcode == OP_ Line 3653  if (opcode == OP_ASSERT || opcode == OP_
3653    /* Assert is failed. */    /* Assert is failed. */
3654    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3655      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3656    
3657    if (framesize < 0)    if (framesize < 0)
3658      {      {
3659      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3720  if (opcode == OP_ASSERT || opcode == OP_ Line 3665  if (opcode == OP_ASSERT || opcode == OP_
3665    else    else
3666      {      {
3667      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));  
3668      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3669      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3670        {        {
# Line 3731  if (opcode == OP_ASSERT || opcode == OP_ Line 3674  if (opcode == OP_ASSERT || opcode == OP_
3674      else      else
3675        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3676      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);  
3677      }      }
3678    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3679    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3755  if (opcode == OP_ASSERT || opcode == OP_ Line 3696  if (opcode == OP_ASSERT || opcode == OP_
3696      }      }
3697    else    else
3698      {      {
3699      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)  
3700        {        {
3701        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3702        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));
3703          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3704        }        }
3705      else if (bra == OP_BRAMINZERO)      else
3706        {        {
3707        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3708        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));
3709          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3710          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3711        }        }
3712      }      }
3713    
# Line 3802  else Line 3744  else
3744      {      {
3745      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3746      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));  
3747      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3748      if (bra != OP_BRA)      if (bra != OP_BRA)
3749        {        {
# Line 3813  else Line 3753  else
3753      else      else
3754        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3755      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);  
3756      }      }
3757    
3758    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3847  return cc + 1 + LINK_SIZE; Line 3785  return cc + 1 + LINK_SIZE;
3785      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
3786          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
3787      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.
3788      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.
3789      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
3790     () - opional values stored on the stack     () - opional values stored on the stack
3791    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3885  return cc + 1 + LINK_SIZE; Line 3823  return cc + 1 + LINK_SIZE;
3823      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.
3824    
3825    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3826    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3827    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3828    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3829                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3830                                              Or nothing, if trace is unnecessary
3831  */  */
3832    
3833  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 3935  cc += GET(cc, 1); Line 3874  cc += GET(cc, 1);
3874  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;
3875  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
3876    opcode = OP_SCOND;    opcode = OP_SCOND;
3877    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
3878      opcode = OP_ONCE;
3879    
3880  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
3881    {    {
# Line 4074  if (opcode == OP_ONCE) Line 4015  if (opcode == OP_ONCE)
4015  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4016    {    {
4017    /* Saving the previous values. */    /* Saving the previous values. */
4018    allocate_stack(common, 4);    allocate_stack(common, 3);
4019    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4020    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));
4021    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4022    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4023    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4024    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4025    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP2, 0);  
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, (offset >> 1) + 1));  
4026    }    }
4027  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4028    {    {
# Line 4146  if (opcode == OP_ONCE) Line 4083  if (opcode == OP_ONCE)
4083        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);
4084        }        }
4085      }      }
4086    else if (ket == OP_KETRMAX)    else
4087      {      {
4088      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4089      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));
4090      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4091          {
4092          /* TMP2 which is set here used by OP_KETRMAX below. */
4093          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4094          }
4095      }      }
4096    }    }
4097    
# Line 4294  framesize = get_framesize(common, cc, FA Line 4235  framesize = get_framesize(common, cc, FA
4235  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4236  if (framesize < 0)  if (framesize < 0)
4237    {    {
4238    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4239    if (!zero)    if (!zero)
4240      stacksize++;      stacksize++;
4241    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4306  if (framesize < 0) Line 4247  if (framesize < 0)
4247      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4248      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));
4249      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4250      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), TMP1, 0);  
4251      }      }
4252    else    else
4253      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 4365  while (*cc != OP_KETRPOS) Line 4304  while (*cc != OP_KETRPOS)
4304      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4305        {        {
4306        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4307        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, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));  
4308        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4309          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4310        }        }
4311      else      else
4312        {        {
# Line 4388  while (*cc != OP_KETRPOS) Line 4325  while (*cc != OP_KETRPOS)
4325      {      {
4326      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4327        {        {
4328          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4329        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4330        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, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));  
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4331        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4332          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4333        }        }
4334      else      else
4335        {        {
4336        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4337          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4338        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4339          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));
4340        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 4408  while (*cc != OP_KETRPOS) Line 4343  while (*cc != OP_KETRPOS)
4343      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4344        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));
4345    
     /* TMP2 must be set above. */  
4346      if (!zero)      if (!zero)
4347        {        {
4348        if (framesize < 0)        if (framesize < 0)
4349          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);
4350        else        else
4351          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);
4352        }        }
4353      }      }
4354    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4436  while (*cc != OP_KETRPOS) Line 4370  while (*cc != OP_KETRPOS)
4370      {      {
4371      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4372        {        {
4373          /* Last alternative. */
4374        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4375          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4376        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 4775  return cc + 1; Line 4710  return cc + 1;
4710  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)
4711  {  {
4712  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
4713  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
4714    
4715  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
# Line 4783  if (common->currententry != NULL) Line 4717  if (common->currententry != NULL)
4717    return cc + 3;    return cc + 3;
4718    
4719  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));
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4720  offset <<= 1;  offset <<= 1;
4721  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);
4722  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
 offset = (offset >> 1) + 1;  
 jump = CMP(SLJIT_C_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, offset);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, offset);  
 JUMPHERE(jump);  
4723  return cc + 3;  return cc + 3;
4724  }  }
4725    
# Line 4974  while (cc < ccend) Line 4903  while (cc < ccend)
4903      break;      break;
4904    
4905      case OP_ONCE:      case OP_ONCE:
4906        case OP_ONCE_NC:
4907      case OP_BRA:      case OP_BRA:
4908      case OP_CBRA:      case OP_CBRA:
4909      case OP_COND:      case OP_COND:
# Line 5204  static void compile_assert_fallbackpath( Line 5134  static void compile_assert_fallbackpath(
5134  DEFINE_COMPILER;  DEFINE_COMPILER;
5135  uschar *cc = current->cc;  uschar *cc = current->cc;
5136  uschar bra = OP_BRA;  uschar bra = OP_BRA;
 struct sljit_jump *jump;  
5137  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5138    
5139  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5250  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5179  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5179    {    {
5180    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);
5181    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5182      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));
5183    
5184    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5185    }    }
5186  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5187    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));  
5188    
5189  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5190    {    {
# Line 5309  if (opcode == OP_CBRA || opcode == OP_SC Line 5231  if (opcode == OP_CBRA || opcode == OP_SC
5231    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5232  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5233    opcode = OP_SCOND;    opcode = OP_SCOND;
5234    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5235      opcode = OP_ONCE;
5236    
5237  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5238    {    {
# Line 5459  if (*cc == OP_ALT || opcode == OP_COND | Line 5383  if (*cc == OP_ALT || opcode == OP_COND |
5383      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5384      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5385        {        {
5386        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5387          {          {
5388            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5389            /* TMP2 which is set here used by OP_KETRMAX below. */
5390          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5391              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5392            else if (ket == OP_KETRMIN)
5393            {            {
5394            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5395            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);
5396            }            }
5397          }          }
5398        else        else
5399          {          {
5400          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. */  
5401          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5402            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5403          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5404            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));
5405              }
5406          }          }
5407        }        }
5408    
# Line 5557  if (offset != 0) Line 5485  if (offset != 0)
5485    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5486    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5487    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);
5488    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
5489    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(3));    free_stack(common, 3);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0);  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);  
   free_stack(common, 4);  
5490    }    }
5491  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5492    {    {
# Line 5575  else if (opcode == OP_ONCE) Line 5500  else if (opcode == OP_ONCE)
5500      {      {
5501      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5502      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));  
5503      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);  
5504      }      }
5505    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5506      {      {
# Line 5649  if (CURRENT_AS(bracketpos_fallback)->fra Line 5570  if (CURRENT_AS(bracketpos_fallback)->fra
5570      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5571      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5572      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
5573      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, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0);  
5574      }      }
5575    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5576    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5665  if (current->topfallbacks) Line 5584  if (current->topfallbacks)
5584    {    {
5585    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5586    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5587    /* 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));  
5588    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);  
5589    JUMPHERE(jump);    JUMPHERE(jump);
5590    }    }
5591  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 5802  while (current) Line 5719  while (current)
5719      break;      break;
5720    
5721      case OP_ONCE:      case OP_ONCE:
5722        case OP_ONCE_NC:
5723      case OP_BRA:      case OP_BRA:
5724      case OP_CBRA:      case OP_CBRA:
5725      case OP_COND:      case OP_COND:
# Line 5873  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 5791  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
5791  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
5792  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);
5793  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
5794    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
5795    
5796  if (alternativesize > 0)  if (alternativesize > 0)
5797    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 5913  while (1) Line 5828  while (1)
5828    }    }
5829  /* None of them matched. */  /* None of them matched. */
5830  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));  
5831  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
5832    
5833  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5922  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 5835  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
5835  if (needsframe)  if (needsframe)
5836    {    {
5837    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5838    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));
5839    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5840    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));
5841    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
5842    }    }
5843  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 5978  common->lcc = (sljit_w)(tables + lcc_off Line 5891  common->lcc = (sljit_w)(tables + lcc_off
5891  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
5892  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
5893    {    {
5894    case 0:    case 0:
5895    /* Compile-time default */    /* Compile-time default */
5896    switch (NEWLINE)    switch (NEWLINE)
5897      {      {
# Line 6064  sljit_emit_enter(compiler, 1, 5, 5, comm Line 5977  sljit_emit_enter(compiler, 1, 5, 5, comm
5977  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
5978  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
5979    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);  
5980    
5981  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
5982  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);
# Line 6112  if (common->accept != NULL) Line 6024  if (common->accept != NULL)
6024    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->acceptlabel);
6025    
6026  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6027  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  copy_ovector(common, re->top_bracket + 1);
   
6028  leave = LABEL();  leave = LABEL();
 copy_ovector(common);  
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
6029  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6030    
6031  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6165  if (reqbyte_notfound != NULL) Line 6074  if (reqbyte_notfound != NULL)
6074    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6075  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6076  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));
6077  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6078  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6079    
6080  flush_stubs(common);  flush_stubs(common);
# Line 6218  sljit_emit_fast_return(compiler, SLJIT_M Line 6127  sljit_emit_fast_return(compiler, SLJIT_M
6127  /* Allocation failed. */  /* Allocation failed. */
6128  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6129  /* 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. */
6130  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6131  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6132    
6133  /* Call limit reached. */  /* Call limit reached. */
6134  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
6135  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6136  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6137    
6138  if (common->revertframes != NULL)  if (common->revertframes != NULL)

Legend:
Removed from v.695  
changed lines
  Added in v.726

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12