/[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 993 by zherczeg, Tue Jul 10 04:33:00 2012 UTC revision 1051 by zherczeg, Tue Oct 2 08:18:24 2012 UTC
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 89  vertical (sub-expression) (See struct ba Line 92  vertical (sub-expression) (See struct ba
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
95  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
97  branches on the try path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Try path: match happens.     Matching path: match happens.
101     Backtrack path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Try path: no need to perform a match.     Matching path: no need to perform a match.
104     Backtrack path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A try path   A matching path
115   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B try path   B matching path
117   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D try path   D matching path
119   return with successful match   return with successful match
120    
121   D backtrack path   D backtrack path
122   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
123   B backtrack path   B backtrack path
124   C expected path   C expected path
125   jump to D try path   jump to D matching path
126   C backtrack path   C backtrack path
127   A backtrack path   A backtrack path
128    
# Line 127  The generated code will be the following Line 130  The generated code will be the following
130   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
131   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
132   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
133   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 188  typedef struct stub_list { Line 191  typedef struct stub_list {
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct backtrack_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
# Line 208  typedef struct assert_backtrack { Line 211  typedef struct assert_backtrack {
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *trypath;    struct sljit_label *matchingpath;
217  } assert_backtrack;  } assert_backtrack;
218    
219  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
220    backtrack_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 230  typedef struct bracket_backtrack { Line 233  typedef struct bracket_backtrack {
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_backtrack;  } bracket_backtrack;
238    
239  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
240    backtrack_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
# Line 245  typedef struct bracketpos_backtrack { Line 248  typedef struct bracketpos_backtrack {
248    
249  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
250    backtrack_common common;    backtrack_common common;
251    struct sljit_label *trypath;    struct sljit_label *matchingpath;
252  } braminzero_backtrack;  } braminzero_backtrack;
253    
254  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
255    backtrack_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *trypath;    struct sljit_label *matchingpath;
258  } iterator_backtrack;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 274  typedef struct compiler_common { Line 277  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    
280    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
281    int *localptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 404  enum { Line 410  enum {
410  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
411  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
412    
413  /* Locals layout. */  /* Local space layout. */
414  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
415  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
416  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 420  the start pointers when the end of the c Line 426  the start pointers when the end of the c
426  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
427  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
428  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
429  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
430    
431  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
432  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
# Line 469  return cc; Line 475  return cc;
475    
476  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
477   next_opcode   next_opcode
478   get_localspace   get_private_data_length
479   set_localptrs   set_private_data_ptrs
480   get_framesize   get_framesize
481   init_frame   init_frame
482   get_localsize   get_private_data_length_for_copy
483   copy_locals   copy_private_data
484   compile_trypath   compile_matchingpath
485   compile_backtrackpath   compile_backtrackingpath
486  */  */
487    
488  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 675  switch(*cc) Line 681  switch(*cc)
681    }    }
682  }  }
683    
684  #define CASE_ITERATOR_LOCAL1 \  #define CASE_ITERATOR_PRIVATE_DATA_1 \
685      case OP_MINSTAR: \      case OP_MINSTAR: \
686      case OP_MINPLUS: \      case OP_MINPLUS: \
687      case OP_QUERY: \      case OP_QUERY: \
# Line 693  switch(*cc) Line 699  switch(*cc)
699      case OP_NOTQUERYI: \      case OP_NOTQUERYI: \
700      case OP_NOTMINQUERYI:      case OP_NOTMINQUERYI:
701    
702  #define CASE_ITERATOR_LOCAL2A \  #define CASE_ITERATOR_PRIVATE_DATA_2A \
703      case OP_STAR: \      case OP_STAR: \
704      case OP_PLUS: \      case OP_PLUS: \
705      case OP_STARI: \      case OP_STARI: \
# Line 703  switch(*cc) Line 709  switch(*cc)
709      case OP_NOTSTARI: \      case OP_NOTSTARI: \
710      case OP_NOTPLUSI:      case OP_NOTPLUSI:
711    
712  #define CASE_ITERATOR_LOCAL2B \  #define CASE_ITERATOR_PRIVATE_DATA_2B \
713      case OP_UPTO: \      case OP_UPTO: \
714      case OP_MINUPTO: \      case OP_MINUPTO: \
715      case OP_UPTOI: \      case OP_UPTOI: \
# Line 713  switch(*cc) Line 719  switch(*cc)
719      case OP_NOTUPTOI: \      case OP_NOTUPTOI: \
720      case OP_NOTMINUPTOI:      case OP_NOTMINUPTOI:
721    
722  #define CASE_ITERATOR_TYPE_LOCAL1 \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
723      case OP_TYPEMINSTAR: \      case OP_TYPEMINSTAR: \
724      case OP_TYPEMINPLUS: \      case OP_TYPEMINPLUS: \
725      case OP_TYPEQUERY: \      case OP_TYPEQUERY: \
726      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
727    
728  #define CASE_ITERATOR_TYPE_LOCAL2A \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
729      case OP_TYPESTAR: \      case OP_TYPESTAR: \
730      case OP_TYPEPLUS:      case OP_TYPEPLUS:
731    
732  #define CASE_ITERATOR_TYPE_LOCAL2B \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
733      case OP_TYPEUPTO: \      case OP_TYPEUPTO: \
734      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
735    
# Line 752  switch(*cc) Line 758  switch(*cc)
758    }    }
759  }  }
760    
761  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
762  {  {
763  int localspace = 0;  int private_data_length = 0;
764  pcre_uchar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
767  int space, size, bracketlen;  int space, size, bracketlen, i;
768    
769  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
770  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 779  while (cc < ccend)
779      cc += 1;      cc += 1;
780      break;      break;
781    
782        case OP_REF:
783        case OP_REFI:
784        common->optimized_cbracket[GET2(cc, 1)] = 0;
785        cc += 1 + IMM2_SIZE;
786        break;
787    
788      case OP_ASSERT:      case OP_ASSERT:
789      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
790      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 781  while (cc < ccend) Line 794  while (cc < ccend)
794      case OP_BRAPOS:      case OP_BRAPOS:
795      case OP_SBRA:      case OP_SBRA:
796      case OP_SBRAPOS:      case OP_SBRAPOS:
797      case OP_SCOND:      private_data_length += sizeof(sljit_w);
     localspace += sizeof(sljit_w);  
798      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
799      break;      break;
800    
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
804        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
806      break;      break;
807    
808      case OP_COND:      case OP_COND:
809      /* Might be a hidden SCOND. */      case OP_SCOND:
810      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
811      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
812        localspace += sizeof(sljit_w);        {
813          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
814          common->optimized_cbracket[bracketlen] = 0;
815          }
816        else if (bracketlen == OP_NCREF)
817          {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          name = (pcre_uchar *)common->name_table;
820          alternative = name;
821          for (i = 0; i < common->name_count; i++)
822            {
823            if (GET2(name, 0) == bracketlen) break;
824            name += common->name_entry_size;
825            }
826          SLJIT_ASSERT(i != common->name_count);
827    
828          for (i = 0; i < common->name_count; i++)
829            {
830            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
831              common->optimized_cbracket[GET2(alternative, 0)] = 0;
832            alternative += common->name_entry_size;
833            }
834          }
835    
836        if (*cc == OP_COND)
837          {
838          /* Might be a hidden SCOND. */
839          alternative = cc + GET(cc, 1);
840          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
841            private_data_length += sizeof(sljit_w);
842          }
843        else
844          private_data_length += sizeof(sljit_w);
845      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
846      break;      break;
847    
# Line 809  while (cc < ccend) Line 854  while (cc < ccend)
854      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
855      break;      break;
856    
857      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
858      space = 1;      space = 1;
859      size = -2;      size = -2;
860      break;      break;
861    
862      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
863      space = 2;      space = 2;
864      size = -2;      size = -2;
865      break;      break;
866    
867      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
868      space = 2;      space = 2;
869      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
870      break;      break;
871    
872      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
873      space = 1;      space = 1;
874      size = 1;      size = 1;
875      break;      break;
876    
877      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
878      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
879        space = 2;        space = 2;
880      size = 1;      size = 1;
881      break;      break;
882    
883      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
884      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
885        space = 2;        space = 2;
886      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 881  while (cc < ccend) Line 926  while (cc < ccend)
926      }      }
927    
928    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
929      localspace += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_w) * space;
930    
931    if (size != 0)    if (size != 0)
932      {      {
# Line 907  while (cc < ccend) Line 952  while (cc < ccend)
952      cc += bracketlen;      cc += bracketlen;
953      }      }
954    }    }
955  return localspace;  return private_data_length;
956  }  }
957    
958  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
959  {  {
960  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
961  pcre_uchar *alternative;  pcre_uchar *alternative;
# Line 934  while (cc < ccend) Line 979  while (cc < ccend)
979      case OP_SBRA:      case OP_SBRA:
980      case OP_SBRAPOS:      case OP_SBRAPOS:
981      case OP_SCOND:      case OP_SCOND:
982      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
983      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
984      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
985      break;      break;
986    
987      case OP_CBRAPOS:      case OP_CBRAPOS:
988      case OP_SCBRAPOS:      case OP_SCBRAPOS:
989      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
990      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
991      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
# Line 951  while (cc < ccend) Line 996  while (cc < ccend)
996      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
997      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
998        {        {
999        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1000        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1001        }        }
1002      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1003      break;      break;
# Line 966  while (cc < ccend) Line 1011  while (cc < ccend)
1011      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1012      break;      break;
1013    
1014      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1015      space = 1;      space = 1;
1016      size = -2;      size = -2;
1017      break;      break;
1018    
1019      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1020      space = 2;      space = 2;
1021      size = -2;      size = -2;
1022      break;      break;
1023    
1024      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1025      space = 2;      space = 2;
1026      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
1027      break;      break;
1028    
1029      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1030      space = 1;      space = 1;
1031      size = 1;      size = 1;
1032      break;      break;
1033    
1034      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1035      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1036        space = 2;        space = 2;
1037      size = 1;      size = 1;
1038      break;      break;
1039    
1040      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1041      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1042        space = 2;        space = 2;
1043      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 1019  while (cc < ccend) Line 1064  while (cc < ccend)
1064    
1065    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1066      {      {
1067      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1068      localptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_w) * space;
1069      }      }
1070    
1071    if (size != 0)    if (size != 0)
# Line 1222  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1267  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1267  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1268  }  }
1269    
1270  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1271  {  {
1272  int localsize = 2;  int private_data_length = 2;
1273  int size;  int size;
1274  pcre_uchar *alternative;  pcre_uchar *alternative;
1275  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1276  while (cc < ccend)  while (cc < ccend)
1277    {    {
1278    size = 0;    size = 0;
# Line 1243  while (cc < ccend) Line 1288  while (cc < ccend)
1288      case OP_SBRA:      case OP_SBRA:
1289      case OP_SBRAPOS:      case OP_SBRAPOS:
1290      case OP_SCOND:      case OP_SCOND:
1291      localsize++;      private_data_length++;
1292      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1293      break;      break;
1294    
1295      case OP_CBRA:      case OP_CBRA:
1296      case OP_SCBRA:      case OP_SCBRA:
1297      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1298          private_data_length++;
1299      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1300      break;      break;
1301    
1302      case OP_CBRAPOS:      case OP_CBRAPOS:
1303      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1304      localsize += 2;      private_data_length += 2;
1305      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1306      break;      break;
1307    
# Line 1263  while (cc < ccend) Line 1309  while (cc < ccend)
1309      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1310      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1311      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1312        localsize++;        private_data_length++;
1313      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1314      break;      break;
1315    
1316      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1317      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1318        localsize++;        private_data_length++;
1319      cc += 2;      cc += 2;
1320  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1321      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1322  #endif  #endif
1323      break;      break;
1324    
1325      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1326      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1327        localsize += 2;        private_data_length += 2;
1328      cc += 2;      cc += 2;
1329  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1330      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1331  #endif  #endif
1332      break;      break;
1333    
1334      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1335      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1336        localsize += 2;        private_data_length += 2;
1337      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1338  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1339      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1340  #endif  #endif
1341      break;      break;
1342    
1343      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1344      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1345        localsize++;        private_data_length++;
1346      cc += 1;      cc += 1;
1347      break;      break;
1348    
1349      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1350      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1351        localsize += 2;        private_data_length += 2;
1352      cc += 1;      cc += 1;
1353      break;      break;
1354    
1355      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1356      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1357        localsize += 2;        private_data_length += 2;
1358      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
1359      break;      break;
1360    
# Line 1320  while (cc < ccend) Line 1366  while (cc < ccend)
1366  #else  #else
1367      size = 1 + 32 / (int)sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1368  #endif  #endif
1369      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1370        localsize += get_class_iterator_size(cc + size);        private_data_length += get_class_iterator_size(cc + size);
1371      cc += size;      cc += size;
1372      break;      break;
1373    
# Line 1332  while (cc < ccend) Line 1378  while (cc < ccend)
1378      }      }
1379    }    }
1380  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1381  return localsize;  return private_data_length;
1382  }  }
1383    
1384  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1385    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1386  {  {
1387  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1405  while (status != end) Line 1451  while (status != end)
1451        case OP_SBRAPOS:        case OP_SBRAPOS:
1452        case OP_SCOND:        case OP_SCOND:
1453        count = 1;        count = 1;
1454        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1455        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1456        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1457        break;        break;
1458    
1459        case OP_CBRA:        case OP_CBRA:
1460        case OP_SCBRA:        case OP_SCBRA:
1461        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1462        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1463            count = 1;
1464            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1465            }
1466        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1467        break;        break;
1468    
1469        case OP_CBRAPOS:        case OP_CBRAPOS:
1470        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1471        count = 2;        count = 2;
1472        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1473        srcw[1] = PRIV_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1474        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1475        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1476        break;        break;
1477    
# Line 1432  while (status != end) Line 1481  while (status != end)
1481        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1482          {          {
1483          count = 1;          count = 1;
1484          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1485          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1486          }          }
1487        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1488        break;        break;
1489    
1490        CASE_ITERATOR_LOCAL1        CASE_ITERATOR_PRIVATE_DATA_1
1491        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1492          {          {
1493          count = 1;          count = 1;
1494          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1495          }          }
1496        cc += 2;        cc += 2;
1497  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1450  while (status != end) Line 1499  while (status != end)
1499  #endif  #endif
1500        break;        break;
1501    
1502        CASE_ITERATOR_LOCAL2A        CASE_ITERATOR_PRIVATE_DATA_2A
1503        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1504          {          {
1505          count = 2;          count = 2;
1506          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1507          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1508          }          }
1509        cc += 2;        cc += 2;
1510  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1463  while (status != end) Line 1512  while (status != end)
1512  #endif  #endif
1513        break;        break;
1514    
1515        CASE_ITERATOR_LOCAL2B        CASE_ITERATOR_PRIVATE_DATA_2B
1516        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1517          {          {
1518          count = 2;          count = 2;
1519          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1520          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1521          }          }
1522        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1523  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1476  while (status != end) Line 1525  while (status != end)
1525  #endif  #endif
1526        break;        break;
1527    
1528        CASE_ITERATOR_TYPE_LOCAL1        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1529        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1530          {          {
1531          count = 1;          count = 1;
1532          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1533          }          }
1534        cc += 1;        cc += 1;
1535        break;        break;
1536    
1537        CASE_ITERATOR_TYPE_LOCAL2A        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1538        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1539          {          {
1540          count = 2;          count = 2;
1541          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1542          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1543          }          }
1544        cc += 1;        cc += 1;
1545        break;        break;
1546    
1547        CASE_ITERATOR_TYPE_LOCAL2B        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1548        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1549          {          {
1550          count = 2;          count = 2;
1551          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1552          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1553          }          }
1554        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
# Line 1513  while (status != end) Line 1562  while (status != end)
1562  #else  #else
1563        size = 1 + 32 / (int)sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1564  #endif  #endif
1565        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1566          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
1567            {            {
1568            case 1:            case 1:
1569            count = 1;            count = 1;
1570            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1571            break;            break;
1572    
1573            case 2:            case 2:
1574            count = 2;            count = 2;
1575            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1576            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_w);
1577            break;            break;
1578    
# Line 1636  if (save) Line 1685  if (save)
1685  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1686  }  }
1687    
1688  #undef CASE_ITERATOR_LOCAL1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1689  #undef CASE_ITERATOR_LOCAL2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1690  #undef CASE_ITERATOR_LOCAL2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
1691  #undef CASE_ITERATOR_TYPE_LOCAL1  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1692  #undef CASE_ITERATOR_TYPE_LOCAL2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1693  #undef CASE_ITERATOR_TYPE_LOCAL2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1694    
1695  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1696  {  {
# Line 1653  static SLJIT_INLINE void set_jumps(jump_ Line 1702  static SLJIT_INLINE void set_jumps(jump_
1702  while (list)  while (list)
1703    {    {
1704    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1705    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1706    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1707    list = list->next;    list = list->next;
1708    }    }
# Line 2420  if (firstline) Line 2469  if (firstline)
2469    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2470    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2471    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2472    
2473    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2474      {      {
# Line 2431  if (firstline) Line 2479  if (firstline)
2479      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2480      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2481      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2482        JUMPHERE(end);
2483      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2484      }      }
2485    else    else
# Line 2442  if (firstline) Line 2491  if (firstline)
2491      read_char(common);      read_char(common);
2492      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2493      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2494        JUMPHERE(end);
2495      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2496      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2497      }      }
2498    
   JUMPHERE(end);  
2499    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
2500    }    }
2501    
# Line 2514  if (newlinecheck) Line 2563  if (newlinecheck)
2563  return mainloop;  return mainloop;
2564  }  }
2565    
2566  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2567    
2568    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2569  {  {
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571  struct sljit_label *start;  struct sljit_label *start;
2572  struct sljit_jump *quit;  struct sljit_jump *quit;
2573  struct sljit_jump *found;  pcre_int32 chars[MAX_N_CHARS * 2];
 pcre_int32 chars[4];  
2574  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2575  int location = 0;  int location = 0;
2576  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2577  BOOL must_end;  int must_stop;
   
 #ifdef COMPILE_PCRE8  
 union {  
     sljit_uh ascombined;  
     sljit_ub asuchars[2];  
 } pair;  
 #else  
 union {  
     sljit_ui ascombined;  
     sljit_uh asuchars[2];  
 } pair;  
 #endif  
2578    
2579    /* We do not support alternatives now. */
2580  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2581    return FALSE;    return FALSE;
2582    
2583  while (TRUE)  while (TRUE)
2584    {    {
2585    caseless = 0;    caseless = 0;
2586    must_end = TRUE;    must_stop = 1;
2587    switch(*cc)    switch(*cc)
2588      {      {
2589      case OP_CHAR:      case OP_CHAR:
2590      must_end = FALSE;      must_stop = 0;
2591      cc++;      cc++;
2592      break;      break;
2593    
2594      case OP_CHARI:      case OP_CHARI:
2595      caseless = 1;      caseless = 1;
2596      must_end = FALSE;      must_stop = 0;
2597      cc++;      cc++;
2598      break;      break;
2599    
# Line 2596  while (TRUE) Line 2635  while (TRUE)
2635      break;      break;
2636    
2637      default:      default:
2638      return FALSE;      must_stop = 2;
2639        break;
2640      }      }
2641    
2642      if (must_stop == 2)
2643          break;
2644    
2645    len = 1;    len = 1;
2646  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2647    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
# Line 2621  while (TRUE) Line 2664  while (TRUE)
2664    else    else
2665      caseless = 0;      caseless = 0;
2666    
2667    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
2668      {      {
2669      c = *cc;      c = *cc;
2670      bit = 0;      bit = 0;
# Line 2639  while (TRUE) Line 2682  while (TRUE)
2682      cc++;      cc++;
2683      }      }
2684    
2685    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2686      break;      break;
   else if (must_end)  
     return FALSE;  
2687    }    }
2688    
2689    /* At least two characters are required. */
2690    if (location < 2 * 2)
2691        return FALSE;
2692    
2693  if (firstline)  if (firstline)
2694    {    {
2695    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2696    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2697    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2698    }    }
2699  else  else
2700    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2701    
2702  start = LABEL();  start = LABEL();
2703  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  
 #ifdef COMPILE_PCRE8  
 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #else /* COMPILE_PCRE8 */  
 OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #endif  
   
 #else /* SLJIT_UNALIGNED */  
2704    
2705  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 #else /* SLJIT_BIG_ENDIAN */  
2706  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2707  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2708  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
2709      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2710  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2711  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
2712  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2713  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
2714  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2715  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2716    if (location > 2 * 2)
2717  #endif    {
2718      if (chars[5] != 0)
2719  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2720    {    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
   pair.asuchars[0] = chars[1];  
   pair.asuchars[1] = chars[3];  
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);  
2721    }    }
2722    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2723    
 pair.asuchars[0] = chars[0];  
 pair.asuchars[1] = chars[2];  
 found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);  
   
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 JUMPTO(SLJIT_JUMP, start);  
 JUMPHERE(found);  
2724  JUMPHERE(quit);  JUMPHERE(quit);
2725    
2726  if (firstline)  if (firstline)
2727    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2728  else  else
2729    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2730  return TRUE;  return TRUE;
2731  }  }
2732    
2733    #undef MAX_N_CHARS
2734    
2735  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2736  {  {
2737  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2861  struct sljit_jump *jump; Line 2888  struct sljit_jump *jump;
2888  if (firstline)  if (firstline)
2889    {    {
2890    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2891    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2892    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2893    }    }
2894    
# Line 2913  JUMPHERE(found); Line 2940  JUMPHERE(found);
2940  JUMPHERE(quit);  JUMPHERE(quit);
2941    
2942  if (firstline)  if (firstline)
2943    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2944  }  }
2945    
2946  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 3454  sljit_emit_fast_return(compiler, RETURN_ Line 3481  sljit_emit_fast_return(compiler, RETURN_
3481  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3482  {  {
3483  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3484  int c1, c2;  pcre_uint32 c1, c2;
3485  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3486  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3487    const ucd_record *ur;
3488    const pcre_uint32 *pp;
3489    
3490  while (src1 < end1)  while (src1 < end1)
3491    {    {
# Line 3464  while (src1 < end1) Line 3493  while (src1 < end1)
3493      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3494    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3495    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3496    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3497      if (c1 != c2 && c1 != c2 + ur->other_case)
3498        {
3499        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3500        for (;;)
3501          {
3502          if (c1 < *pp) return NULL;
3503          if (c1 == *pp++) break;
3504          }
3505        }
3506    }    }
3507  return src2;  return src2;
3508  }  }
# Line 3651  return cc; Line 3689  return cc;
3689      } \      } \
3690    charoffset = (value);    charoffset = (value);
3691    
3692  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3693  {  {
3694  DEFINE_COMPILER;  DEFINE_COMPILER;
3695  jump_list *found = NULL;  jump_list *found = NULL;
3696  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3697  unsigned int c;  pcre_int32 c, charoffset;
3698  int compares;  const pcre_uint32 *other_cases;
3699  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3700  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3701    int compares, invertcmp, numberofcmps;
3702  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3703  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3704  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3705  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3706  unsigned int typeoffset;  pcre_int32 typeoffset;
3707  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3708    
3709  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3710     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3765  while (*cc != XCL_END) Line 3802  while (*cc != XCL_END)
3802        needschar = TRUE;        needschar = TRUE;
3803        break;        break;
3804    
3805          case PT_CLIST:
3806          needschar = TRUE;
3807          break;
3808    
3809        default:        default:
3810        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3811        break;        break;
# Line 3974  while (*cc != XCL_END) Line 4015  while (*cc != XCL_END)
4015        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4016        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4017        break;        break;
4018    
4019          case PT_CLIST:
4020          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4021    
4022          /* At least two characters are required. */
4023          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR);
4024    
4025          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4026          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4027    
4028          do
4029            {
4030            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4031            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4032            }
4033          while (*other_cases != NOTACHAR);
4034          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4035          break;
4036        }        }
4037      cc += 2;      cc += 2;
4038      }      }
# Line 3992  if (found != NULL) Line 4051  if (found != NULL)
4051    
4052  #endif  #endif
4053    
4054  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
4055  {  {
4056  DEFINE_COMPILER;  DEFINE_COMPILER;
4057  int length;  int length;
# Line 4124  switch(type) Line 4183  switch(type)
4183    propdata[2] = cc[0];    propdata[2] = cc[0];
4184    propdata[3] = cc[1];    propdata[3] = cc[1];
4185    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4186    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4187    return cc + 2;    return cc + 2;
4188  #endif  #endif
4189  #endif  #endif
# Line 4170  switch(type) Line 4229  switch(type)
4229    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4230    read_char(common);    read_char(common);
4231    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4232    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4233    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4234      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4235      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4236    
4237    label = LABEL();    label = LABEL();
4238    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4239    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4240    read_char(common);    read_char(common);
4241    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4242    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4243    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4244    
4245      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4246      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4247      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4248      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4249      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4250      JUMPTO(SLJIT_C_NOT_ZERO, label);
4251    
4252    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4253    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4254      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4255    
4256    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4257      {      {
4258      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 4308  switch(type) Line 4378  switch(type)
4378    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4379    
4380    if (!common->endonly)    if (!common->endonly)
4381      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4382    else    else
4383      {      {
4384      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
# Line 4396  switch(type) Line 4466  switch(type)
4466      }      }
4467    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4468    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4469    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4470    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4471    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4472    return cc + length;    return cc + length;
# Line 4499  switch(type) Line 4569  switch(type)
4569    
4570  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4571    case OP_XCLASS:    case OP_XCLASS:
4572    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4573    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4574  #endif  #endif
4575    
# Line 4533  SLJIT_ASSERT_STOP(); Line 4603  SLJIT_ASSERT_STOP();
4603  return cc;  return cc;
4604  }  }
4605    
4606  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4607  {  {
4608  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4609  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 4596  if (context.length > 0) Line 4666  if (context.length > 0)
4666    }    }
4667    
4668  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4669  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4670  }  }
4671    
4672  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 4622  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4692  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4692  }  }
4693    
4694  /* Forward definitions. */  /* Forward definitions. */
4695  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4696  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4697    
4698  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4699    do \    do \
# Line 4653  static void compile_backtrackpath(compil Line 4723  static void compile_backtrackpath(compil
4723    
4724  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4725    
4726  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4727  {  {
4728  DEFINE_COMPILER;  DEFINE_COMPILER;
4729  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 4735  if (jump != NULL) Line 4805  if (jump != NULL)
4805  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4806  }  }
4807    
4808  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4809  {  {
4810  DEFINE_COMPILER;  DEFINE_COMPILER;
4811  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4806  if (!minimize) Line 4876  if (!minimize)
4876      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4877    
4878    label = LABEL();    label = LABEL();
4879    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4880    
4881    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4882      {      {
# Line 4834  if (!minimize) Line 4904  if (!minimize)
4904      }      }
4905    
4906    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4907    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4908    
4909    decrease_call_count(common);    decrease_call_count(common);
4910    return cc;    return cc;
# Line 4854  if (min == 0) Line 4924  if (min == 0)
4924  else  else
4925    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4926    
4927  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4928  if (max > 0)  if (max > 0)
4929    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4930    
4931  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4932  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4933    
4934  if (min > 1)  if (min > 1)
# Line 4866  if (min > 1) Line 4936  if (min > 1)
4936    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4937    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4938    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4939    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4940    }    }
4941  else if (max > 0)  else if (max > 0)
4942    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4879  decrease_call_count(common); Line 4949  decrease_call_count(common);
4949  return cc;  return cc;
4950  }  }
4951    
4952  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4953  {  {
4954  DEFINE_COMPILER;  DEFINE_COMPILER;
4955  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4936  add_jump(compiler, &backtrack->topbacktr Line 5006  add_jump(compiler, &backtrack->topbacktr
5006  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5007  }  }
5008    
5009  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5010  {  {
5011  DEFINE_COMPILER;  DEFINE_COMPILER;
5012  int framesize;  int framesize;
5013  int localptr;  int private_data_ptr;
5014  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5015  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5016  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4962  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5032  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5032    bra = *cc;    bra = *cc;
5033    cc++;    cc++;
5034    }    }
5035  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5036  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5037  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5038  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5039  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5040  opcode = *cc;  opcode = *cc;
5041  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5042  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4983  if (bra == OP_BRAMINZERO) Line 5053  if (bra == OP_BRAMINZERO)
5053    
5054  if (framesize < 0)  if (framesize < 0)
5055    {    {
5056    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5057    allocate_stack(common, 1);    allocate_stack(common, 1);
5058    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5059    }    }
5060  else  else
5061    {    {
5062    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5063    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5064    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
5065    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5066    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5067    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5068    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
# Line 5012  while (1) Line 5082  while (1)
5082      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5083    
5084    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5085    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5086    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5087      {      {
5088      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5027  while (1) Line 5097  while (1)
5097    
5098    /* Reset stack. */    /* Reset stack. */
5099    if (framesize < 0)    if (framesize < 0)
5100      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5101    else {    else {
5102      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5103        {        {
5104        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5105        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5106        }        }
5107      else      else
5108        {        {
5109        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5110        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5111        }        }
5112    }    }
# Line 5054  while (1) Line 5124  while (1)
5124          {          {
5125          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));
5126          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));
5127          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5128          }          }
5129        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));
5130        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 5062  while (1) Line 5132  while (1)
5132      else if (framesize >= 0)      else if (framesize >= 0)
5133        {        {
5134        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5135        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5136        }        }
5137      }      }
5138    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5139    
5140    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5141    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5142      {      {
5143      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5113  if (opcode == OP_ASSERT || opcode == OP_ Line 5183  if (opcode == OP_ASSERT || opcode == OP_
5183        }        }
5184      else      else
5185        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5186      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5187      }      }
5188    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5189    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 5138  if (opcode == OP_ASSERT || opcode == OP_ Line 5208  if (opcode == OP_ASSERT || opcode == OP_
5208      {      {
5209      if (bra == OP_BRA)      if (bra == OP_BRA)
5210        {        {
5211        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5212        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5213        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5214        }        }
5215      else      else
5216        {        {
5217        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5218        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5219        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5220        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5221        }        }
# Line 5153  if (opcode == OP_ASSERT || opcode == OP_ Line 5223  if (opcode == OP_ASSERT || opcode == OP_
5223    
5224    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5225      {      {
5226      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5227      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5228      }      }
5229    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5230      {      {
5231      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5232      JUMPHERE(brajump);      JUMPHERE(brajump);
5233      if (framesize >= 0)      if (framesize >= 0)
5234        {        {
5235        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5236        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5237        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5238        }        }
5239      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5240      }      }
# Line 5192  else Line 5262  else
5262        }        }
5263      else      else
5264        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5265      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5266      }      }
5267    
5268    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5269      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5270    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5271      {      {
5272      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5273      JUMPHERE(brajump);      JUMPHERE(brajump);
5274      }      }
5275    
# Line 5382  return condition; Line 5452  return condition;
5452                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5453  */  */
5454    
5455  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5456  {  {
5457  DEFINE_COMPILER;  DEFINE_COMPILER;
5458  backtrack_common *backtrack;  backtrack_common *backtrack;
5459  pcre_uchar opcode;  pcre_uchar opcode;
5460  int localptr = 0;  int private_data_ptr = 0;
5461  int offset = 0;  int offset = 0;
5462  int stacksize;  int stacksize;
5463  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5464  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5465  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5466  pcre_uchar ket;  pcre_uchar ket;
5467  assert_backtrack *assert;  assert_backtrack *assert;
# Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5482  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5482    
5483  opcode = *cc;  opcode = *cc;
5484  ccbegin = cc;  ccbegin = cc;
5485  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5486    
5487  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5488    {    {
# Line 5429  cc += GET(cc, 1); Line 5499  cc += GET(cc, 1);
5499  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5500  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5501    {    {
5502    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5503    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5504      {      {
5505      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5506      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5507        has_alternatives = FALSE;        has_alternatives = FALSE;
5508      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 5451  if (opcode == OP_CBRA || opcode == OP_SC Line 5521  if (opcode == OP_CBRA || opcode == OP_SC
5521    {    {
5522    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5523    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5524    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5525    offset <<= 1;      {
5526    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5527    trypath += IMM2_SIZE;      offset <<= 1;
5528        }
5529      else
5530        {
5531        offset <<= 1;
5532        private_data_ptr = OVECTOR(offset);
5533        }
5534      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5535      matchingpath += IMM2_SIZE;
5536    }    }
5537  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5538    {    {
5539    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5540    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5541    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5542    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5543    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5544      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5545    }    }
# Line 5507  if (bra == OP_BRAMINZERO) Line 5585  if (bra == OP_BRAMINZERO)
5585        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5586        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5587          {          {
5588          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5589          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5590          }          }
5591        else        else
5592          {          {
5593          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5594          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5595          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5596          }          }
5597        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5528  if (bra == OP_BRAMINZERO) Line 5606  if (bra == OP_BRAMINZERO)
5606    }    }
5607    
5608  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5609    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5610    
5611  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5612    {    {
5613    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5614    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5615      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5616    }    }
5617    
5618  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 5545  if (opcode == OP_ONCE) Line 5623  if (opcode == OP_ONCE)
5623      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5624      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5625        {        {
5626        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5627        allocate_stack(common, 2);        allocate_stack(common, 2);
5628        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5629        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5630        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5631        }        }
5632      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5633        {        {
5634        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5635        allocate_stack(common, 1);        allocate_stack(common, 1);
5636        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5637        }        }
5638      else      else
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5640      }      }
5641    else    else
5642      {      {
5643      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5644        {        {
5645        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5646        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5647        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5648        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5649        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5650        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5651        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5652        }        }
5653      else      else
5654        {        {
5655        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5656        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5657        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5658        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5659        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5660        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5661        }        }
# Line 5586  if (opcode == OP_ONCE) Line 5664  if (opcode == OP_ONCE)
5664  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5665    {    {
5666    /* Saving the previous values. */    /* Saving the previous values. */
5667    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5668    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5669    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5670    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5671    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5672    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5673    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5674    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5675        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5676        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5677        }
5678      else
5679        {
5680        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5681        allocate_stack(common, 2);
5682        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5683        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5684        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5685        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5686        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5687        }
5688    }    }
5689  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5690    {    {
5691    /* Saving the previous value. */    /* Saving the previous value. */
5692    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5693    allocate_stack(common, 1);    allocate_stack(common, 1);
5694    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5695    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5696    }    }
5697  else if (has_alternatives)  else if (has_alternatives)
# Line 5613  else if (has_alternatives) Line 5704  else if (has_alternatives)
5704  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5705  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5706    {    {
5707    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5708      {      {
5709      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5710      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5711        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5712      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5713      }      }
5714    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5715      {      {
5716      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5717      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5718      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5719    
5720      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 5637  if (opcode == OP_COND || opcode == OP_SC Line 5728  if (opcode == OP_COND || opcode == OP_SC
5728      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5729    
5730      JUMPHERE(jump);      JUMPHERE(jump);
5731      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5732      }      }
5733    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5734      {      {
5735      /* Never has other case. */      /* Never has other case. */
5736      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5737    
5738      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5739      if (common->currententry == NULL)      if (common->currententry == NULL)
5740        stacksize = 0;        stacksize = 0;
5741      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 5654  if (opcode == OP_COND || opcode == OP_SC Line 5745  if (opcode == OP_COND || opcode == OP_SC
5745      else      else
5746        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5747    
5748      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5749        {        {
5750        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5751        if (stacksize != 0)        if (stacksize != 0)
5752          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5753        else        else
5754          {          {
5755          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5756            {            {
5757            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5758            cc += GET(cc, 1);            cc += GET(cc, 1);
5759            }            }
5760          else          else
5761            trypath = cc;            matchingpath = cc;
5762          }          }
5763        }        }
5764      else      else
5765        {        {
5766        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5767    
5768        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5769        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5770        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5771        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 5685  if (opcode == OP_COND || opcode == OP_SC Line 5776  if (opcode == OP_COND || opcode == OP_SC
5776        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5777        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5778        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5779        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5780        }        }
5781      }      }
5782    else    else
5783      {      {
5784      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5785      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5786      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5787      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5788        return NULL;        return NULL;
5789      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5790      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5791      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5792      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5793      }      }
5794    }    }
5795    
5796  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5797  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5798    return NULL;    return NULL;
5799    
# Line 5710  if (opcode == OP_ONCE) Line 5801  if (opcode == OP_ONCE)
5801    {    {
5802    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5803      {      {
5804      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5805      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5806      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5807        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5808      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5809        {        {
5810        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5811        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5812        }        }
5813      }      }
5814    else    else
5815      {      {
5816      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5817      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5818      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5819        {        {
5820        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5758  if (has_alternatives) Line 5849  if (has_alternatives)
5849    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5850      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5851    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5852      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5853    }    }
5854    
5855  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5856  if (offset != 0)  if (offset != 0)
5857    {    {
5858    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5859    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);
5860    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5861    }    }
# Line 5774  if (ket == OP_KETRMAX) Line 5865  if (ket == OP_KETRMAX)
5865    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5866      {      {
5867      if (has_alternatives)      if (has_alternatives)
5868        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5869      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5870      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5871        {        {
5872        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5873        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5874        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5875          free_stack(common, 1);          free_stack(common, 1);
# Line 5789  if (ket == OP_KETRMAX) Line 5880  if (ket == OP_KETRMAX)
5880      }      }
5881    else    else
5882      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5883    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5884    }    }
5885    
5886  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5887    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5888    
5889  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5890    {    {
5891    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5892    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5893    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5894      {      {
5895      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5807  if (bra == OP_BRAMINZERO) Line 5898  if (bra == OP_BRAMINZERO)
5898      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5899      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5900        {        {
5901        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5902        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5903        }        }
5904      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5826  cc += 1 + LINK_SIZE; Line 5917  cc += 1 + LINK_SIZE;
5917  return cc;  return cc;
5918  }  }
5919    
5920  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5921  {  {
5922  DEFINE_COMPILER;  DEFINE_COMPILER;
5923  backtrack_common *backtrack;  backtrack_common *backtrack;
5924  pcre_uchar opcode;  pcre_uchar opcode;
5925  int localptr;  int private_data_ptr;
5926  int cbraprivptr = 0;  int cbraprivptr = 0;
5927  int framesize;  int framesize;
5928  int stacksize;  int stacksize;
# Line 5850  if (*cc == OP_BRAPOSZERO) Line 5941  if (*cc == OP_BRAPOSZERO)
5941    }    }
5942    
5943  opcode = *cc;  opcode = *cc;
5944  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5945  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5946  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5947  switch(opcode)  switch(opcode)
5948    {    {
5949    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5863  switch(opcode) Line 5954  switch(opcode)
5954    case OP_CBRAPOS:    case OP_CBRAPOS:
5955    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5956    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5957      /* This case cannot be optimized in the same was as
5958      normal capturing brackets. */
5959      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5960    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5961    offset <<= 1;    offset <<= 1;
5962    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5882  if (framesize < 0) Line 5976  if (framesize < 0)
5976      stacksize++;      stacksize++;
5977    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5978    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5979    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5980    
5981    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5982      {      {
# Line 5907  else Line 6001  else
6001    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6002    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6003    
6004    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6005    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6006    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6007    stack = 0;    stack = 0;
6008    if (!zero)    if (!zero)
6009      {      {
# Line 5935  while (*cc != OP_KETRPOS) Line 6029  while (*cc != OP_KETRPOS)
6029    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6030    cc += GET(cc, 1);    cc += GET(cc, 1);
6031    
6032    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6033    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6034      return NULL;      return NULL;
6035    
6036    if (framesize < 0)    if (framesize < 0)
6037      {      {
6038      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6039    
6040      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6041        {        {
# Line 5967  while (*cc != OP_KETRPOS) Line 6061  while (*cc != OP_KETRPOS)
6061      {      {
6062      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6063        {        {
6064        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
6065        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6066        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);
6067        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5975  while (*cc != OP_KETRPOS) Line 6069  while (*cc != OP_KETRPOS)
6069        }        }
6070      else      else
6071        {        {
6072        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6073        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
6074        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6075          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));
# Line 5996  while (*cc != OP_KETRPOS) Line 6090  while (*cc != OP_KETRPOS)
6090    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6091    flush_stubs(common);    flush_stubs(common);
6092    
6093    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6094    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6095      return NULL;      return NULL;
6096    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 6014  while (*cc != OP_KETRPOS) Line 6108  while (*cc != OP_KETRPOS)
6108        {        {
6109        /* Last alternative. */        /* Last alternative. */
6110        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6111          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6112        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6113        }        }
6114      else      else
6115        {        {
6116        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6117        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6118        }        }
6119      }      }
# Line 6034  if (!zero) Line 6128  if (!zero)
6128    {    {
6129    if (framesize < 0)    if (framesize < 0)
6130      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
6131    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6132      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
6133    }    }
6134    
# Line 6136  if (end != NULL) Line 6230  if (end != NULL)
6230  return cc;  return cc;
6231  }  }
6232    
6233  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6234  {  {
6235  DEFINE_COMPILER;  DEFINE_COMPILER;
6236  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6147  pcre_uchar* end; Line 6241  pcre_uchar* end;
6241  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6242  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6243  struct sljit_label *label;  struct sljit_label *label;
6244  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6245  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6246  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6247  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6248  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6249    
6250  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6204  switch(opcode) Line 6298  switch(opcode)
6298    case OP_CRRANGE:    case OP_CRRANGE:
6299    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6300      {      {
6301      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6302      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6303        {        {
6304        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6221  switch(opcode) Line 6315  switch(opcode)
6315        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6316    
6317      label = LABEL();      label = LABEL();
6318      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6319      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6320        {        {
6321        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 6243  switch(opcode) Line 6337  switch(opcode)
6337    else    else
6338      {      {
6339      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6340        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6341      if (localptr == 0)      if (private_data_ptr == 0)
6342        allocate_stack(common, 2);        allocate_stack(common, 2);
6343      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6344      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6252  switch(opcode) Line 6346  switch(opcode)
6346      else      else
6347        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6348      label = LABEL();      label = LABEL();
6349      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6350      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6351      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
6352        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6273  switch(opcode) Line 6367  switch(opcode)
6367        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6368      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6369      }      }
6370    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6371    break;    break;
6372    
6373    case OP_MINSTAR:    case OP_MINSTAR:
6374    case OP_MINPLUS:    case OP_MINPLUS:
6375    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6376      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6377    if (localptr == 0)    if (private_data_ptr == 0)
6378      allocate_stack(common, 1);      allocate_stack(common, 1);
6379    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6380    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6381    break;    break;
6382    
6383    case OP_MINUPTO:    case OP_MINUPTO:
6384    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6385    if (localptr == 0)    if (private_data_ptr == 0)
6386      allocate_stack(common, 2);      allocate_stack(common, 2);
6387    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6388    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6389    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6390      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6391    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6392    break;    break;
6393    
6394    case OP_QUERY:    case OP_QUERY:
6395    case OP_MINQUERY:    case OP_MINQUERY:
6396    if (localptr == 0)    if (private_data_ptr == 0)
6397      allocate_stack(common, 1);      allocate_stack(common, 1);
6398    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6399    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6400      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6401    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6402    break;    break;
6403    
6404    case OP_EXACT:    case OP_EXACT:
6405    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6406    label = LABEL();    label = LABEL();
6407    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6408    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6409    JUMPTO(SLJIT_C_NOT_ZERO, label);    JUMPTO(SLJIT_C_NOT_ZERO, label);
6410    break;    break;
# Line 6319  switch(opcode) Line 6413  switch(opcode)
6413    case OP_POSPLUS:    case OP_POSPLUS:
6414    case OP_POSUPTO:    case OP_POSUPTO:
6415    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
6416      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6417    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
6418      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6419    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6420    label = LABEL();    label = LABEL();
6421    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6422    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6423    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
6424      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6339  switch(opcode) Line 6433  switch(opcode)
6433    
6434    case OP_POSQUERY:    case OP_POSQUERY:
6435    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6436    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6437    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6438    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6439    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
# Line 6354  decrease_call_count(common); Line 6448  decrease_call_count(common);
6448  return end;  return end;
6449  }  }
6450    
6451  static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6452  {  {
6453  DEFINE_COMPILER;  DEFINE_COMPILER;
6454  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6398  add_jump(compiler, &backtrack->topbacktr Line 6492  add_jump(compiler, &backtrack->topbacktr
6492  return cc + 1;  return cc + 1;
6493  }  }
6494    
6495  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
6496  {  {
6497  DEFINE_COMPILER;  DEFINE_COMPILER;
6498  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6499    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6500    
6501  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6502  if (common->currententry != NULL)  if (common->currententry != NULL)
6503    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6504    
6505  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6506      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6507  offset <<= 1;  offset <<= 1;
6508  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);
6509  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6510      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6511  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6512  }  }
6513    
6514  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6515  {  {
6516  DEFINE_COMPILER;  DEFINE_COMPILER;
6517  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6453  while (cc < ccend) Line 6550  while (cc < ccend)
6550      case OP_NOT:      case OP_NOT:
6551      case OP_NOTI:      case OP_NOTI:
6552      case OP_REVERSE:      case OP_REVERSE:
6553      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6554      break;      break;
6555    
6556      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6468  while (cc < ccend) Line 6565  while (cc < ccend)
6565      case OP_CHAR:      case OP_CHAR:
6566      case OP_CHARI:      case OP_CHARI:
6567      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6568        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6569      else      else
6570        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6571      break;      break;
6572    
6573      case OP_STAR:      case OP_STAR:
# Line 6538  while (cc < ccend) Line 6635  while (cc < ccend)
6635      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6636      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6637      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6638      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6639      break;      break;
6640    
6641      case OP_CLASS:      case OP_CLASS:
6642      case OP_NCLASS:      case OP_NCLASS:
6643      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
6644        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6645      else      else
6646        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6647      break;      break;
6648    
6649  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6650      case OP_XCLASS:      case OP_XCLASS:
6651      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6652        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6653      else      else
6654        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6655      break;      break;
6656  #endif  #endif
6657    
6658      case OP_REF:      case OP_REF:
6659      case OP_REFI:      case OP_REFI:
6660      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
6661        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6662      else      else
6663        cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
6664      break;      break;
6665    
6666      case OP_RECURSE:      case OP_RECURSE:
6667      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6668      break;      break;
6669    
6670      case OP_ASSERT:      case OP_ASSERT:
# Line 6575  while (cc < ccend) Line 6672  while (cc < ccend)
6672      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6673      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6674      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6675      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6676      break;      break;
6677    
6678      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 6592  while (cc < ccend) Line 6689  while (cc < ccend)
6689        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6690        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6691        }        }
6692      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6693      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6694        decrease_call_count(common);        decrease_call_count(common);
6695      break;      break;
# Line 6605  while (cc < ccend) Line 6702  while (cc < ccend)
6702      case OP_SBRA:      case OP_SBRA:
6703      case OP_SCBRA:      case OP_SCBRA:
6704      case OP_SCOND:      case OP_SCOND:
6705      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6706      break;      break;
6707    
6708      case OP_BRAZERO:      case OP_BRAZERO:
6709      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6710        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6711      else      else
6712        {        {
6713        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6714        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6715        }        }
6716      break;      break;
6717    
# Line 6623  while (cc < ccend) Line 6720  while (cc < ccend)
6720      case OP_SBRAPOS:      case OP_SBRAPOS:
6721      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6722      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6723      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6724      break;      break;
6725    
6726      case OP_MARK:      case OP_MARK:
# Line 6647  while (cc < ccend) Line 6744  while (cc < ccend)
6744      case OP_FAIL:      case OP_FAIL:
6745      case OP_ACCEPT:      case OP_ACCEPT:
6746      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6747      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6748      break;      break;
6749    
6750      case OP_CLOSE:      case OP_CLOSE:
6751      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6752      break;      break;
6753    
6754      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 6672  SLJIT_ASSERT(cc == ccend); Line 6769  SLJIT_ASSERT(cc == ccend);
6769  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6770  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6771    
6772  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6773    do \    do \
6774      { \      { \
6775      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6776      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6777        return; \        return; \
6778      } \      } \
# Line 6683  SLJIT_ASSERT(cc == ccend); Line 6780  SLJIT_ASSERT(cc == ccend);
6780    
6781  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6782    
6783  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6784  {  {
6785  DEFINE_COMPILER;  DEFINE_COMPILER;
6786  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6693  int arg1 = -1, arg2 = -1; Line 6790  int arg1 = -1, arg2 = -1;
6790  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6791  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6792  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6793  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6794  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6795  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6796  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6797    
6798  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6799    
# Line 6708  switch(opcode) Line 6805  switch(opcode)
6805    case OP_CRRANGE:    case OP_CRRANGE:
6806    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6807      {      {
6808      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6809      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6810      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6811      free_stack(common, 1);      free_stack(common, 1);
6812      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6813      }      }
6814    else    else
6815      {      {
# Line 6732  switch(opcode) Line 6829  switch(opcode)
6829        }        }
6830      skip_char_back(common);      skip_char_back(common);
6831      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6832      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6833      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6834        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6835      JUMPHERE(jump);      JUMPHERE(jump);
6836      if (localptr == 0)      if (private_data_ptr == 0)
6837        free_stack(common, 2);        free_stack(common, 2);
6838      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6839        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6746  switch(opcode) Line 6843  switch(opcode)
6843    case OP_MINSTAR:    case OP_MINSTAR:
6844    case OP_MINPLUS:    case OP_MINPLUS:
6845    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6846    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6847    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6848    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6849    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6850    if (localptr == 0)    if (private_data_ptr == 0)
6851      free_stack(common, 1);      free_stack(common, 1);
6852    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6853      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6764  switch(opcode) Line 6861  switch(opcode)
6861      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6862      }      }
6863    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6864    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6865    
6866    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6867    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6775  switch(opcode) Line 6872  switch(opcode)
6872      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6873    
6874    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6875      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6876    else    else
6877      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
6878    
6879    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6880    if (localptr == 0)    if (private_data_ptr == 0)
6881      free_stack(common, 2);      free_stack(common, 2);
6882    break;    break;
6883    
6884    case OP_QUERY:    case OP_QUERY:
6885    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6886    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6887    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6888    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6889    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6890    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6891    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6892    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6893    JUMPHERE(jump);    JUMPHERE(jump);
6894    if (localptr == 0)    if (private_data_ptr == 0)
6895      free_stack(common, 1);      free_stack(common, 1);
6896    break;    break;
6897    
# Line 6802  switch(opcode) Line 6899  switch(opcode)
6899    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6900    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6901    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6902    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6903    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6904    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6905    JUMPHERE(jump);    JUMPHERE(jump);
6906    if (localptr == 0)    if (private_data_ptr == 0)
6907      free_stack(common, 1);      free_stack(common, 1);
6908    break;    break;
6909    
# Line 6826  switch(opcode) Line 6923  switch(opcode)
6923    }    }
6924  }  }
6925    
6926  static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6927  {  {
6928  DEFINE_COMPILER;  DEFINE_COMPILER;
6929  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6838  if ((type & 0x1) == 0) Line 6935  if ((type & 0x1) == 0)
6935    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6936    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6937    free_stack(common, 1);    free_stack(common, 1);
6938    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6939    return;    return;
6940    }    }
6941    
6942  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6943  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6944  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6945  free_stack(common, 2);  free_stack(common, 2);
6946  }  }
6947    
6948  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6949  {  {
6950  DEFINE_COMPILER;  DEFINE_COMPILER;
6951    
# Line 6870  else if (common->has_set_som || common-> Line 6967  else if (common->has_set_som || common->
6967    }    }
6968  }  }
6969    
6970  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6971  {  {
6972  DEFINE_COMPILER;  DEFINE_COMPILER;
6973  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6897  if (CURRENT_AS(assert_backtrack)->frames Line 6994  if (CURRENT_AS(assert_backtrack)->frames
6994    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6995      {      {
6996      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6997      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6998      free_stack(common, 1);      free_stack(common, 1);
6999      }      }
7000    return;    return;
# Line 6908  if (bra == OP_BRAZERO) Line 7005  if (bra == OP_BRAZERO)
7005    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
7006      {      {
7007      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7008      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
7009      free_stack(common, 1);      free_stack(common, 1);
7010      return;      return;
7011      }      }
# Line 6918  if (bra == OP_BRAZERO) Line 7015  if (bra == OP_BRAZERO)
7015    
7016  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7017    {    {
7018    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr);
7019    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7020    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
7021    
7022    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7023    }    }
# Line 6932  if (bra == OP_BRAZERO) Line 7029  if (bra == OP_BRAZERO)
7029    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
7030    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));
7031    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7032    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
7033    JUMPHERE(brajump);    JUMPHERE(brajump);
7034    }    }
7035  }  }
7036    
7037  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7038  {  {
7039  DEFINE_COMPILER;  DEFINE_COMPILER;
7040  int opcode;  int opcode;
7041  int offset = 0;  int offset = 0;
7042  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7043  int stacksize;  int stacksize;
7044  int count;  int count;
7045  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6997  else if (ket == OP_KETRMIN) Line 7094  else if (ket == OP_KETRMIN)
7094        {        {
7095        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7096        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7097          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7098        else        else
7099          {          {
7100          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7101          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7102          }          }
7103        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7104          free_stack(common, 1);          free_stack(common, 1);
7105        }        }
7106      else      else
7107        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7108      }      }
7109    rminlabel = LABEL();    rminlabel = LABEL();
7110    }    }
# Line 7022  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7119  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7119    {    {
7120    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7121      {      {
7122      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7123      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7124      }      }
7125    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 7075  else if (*cc == OP_ALT) Line 7172  else if (*cc == OP_ALT)
7172    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7173    }    }
7174    
7175  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7176  if (current->topbacktracks)  if (current->topbacktracks)
7177    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7178    
# Line 7088  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7185  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7185      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7186      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
7187        {        {
7188        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7189        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7190        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
7191        }        }
7192      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7193      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
# Line 7119  if (has_alternatives) Line 7216  if (has_alternatives)
7216        cc += GET(cc, 1);        cc += GET(cc, 1);
7217        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7218          {          {
7219          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7220            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7221          else          else
7222            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7223          }          }
7224        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7225        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7226          return;          return;
7227        }        }
7228    
7229      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7230      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7231      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7232        {        {
7233        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7234          {          {
7235          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7236          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7237          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7238            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7239          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7240            {            {
7241            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7242            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
7243            }            }
7244          }          }
7245        else        else
7246          {          {
7247          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
7248          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7249            {            {
7250            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 7188  if (has_alternatives) Line 7285  if (has_alternatives)
7285    
7286      if (offset != 0)      if (offset != 0)
7287        {        {
7288        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7289        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);
7290        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
7291        }        }
7292    
7293      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7294    
7295      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7296        {        {
# Line 7202  if (has_alternatives) Line 7299  if (has_alternatives)
7299        jumplist = jumplist->next;        jumplist = jumplist->next;
7300        }        }
7301    
7302      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7303      if (current->topbacktracks)      if (current->topbacktracks)
7304        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7305      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 7217  if (has_alternatives) Line 7314  if (has_alternatives)
7314      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
7315    
7316        {        {
7317        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7318        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7319        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
7320        }        }
7321      JUMPHERE(cond);      JUMPHERE(cond);
7322      }      }
7323    
7324    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7325    if (localptr == 0)    if (private_data_ptr == 0)
7326      free_stack(common, 1);      free_stack(common, 1);
7327    }    }
7328    
7329  if (offset != 0)  if (offset != 0)
7330    {    {
7331    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7332    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7333    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7334    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7335    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7336    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7337    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7338        free_stack(common, 3);
7339        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7340        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7341        }
7342      else
7343        {
7344        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7345        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7346        free_stack(common, 2);
7347        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7348        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7349        }
7350    }    }
7351  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7352    {    {
7353    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
7354    free_stack(common, 1);    free_stack(common, 1);
7355    }    }
7356  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7260  else if (opcode == OP_ONCE) Line 7369  else if (opcode == OP_ONCE)
7369      }      }
7370    
7371    JUMPHERE(once);    JUMPHERE(once);
7372    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7373    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7374      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
7375    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7376      {      {
7377      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7378      /* See the comment below. */      /* See the comment below. */
7379      free_stack(common, 2);      free_stack(common, 2);
7380      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7381      }      }
7382    }    }
7383    
# Line 7277  if (ket == OP_KETRMAX) Line 7386  if (ket == OP_KETRMAX)
7386    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7387    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7388      free_stack(common, 1);      free_stack(common, 1);
7389    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7390    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7391      {      {
7392      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7393      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7394      JUMPHERE(brazero);      JUMPHERE(brazero);
7395      free_stack(common, 1);      free_stack(common, 1);
7396      }      }
# Line 7304  else if (ket == OP_KETRMIN) Line 7413  else if (ket == OP_KETRMIN)
7413  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7414    {    {
7415    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7416    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7417    JUMPHERE(brazero);    JUMPHERE(brazero);
7418    }    }
7419  }  }
7420    
7421  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7422  {  {
7423  DEFINE_COMPILER;  DEFINE_COMPILER;
7424  int offset;  int offset;
# Line 7330  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7439  if (CURRENT_AS(bracketpos_backtrack)->fr
7439    return;    return;
7440    }    }
7441    
7442  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
7443  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7444    
7445  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7341  if (current->topbacktracks) Line 7450  if (current->topbacktracks)
7450    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7451    JUMPHERE(jump);    JUMPHERE(jump);
7452    }    }
7453  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
7454  }  }
7455    
7456  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7457  {  {
7458  assert_backtrack backtrack;  assert_backtrack backtrack;
7459    
# Line 7353  current->topbacktracks = NULL; Line 7462  current->topbacktracks = NULL;
7462  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7463  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7464    {    {
7465    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7466    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7467    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7468    }    }
7469  else  else
7470    {    {
7471    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7472    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7473    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7474    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7475    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7476    }    }
7477  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7478  }  }
7479    
7480  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7481  {  {
7482  DEFINE_COMPILER;  DEFINE_COMPILER;
7483    
# Line 7454  while (current) Line 7563  while (current)
7563  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7564      case OP_XCLASS:      case OP_XCLASS:
7565  #endif  #endif
7566      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7567      break;      break;
7568    
7569      case OP_REF:      case OP_REF:
7570      case OP_REFI:      case OP_REFI:
7571      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7572      break;      break;
7573    
7574      case OP_RECURSE:      case OP_RECURSE:
7575      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7576      break;      break;
7577    
7578      case OP_ASSERT:      case OP_ASSERT:
7579      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7580      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7581      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7582      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7583      break;      break;
7584    
7585      case OP_ONCE:      case OP_ONCE:
# Line 7481  while (current) Line 7590  while (current)
7590      case OP_SBRA:      case OP_SBRA:
7591      case OP_SCBRA:      case OP_SCBRA:
7592      case OP_SCOND:      case OP_SCOND:
7593      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7594      break;      break;
7595    
7596      case OP_BRAZERO:      case OP_BRAZERO:
7597      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7598        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7599      else      else
7600        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7601      break;      break;
7602    
7603      case OP_BRAPOS:      case OP_BRAPOS:
# Line 7496  while (current) Line 7605  while (current)
7605      case OP_SBRAPOS:      case OP_SBRAPOS:
7606      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7607      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7608      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7609      break;      break;
7610    
7611      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7612      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7613      break;      break;
7614    
7615      case OP_MARK:      case OP_MARK:
# Line 7537  DEFINE_COMPILER; Line 7646  DEFINE_COMPILER;
7646  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7647  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
7648  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7649  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7650  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7651  int alternativesize;  int alternativesize;
7652  BOOL needsframe;  BOOL needsframe;
# Line 7557  common->currententry->entry = LABEL(); Line 7666  common->currententry->entry = LABEL();
7666  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7667    
7668  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7669  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7670  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
7671  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7672  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
7673  if (needsframe)  if (needsframe)
7674    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 7582  while (1) Line 7691  while (1)
7691    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7692      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7693    
7694    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7695    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7696      {      {
7697      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7592  while (1) Line 7701  while (1)
7701    
7702    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7703    
7704    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7705    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7706      {      {
7707      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7625  if (needsframe) Line 7734  if (needsframe)
7734  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
7735    
7736  JUMPHERE(jump);  JUMPHERE(jump);
7737  copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7738  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7739  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
7740  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7741  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
# Line 7636  common->quitlabel = save_quitlabel; Line 7745  common->quitlabel = save_quitlabel;
7745  common->quit = save_quit;  common->quit = save_quit;
7746  }  }
7747    
7748  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKINGPATH
7749  #undef CURRENT_AS  #undef CURRENT_AS
7750    
7751  void  void
# Line 7648  compiler_common common_data; Line 7757  compiler_common common_data;
7757  compiler_common *common = &common_data;  compiler_common *common = &common_data;
7758  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
7759  pcre_study_data *study;  pcre_study_data *study;
7760  int localsize;  int private_data_size;
7761  pcre_uchar *ccend;  pcre_uchar *ccend;
7762  executable_functions *functions;  executable_functions *functions;
7763  void *executable_func;  void *executable_func;
# Line 7724  ccend = bracketend(rootbacktrack.cc); Line 7833  ccend = bracketend(rootbacktrack.cc);
7833    
7834  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7835  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7836    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7837    if (!common->optimized_cbracket)
7838      return;
7839    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7840    
7841  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7842  localsize = get_localspace(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7843  if (localsize < 0)  if (private_data_size < 0)
7844      {
7845      SLJIT_FREE(common->optimized_cbracket);
7846    return;    return;
7847      }
7848    
7849  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7850  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
# Line 7758  if ((common->ovector_start & sizeof(slji Line 7874  if ((common->ovector_start & sizeof(slji
7874    
7875  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
7876  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7877  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7878  if (localsize > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7879      {
7880      SLJIT_FREE(common->optimized_cbracket);
7881    return;    return;
7882  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));    }
7883  if (!common->localptrs)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7884    if (!common->private_data_ptrs)
7885      {
7886      SLJIT_FREE(common->optimized_cbracket);
7887    return;    return;
7888  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));    }
7889  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7890    set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7891    
7892  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7893  if (!compiler)  if (!compiler)
7894    {    {
7895    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7896      SLJIT_FREE(common->private_data_ptrs);
7897    return;    return;
7898    }    }
7899  common->compiler = compiler;  common->compiler = compiler;
7900    
7901  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
7902  sljit_emit_enter(compiler, 1, 5, 5, localsize);  sljit_emit_enter(compiler, 1, 5, 5, private_data_size);
7903    
7904  /* Register init. */  /* Register init. */
7905  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
# Line 7803  if ((re->options & PCRE_ANCHORED) == 0) Line 7926  if ((re->options & PCRE_ANCHORED) == 0)
7926    /* Forward search if possible. */    /* Forward search if possible. */
7927    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7928      {      {
7929      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7930        /* Do nothing */;        { /* Do nothing */ }
7931      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7932        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
7933      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
# Line 7832  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7955  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7955  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
7956    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7957    
7958  compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7959  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7960    {    {
7961    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7962    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7963      SLJIT_FREE(common->private_data_ptrs);
7964    return;    return;
7965    }    }
7966    
# Line 7862  if (mode != JIT_COMPILE) Line 7986  if (mode != JIT_COMPILE)
7986    }    }
7987    
7988  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
7989  compile_backtrackpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
7990  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7991    {    {
7992    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7993    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7994      SLJIT_FREE(common->private_data_ptrs);
7995    return;    return;
7996    }    }
7997    
# Line 7944  while (common->currententry != NULL) Line 8069  while (common->currententry != NULL)
8069    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8070      {      {
8071      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8072      SLJIT_FREE(common->localptrs);      SLJIT_FREE(common->optimized_cbracket);
8073        SLJIT_FREE(common->private_data_ptrs);
8074      return;      return;
8075      }      }
8076    flush_stubs(common);    flush_stubs(common);
# Line 8039  if (common->getucd != NULL) Line 8165  if (common->getucd != NULL)
8165    }    }
8166  #endif  #endif
8167    
8168  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->optimized_cbracket);
8169    SLJIT_FREE(common->private_data_ptrs);
8170  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8171  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
8172  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8083  union { Line 8210  union {
8210     void* executable_func;     void* executable_func;
8211     jit_function call_executable_func;     jit_function call_executable_func;
8212  } convert_executable_func;  } convert_executable_func;
8213  pcre_uint8 local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_space[MACHINE_STACK_SIZE];
8214  struct sljit_stack local_stack;  struct sljit_stack local_stack;
8215    
8216  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_space;
8217  local_stack.base = local_stack.top;  local_stack.base = local_stack.top;
8218  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
8219  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
8220  arguments->stack = &local_stack;  arguments->stack = &local_stack;
8221  convert_executable_func.executable_func = executable_func;  convert_executable_func.executable_func = executable_func;

Legend:
Removed from v.993  
changed lines
  Added in v.1051

  ViewVC Help
Powered by ViewVC 1.1.5