/[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 675 by ph10, Sat Aug 27 10:18:46 2011 UTC revision 736 by zherczeg, Sun Oct 16 15:48:03 2011 UTC
# Line 119  The generated code will be the following Line 119  The generated code will be the following
119   jump to D hot path   jump to D hot path
120   C fallback path   C fallback path
121   A fallback path   A fallback path
122    
123   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
124   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
125   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    uschar *ptr;    uschar *ptr;
153    /* Everything else after. */    /* Everything else after. */
154    int offsetcount;    int offsetcount;
155      int calllimit;
156    uschar notbol;    uschar notbol;
157    uschar noteol;    uschar noteol;
158    uschar notempty;    uschar notempty;
# Line 169  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 280  typedef struct compiler_common { Line 281  typedef struct compiler_common {
281    recurse_entry *entries;    recurse_entry *entries;
282    recurse_entry *currententry;    recurse_entry *currententry;
283    jump_list *accept;    jump_list *accept;
284      jump_list *calllimit;
285    jump_list *stackalloc;    jump_list *stackalloc;
286    jump_list *revertframes;    jump_list *revertframes;
287    jump_list *wordboundary;    jump_list *wordboundary;
# Line 326  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 341  enum { Line 342  enum {
342  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
343  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
344  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
345  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
346  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
347    
348  /* Locals layout. */  /* Locals layout. */
# Line 351  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))
357    /* Max limit of recursions. */
358    #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     (6 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))
361  /* End pointer of the first line. */  /* End pointer of the first line. */
# Line 399  cc += 1 + LINK_SIZE; Line 400  cc += 1 + LINK_SIZE;
400  return cc;  return cc;
401  }  }
402    
403  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
404   next_opcode   next_opcode
405   get_localspace   get_localspace
406   set_localptrs   set_localptrs
# Line 466  switch(*cc) Line 467  switch(*cc)
467    case OP_SKIPZERO:    case OP_SKIPZERO:
468    return cc + 1;    return cc + 1;
469    
470      case OP_ANYBYTE:
471    #ifdef SUPPORT_UTF8
472      if (common->utf8) return NULL;
473    #endif
474      return cc + 1;
475    
476    case OP_CHAR:    case OP_CHAR:
477    case OP_CHARI:    case OP_CHARI:
478    case OP_NOT:    case OP_NOT:
# Line 568  switch(*cc) Line 575  switch(*cc)
575    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
576    case OP_REVERSE:    case OP_REVERSE:
577    case OP_ONCE:    case OP_ONCE:
578      case OP_ONCE_NC:
579    case OP_BRA:    case OP_BRA:
580    case OP_BRAPOS:    case OP_BRAPOS:
581    case OP_COND:    case OP_COND:
# Line 606  while (cc < ccend) Line 614  while (cc < ccend)
614      case OP_ASSERTBACK:      case OP_ASSERTBACK:
615      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
616      case OP_ONCE:      case OP_ONCE:
617        case OP_ONCE_NC:
618      case OP_BRAPOS:      case OP_BRAPOS:
619      case OP_SBRA:      case OP_SBRA:
620      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 651  while (cc < ccend) Line 660  while (cc < ccend)
660      case OP_ASSERTBACK:      case OP_ASSERTBACK:
661      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
662      case OP_ONCE:      case OP_ONCE:
663        case OP_ONCE_NC:
664      case OP_BRAPOS:      case OP_BRAPOS:
665      case OP_SBRA:      case OP_SBRA:
666      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 690  while (cc < ccend) Line 700  while (cc < ccend)
700  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)
701  {  {
702  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 uschar *end;  
703  int length = 0;  int length = 0;
704  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
705  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
706    
707  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
708    {    {
709    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
710    possessive = TRUE;    possessive = TRUE;
711    }    }
712    
# Line 719  while (cc < ccend) Line 725  while (cc < ccend)
725      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
726      break;      break;
727    
     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;  
   
728      case OP_CBRA:      case OP_CBRA:
729      case OP_CBRAPOS:      case OP_CBRAPOS:
730      case OP_SCBRA:      case OP_SCBRA:
731      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
732      length += 3;      length += 3;
733      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + 2;
734      break;      break;
# Line 761  while (cc < ccend) Line 740  while (cc < ccend)
740      }      }
741    
742  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
743  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
744    return -1;    return -1;
745    
746  if (length > 0)  if (length > 0)
747    return length + 2;    return length + 1;
748  return needs_frame ? 0 : -1;  return -1;
749  }  }
750    
751  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)
752  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
753  DEFINE_COMPILER;  DEFINE_COMPILER;
754  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
755  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
756  int offset;  int offset;
757    
758  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
759    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
760    
761  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);  
   
762  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
763    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
764  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 809  while (cc < ccend) Line 779  while (cc < ccend)
779      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
780      break;      break;
781    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
782      case OP_CBRA:      case OP_CBRA:
783      case OP_CBRAPOS:      case OP_CBRAPOS:
784      case OP_SCBRA:      case OP_SCBRA:
785      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;  
       }  
786      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
787      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
788      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 849  while (cc < ccend) Line 803  while (cc < ccend)
803      }      }
804    
805  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
806  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
807  }  }
808    
809  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)
# Line 866  while (cc < ccend) Line 820  while (cc < ccend)
820      case OP_ASSERTBACK:      case OP_ASSERTBACK:
821      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
822      case OP_ONCE:      case OP_ONCE:
823        case OP_ONCE_NC:
824      case OP_BRAPOS:      case OP_BRAPOS:
825      case OP_SBRA:      case OP_SBRA:
826      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 968  while (status != end) Line 923  while (status != end)
923        case OP_ASSERTBACK:        case OP_ASSERTBACK:
924        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
925        case OP_ONCE:        case OP_ONCE:
926          case OP_ONCE_NC:
927        case OP_BRAPOS:        case OP_BRAPOS:
928        case OP_SBRA:        case OP_SBRA:
929        case OP_SBRAPOS:        case OP_SBRAPOS:
# Line 1164  while (list_item) Line 1120  while (list_item)
1120      case stack_alloc:      case stack_alloc:
1121      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1122      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1123      }      }
1124    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1125    list_item = list_item->next;    list_item = list_item->next;
# Line 1175  while (list_item) Line 1127  while (list_item)
1127  common->stubs = NULL;  common->stubs = NULL;
1128  }  }
1129    
1130    static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1131    {
1132    DEFINE_COMPILER;
1133    
1134    OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1135    add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1136    }
1137    
1138  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1139  {  {
1140  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
# Line 1204  struct sljit_label *loop; Line 1164  struct sljit_label *loop;
1164  int i;  int i;
1165  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1166  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  
1167  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);
1168  if (length < 8)  if (length < 8)
1169    {    {
# Line 1222  else Line 1181  else
1181    }    }
1182  }  }
1183    
1184  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1185  {  {
1186  DEFINE_COMPILER;  DEFINE_COMPILER;
1187  struct sljit_label *loop;  struct sljit_label *loop;
1188  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1189    
1190  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1191    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1192    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1193    
1194  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1195  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));
1196  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
# Line 1244  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP Line 1206  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP
1206  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);
1207  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1208  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1209    
1210    /* Calculate the return value, which is the maximum ovector value. */
1211    if (topbracket > 1)
1212      {
1213      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1214      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1215    
1216      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1217      loop = LABEL();
1218      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1219      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1220      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1221      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1222      }
1223    else
1224      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1225  }  }
1226    
1227  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)
# Line 1364  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1342  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1342  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1343  if (common->utf8)  if (common->utf8)
1344    {    {
1345    /* 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);  
1346    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1347    JUMPHERE(jump);    JUMPHERE(jump);
1348    }    }
# Line 1386  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST Line 1363  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(ST
1363  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1364  if (common->utf8)  if (common->utf8)
1365    {    {
1366    /* 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);  
1367    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));
1368    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1369    JUMPHERE(jump);    JUMPHERE(jump);
# Line 1411  if (common->utf8) Line 1387  if (common->utf8)
1387    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1388    it is a clever early read in most cases. */    it is a clever early read in most cases. */
1389    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1390    /* 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);  
1391    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));
1392    JUMPHERE(jump);    JUMPHERE(jump);
1393    return;    return;
# Line 1472  else Line 1447  else
1447  static void do_utf8readchar(compiler_common *common)  static void do_utf8readchar(compiler_common *common)
1448  {  {
1449  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding an utf8 character. TMP1 contains the first byte
1450  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. */
1451  DEFINE_COMPILER;  DEFINE_COMPILER;
1452  struct sljit_jump *jump;  struct sljit_jump *jump;
1453    
# Line 1555  sljit_emit_fast_return(compiler, RETURN_ Line 1530  sljit_emit_fast_return(compiler, RETURN_
1530  static void do_utf8readtype8(compiler_common *common)  static void do_utf8readtype8(compiler_common *common)
1531  {  {
1532  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding an utf8 character type. TMP2 contains the first byte
1533  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */
1534  DEFINE_COMPILER;  DEFINE_COMPILER;
1535  struct sljit_jump *jump;  struct sljit_jump *jump;
1536  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1581  sljit_emit_fast_return(compiler, RETURN_ Line 1556  sljit_emit_fast_return(compiler, RETURN_
1556  JUMPHERE(jump);  JUMPHERE(jump);
1557    
1558  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1559  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);  
1560  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1561  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1562  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1626  struct sljit_label *newlinelabel = NULL; Line 1600  struct sljit_label *newlinelabel = NULL;
1600  struct sljit_jump *start;  struct sljit_jump *start;
1601  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1602  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1603    #ifdef SUPPORT_UTF8
1604    struct sljit_jump *singlebyte;
1605    #endif
1606  jump_list *newline = NULL;  jump_list *newline = NULL;
1607  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1608  BOOL readbyte = FALSE;  BOOL readbyte = FALSE;
# Line 1696  if (readbyte) Line 1673  if (readbyte)
1673  if (newlinecheck)  if (newlinecheck)
1674    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);
1675    
1676    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1677  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1678  if (common->utf8)  if (common->utf8)
1679    {    {
1680    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);
1681      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1682    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1683      JUMPHERE(singlebyte);
1684    }    }
 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);  
1685  #endif  #endif
1686  JUMPHERE(start);  JUMPHERE(start);
1687    
# Line 1758  else Line 1734  else
1734      }      }
1735    }    }
1736    
1737    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1738  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1739  if (common->utf8)  if (common->utf8)
1740    {    {
1741    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);
1742      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1743    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1744    }    }
 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);  
1745  #endif  #endif
1746  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1747  JUMPHERE(found);  JUMPHERE(found);
# Line 1874  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P Line 1848  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_P
1848  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1849  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1850  if (common->utf8)  if (common->utf8)
1851    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1852  #endif  #endif
1853  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
1854  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1885  found = JUMP(SLJIT_C_NOT_ZERO); Line 1859  found = JUMP(SLJIT_C_NOT_ZERO);
1859    
1860  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1861  if (common->utf8)  if (common->utf8)
1862    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1863  else  #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
1864  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1865    #ifdef SUPPORT_UTF8
1866    if (common->utf8)
1867      {
1868      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1869      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
1870      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1871      }
1872  #endif  #endif
1873  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1874  JUMPHERE(found);  JUMPHERE(found);
# Line 1957  return notfound; Line 1936  return notfound;
1936  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
1937  {  {
1938  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
1939  struct sljit_jump *jump;  struct sljit_jump *jump;
1940  struct sljit_label *mainloop;  struct sljit_label *mainloop;
1941    
1942  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);
1943  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1944    
1945  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
1946  mainloop = LABEL();  mainloop = LABEL();
1947  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1948  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1978  JUMPTO(SLJIT_JUMP, mainloop); Line 1955  JUMPTO(SLJIT_JUMP, mainloop);
1955  JUMPHERE(jump);  JUMPHERE(jump);
1956  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
1957  /* 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);  
1958  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1959    
1960  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);  
1961  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
1962  /* Set max index. */  /* Set string begin. */
1963  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
1964  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));
1965  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 2370  do Line 2336  do
2336        }        }
2337      context->byteptr = 0;      context->byteptr = 0;
2338      }      }
2339    
2340  #else  #else
2341    
2342    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
# Line 2432  uschar *ccbegin; Line 2398  uschar *ccbegin;
2398  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2399  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2400  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2401  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2402    unsigned int typeoffset;
2403  #endif  #endif
2404  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2405    unsigned int charoffset;
2406    
2407  /* 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. */
2408  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
# Line 2827  switch(type) Line 2795  switch(type)
2795    if (common->utf8)    if (common->utf8)
2796      {      {
2797      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2798      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);
2799        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2800        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
2801      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2802        JUMPHERE(jump[0]);
2803      return cc;      return cc;
2804      }      }
2805  #endif  #endif
2806    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2807    return cc;    return cc;
2808    
2809      case OP_ANYBYTE:
2810      check_input_end(common, fallbacks);
2811      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
2812      return cc;
2813    
2814  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2815  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2816    case OP_NOTPROP:    case OP_NOTPROP:
# Line 3081  switch(type) Line 3057  switch(type)
3057      if (c <= 127)      if (c <= 127)
3058        {        {
3059        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);  
3060        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3061          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));
3062        else        else
3063          {          {
3064          /* 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. */
3065          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3066          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));
3067          }          }
3068        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3069        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
3070          jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3071          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);
3072          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3073          JUMPHERE(jump[0]);
3074        return cc + length;        return cc + length;
3075        }        }
3076      else      else
# Line 3218  do Line 3197  do
3197        else if (cc[1] >= 0xc0)        else if (cc[1] >= 0xc0)
3198          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += _pcre_utf8_table4[cc[1] & 0x3f];
3199        }        }
3200      else      else
3201  #endif  #endif
3202      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)
3203        size = 0;        size = 0;
# Line 3455  if (!minimize) Line 3434  if (!minimize)
3434    
3435    JUMPHERE(zerolength);    JUMPHERE(zerolength);
3436    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3437    
3438      decrease_call_count(common);
3439    return cc;    return cc;
3440    }    }
3441    
# Line 3492  else if (max > 0) Line 3473  else if (max > 0)
3473  if (jump != NULL)  if (jump != NULL)
3474    JUMPHERE(jump);    JUMPHERE(jump);
3475  JUMPHERE(zerolength);  JUMPHERE(zerolength);
3476    
3477    decrease_call_count(common);
3478  return cc;  return cc;
3479  }  }
3480    
# Line 3624  while (1) Line 3607  while (1)
3607    if (common->accept != NULL)    if (common->accept != NULL)
3608      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3609    
3610      /* Reset stack. */
3611    if (framesize < 0)    if (framesize < 0)
3612      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3613      else {
3614        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3615          {
3616          /* We don't need to keep the STR_PTR, only the previous localptr. */
3617          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3618          }
3619        else
3620          {
3621          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3622          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3623          }
3624      }
3625    
3626    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3627      {      {
3628      /* 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. */
3629      if (conditional)      if (conditional)
3630        {        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));  
         }  
       }  
3631      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3632        {        {
3633        if (framesize < 0)        if (framesize < 0)
3634          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3635        else        else
3636          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3637          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));
3638          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));
3639          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3655  while (1) Line 3641  while (1)
3641        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));
3642        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3643        }        }
3644      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3645        {        {
3646        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3647          {        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));  
         }  
3648        }        }
3649      }      }
3650    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3689  if (opcode == OP_ASSERT || opcode == OP_ Line 3671  if (opcode == OP_ASSERT || opcode == OP_
3671    /* Assert is failed. */    /* Assert is failed. */
3672    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3673      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3674    
3675    if (framesize < 0)    if (framesize < 0)
3676      {      {
3677      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3700  if (opcode == OP_ASSERT || opcode == OP_ Line 3683  if (opcode == OP_ASSERT || opcode == OP_
3683    else    else
3684      {      {
3685      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));  
3686      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3687      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3688        {        {
# Line 3711  if (opcode == OP_ASSERT || opcode == OP_ Line 3692  if (opcode == OP_ASSERT || opcode == OP_
3692      else      else
3693        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3694      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);  
3695      }      }
3696    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3697    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3735  if (opcode == OP_ASSERT || opcode == OP_ Line 3714  if (opcode == OP_ASSERT || opcode == OP_
3714      }      }
3715    else    else
3716      {      {
3717      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)  
3718        {        {
3719        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3720        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));
3721          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3722        }        }
3723      else if (bra == OP_BRAMINZERO)      else
3724        {        {
3725        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3726        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));
3727          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3728          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
3729        }        }
3730      }      }
3731    
# Line 3782  else Line 3762  else
3762      {      {
3763      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3764      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));  
3765      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3766      if (bra != OP_BRA)      if (bra != OP_BRA)
3767        {        {
# Line 3793  else Line 3771  else
3771      else      else
3772        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3773      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);  
3774      }      }
3775    
3776    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3827  return cc + 1 + LINK_SIZE; Line 3803  return cc + 1 + LINK_SIZE;
3803      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
3804          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
3805      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.
3806      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.
3807      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
3808     () - opional values stored on the stack     () - opional values stored on the stack
3809    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3865  return cc + 1 + LINK_SIZE; Line 3841  return cc + 1 + LINK_SIZE;
3841      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.
3842    
3843    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
3844    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
3845    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
3846    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
3847                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
3848                                              Or nothing, if trace is unnecessary
3849  */  */
3850    
3851  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 3915  cc += GET(cc, 1); Line 3892  cc += GET(cc, 1);
3892  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;
3893  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
3894    opcode = OP_SCOND;    opcode = OP_SCOND;
3895    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
3896      opcode = OP_ONCE;
3897    
3898  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
3899    {    {
# Line 4054  if (opcode == OP_ONCE) Line 4033  if (opcode == OP_ONCE)
4033  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4034    {    {
4035    /* Saving the previous values. */    /* Saving the previous values. */
4036    allocate_stack(common, 4);    allocate_stack(common, 3);
4037    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4038    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));
4039    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4040    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4041    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);  
4042    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4043    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));  
4044    }    }
4045  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4046    {    {
# Line 4125  if (opcode == OP_ONCE) Line 4101  if (opcode == OP_ONCE)
4101        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);
4102        }        }
4103      }      }
4104    else if (ket == OP_KETRMAX)    else
4105      {      {
4106      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4107      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));
4108      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4109          {
4110          /* TMP2 which is set here used by OP_KETRMAX below. */
4111          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4112          }
4113      }      }
4114    }    }
4115    
# Line 4212  if (bra == OP_BRAMINZERO) Line 4192  if (bra == OP_BRAMINZERO)
4192    /* Continue to the normal fallback. */    /* Continue to the normal fallback. */
4193    }    }
4194    
4195    if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
4196      decrease_call_count(common);
4197    
4198  /* Skip the other alternatives. */  /* Skip the other alternatives. */
4199  while (*cc == OP_ALT)  while (*cc == OP_ALT)
4200    cc += GET(cc, 1);    cc += GET(cc, 1);
# Line 4270  framesize = get_framesize(common, cc, FA Line 4253  framesize = get_framesize(common, cc, FA
4253  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4254  if (framesize < 0)  if (framesize < 0)
4255    {    {
4256    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4257    if (!zero)    if (!zero)
4258      stacksize++;      stacksize++;
4259    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4283  if (framesize < 0) Line 4266  if (framesize < 0)
4266      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));
4267      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4268      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);  
4269      }      }
4270    else    else
4271      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 4341  while (*cc != OP_KETRPOS) Line 4323  while (*cc != OP_KETRPOS)
4323        {        {
4324        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4325        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));  
4326        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4327          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4328        }        }
4329      else      else
4330        {        {
# Line 4362  while (*cc != OP_KETRPOS) Line 4343  while (*cc != OP_KETRPOS)
4343      {      {
4344      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4345        {        {
4346          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4347        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);  
4348        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));  
4349        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4350          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4351        }        }
4352      else      else
4353        {        {
4354        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4355          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4356        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4357          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));
4358        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 4381  while (*cc != OP_KETRPOS) Line 4361  while (*cc != OP_KETRPOS)
4361      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4362        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));
4363    
     /* TMP2 must be set above. */  
4364      if (!zero)      if (!zero)
4365        {        {
4366        if (framesize < 0)        if (framesize < 0)
4367          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);
4368        else        else
4369          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);
4370        }        }
4371      }      }
4372    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4409  while (*cc != OP_KETRPOS) Line 4388  while (*cc != OP_KETRPOS)
4388      {      {
4389      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4390        {        {
4391          /* Last alternative. */
4392        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4393          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4394        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 4436  if (!zero) Line 4416  if (!zero)
4416    
4417  /* None of them matched. */  /* None of them matched. */
4418  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
4419    decrease_call_count(common);
4420  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4421  }  }
4422    
# Line 4696  switch(opcode) Line 4677  switch(opcode)
4677    break;    break;
4678    }    }
4679    
4680    decrease_call_count(common);
4681  return end;  return end;
4682  }  }
4683    
# Line 4746  return cc + 1; Line 4728  return cc + 1;
4728  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)
4729  {  {
4730  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
4731  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
4732    
4733  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
# Line 4755  if (common->currententry != NULL) Line 4736  if (common->currententry != NULL)
4736    
4737  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));
4738  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
4739  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);
4740  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);  
4741  return cc + 3;  return cc + 3;
4742  }  }
4743    
# Line 4785  while (cc < ccend) Line 4762  while (cc < ccend)
4762      case OP_WORDCHAR:      case OP_WORDCHAR:
4763      case OP_ANY:      case OP_ANY:
4764      case OP_ALLANY:      case OP_ALLANY:
4765        case OP_ANYBYTE:
4766      case OP_NOTPROP:      case OP_NOTPROP:
4767      case OP_PROP:      case OP_PROP:
4768      case OP_ANYNL:      case OP_ANYNL:
# Line 4939  while (cc < ccend) Line 4917  while (cc < ccend)
4917        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
4918        }        }
4919      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
4920        if (cc[1] > OP_ASSERTBACK_NOT)
4921          decrease_call_count(common);
4922      break;      break;
4923    
4924      case OP_ONCE:      case OP_ONCE:
4925        case OP_ONCE_NC:
4926      case OP_BRA:      case OP_BRA:
4927      case OP_CBRA:      case OP_CBRA:
4928      case OP_COND:      case OP_COND:
# Line 5172  static void compile_assert_fallbackpath( Line 5153  static void compile_assert_fallbackpath(
5153  DEFINE_COMPILER;  DEFINE_COMPILER;
5154  uschar *cc = current->cc;  uschar *cc = current->cc;
5155  uschar bra = OP_BRA;  uschar bra = OP_BRA;
 struct sljit_jump *jump;  
5156  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5157    
5158  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5218  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5198  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5198    {    {
5199    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);
5200    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5201      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));
5202    
5203    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5204    }    }
5205  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5206    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));  
5207    
5208  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5209    {    {
# Line 5277  if (opcode == OP_CBRA || opcode == OP_SC Line 5250  if (opcode == OP_CBRA || opcode == OP_SC
5250    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5251  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5252    opcode = OP_SCOND;    opcode = OP_SCOND;
5253    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5254      opcode = OP_ONCE;
5255    
5256  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5257    {    {
# Line 5427  if (*cc == OP_ALT || opcode == OP_COND | Line 5402  if (*cc == OP_ALT || opcode == OP_COND |
5402      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5403      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5404        {        {
5405        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5406          {          {
5407            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5408            /* TMP2 which is set here used by OP_KETRMAX below. */
5409          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5410              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5411            else if (ket == OP_KETRMIN)
5412            {            {
5413            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5414            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);
5415            }            }
5416          }          }
5417        else        else
5418          {          {
5419          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. */  
5420          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5421            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5422          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5423            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));
5424              }
5425          }          }
5426        }        }
5427    
# Line 5525  if (offset != 0) Line 5504  if (offset != 0)
5504    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5505    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5506    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);
5507    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));
5508    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);  
5509    }    }
5510  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5511    {    {
# Line 5542  else if (opcode == OP_ONCE) Line 5519  else if (opcode == OP_ONCE)
5519      {      {
5520      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
5521      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));  
5522      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);  
5523      }      }
5524    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
5525      {      {
# Line 5617  if (CURRENT_AS(bracketpos_fallback)->fra Line 5590  if (CURRENT_AS(bracketpos_fallback)->fra
5590      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5591      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5592      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));  
5593      }      }
5594    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5595    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5631  if (current->topfallbacks) Line 5603  if (current->topfallbacks)
5603    {    {
5604    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5605    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5606    /* 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));  
5607    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);  
5608    JUMPHERE(jump);    JUMPHERE(jump);
5609    }    }
5610  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 5768  while (current) Line 5738  while (current)
5738      break;      break;
5739    
5740      case OP_ONCE:      case OP_ONCE:
5741        case OP_ONCE_NC:
5742      case OP_BRA:      case OP_BRA:
5743      case OP_CBRA:      case OP_CBRA:
5744      case OP_COND:      case OP_COND:
# Line 5839  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST Line 5810  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), ST
5810  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
5811  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);
5812  if (needsframe)  if (needsframe)
   {  
   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + alternativesize - 1));  
5813    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
   }  
5814    
5815  if (alternativesize > 0)  if (alternativesize > 0)
5816    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 5879  while (1) Line 5847  while (1)
5847    }    }
5848  /* None of them matched. */  /* None of them matched. */
5849  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));  
5850  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
5851    
5852  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
# Line 5888  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 5854  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
5854  if (needsframe)  if (needsframe)
5855    {    {
5856    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5857    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));
5858    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5859    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));
5860    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
5861    }    }
5862  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
# Line 5915  fallback_common rootfallback; Line 5881  fallback_common rootfallback;
5881  compiler_common common_data;  compiler_common common_data;
5882  compiler_common *common = &common_data;  compiler_common *common = &common_data;
5883  const unsigned char *tables = re->tables;  const unsigned char *tables = re->tables;
5884  pcre_study_data *study = (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0 ? extra->study_data : NULL;  pcre_study_data *study;
5885  uschar *ccend;  uschar *ccend;
5886  executable_function *function;  executable_function *function;
5887  void *executable_func;  void *executable_func;
# Line 5927  struct sljit_jump *alloc_error; Line 5893  struct sljit_jump *alloc_error;
5893  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
5894  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
5895    
5896    SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
5897    study = extra->study_data;
5898    
5899  if (!tables)  if (!tables)
5900    tables = _pcre_default_tables;    tables = _pcre_default_tables;
5901    
# Line 5941  common->lcc = (sljit_w)(tables + lcc_off Line 5910  common->lcc = (sljit_w)(tables + lcc_off
5910  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
5911  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
5912    {    {
5913    case 0: common->newline = NEWLINE; break;   /* Compile-time default */    case 0:
5914      /* Compile-time default */
5915      switch (NEWLINE)
5916        {
5917        case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
5918        case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
5919        default: common->newline = NEWLINE; break;
5920        }
5921      break;
5922    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
5923    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
5924    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
# Line 5969  common->stubs = NULL; Line 5946  common->stubs = NULL;
5946  common->entries = NULL;  common->entries = NULL;
5947  common->currententry = NULL;  common->currententry = NULL;
5948  common->accept = NULL;  common->accept = NULL;
5949    common->calllimit = NULL;
5950  common->stackalloc = NULL;  common->stackalloc = NULL;
5951  common->revertframes = NULL;  common->revertframes = NULL;
5952  common->wordboundary = NULL;  common->wordboundary = NULL;
# Line 6018  sljit_emit_enter(compiler, 1, 5, 5, comm Line 5996  sljit_emit_enter(compiler, 1, 5, 5, comm
5996  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
5997  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
5998    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);  
5999    
6000  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);
6001  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);
6002  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6003  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6004  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6005    OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
6006  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
6007  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6008    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6009    
6010  /* Main part of the matching */  /* Main part of the matching */
6011  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
# Line 6045  if ((re->flags & PCRE_REQCHSET) != 0) Line 6024  if ((re->flags & PCRE_REQCHSET) != 0)
6024    
6025  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6026  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);
6027    /* Copy the limit of allowed recursions. */
6028    OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6029    
6030  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6031  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6062  if (common->accept != NULL) Line 6043  if (common->accept != NULL)
6043    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->acceptlabel);
6044    
6045  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6046  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  copy_ovector(common, re->top_bracket + 1);
   
6047  leave = LABEL();  leave = LABEL();
 copy_ovector(common);  
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0);  
6048  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6049    
6050  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6115  if (reqbyte_notfound != NULL) Line 6093  if (reqbyte_notfound != NULL)
6093    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6094  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6095  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));
6096  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6097  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6098    
6099  flush_stubs(common);  flush_stubs(common);
# Line 6145  while (common->currententry != NULL) Line 6123  while (common->currententry != NULL)
6123    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
6124    }    }
6125    
6126  /* Allocating stack, returns with PCRE_ERROR_NOMEMORY if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
6127  /* This is a (really) rare case. */  /* This is a (really) rare case. */
6128  set_jumps(common->stackalloc, LABEL());  set_jumps(common->stackalloc, LABEL());
6129  /* RETURN_ADDR is not a saved register. */  /* RETURN_ADDR is not a saved register. */
# Line 6168  sljit_emit_fast_return(compiler, SLJIT_M Line 6146  sljit_emit_fast_return(compiler, SLJIT_M
6146  /* Allocation failed. */  /* Allocation failed. */
6147  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6148  /* 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. */
6149  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMEMORY);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6150    JUMPTO(SLJIT_JUMP, leave);
6151    
6152    /* Call limit reached. */
6153    set_jumps(common->calllimit, LABEL());
6154    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6155  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6156    
6157  if (common->revertframes != NULL)  if (common->revertframes != NULL)
# Line 6268  return convert_executable_func.call_exec Line 6251  return convert_executable_func.call_exec
6251    
6252  int  int
6253  _pcre_jit_exec(const real_pcre *re, void *executable_func,  _pcre_jit_exec(const real_pcre *re, void *executable_func,
6254    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options,
6255    int offsetcount)    int match_limit, int *offsets, int offsetcount)
6256  {  {
6257  executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
6258  union {  union {
# Line 6285  arguments.stack = NULL; Line 6268  arguments.stack = NULL;
6268  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
6269  arguments.begin = subject;  arguments.begin = subject;
6270  arguments.end = subject + length;  arguments.end = subject + length;
6271    arguments.calllimit = match_limit; /* JIT decreases this value less times. */
6272  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
6273  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
6274  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 6351  PCRE_EXP_DECL void Line 6335  PCRE_EXP_DECL void
6335  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6336  {  {
6337  executable_function *function;  executable_function *function;
6338  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)  if (extra != NULL &&
6339        (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6340        extra->executable_jit != NULL)
6341    {    {
6342    function = (executable_function*)extra->executable_jit;    function = (executable_function*)extra->executable_jit;
6343    function->callback = callback;    function->callback = callback;
# Line 6361  if ((extra->flags & PCRE_EXTRA_EXECUTABL Line 6347  if ((extra->flags & PCRE_EXTRA_EXECUTABL
6347    
6348  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
6349    
6350  /* 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
6351  being compiled. */  being compiled. */
6352    
6353  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *

Legend:
Removed from v.675  
changed lines
  Added in v.736

  ViewVC Help
Powered by ViewVC 1.1.5