/[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 1015 by ph10, Sun Aug 26 16:07:14 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 2861  struct sljit_jump *jump; Line 2910  struct sljit_jump *jump;
2910  if (firstline)  if (firstline)
2911    {    {
2912    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2913    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2914    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);
2915    }    }
2916    
# Line 2913  JUMPHERE(found); Line 2962  JUMPHERE(found);
2962  JUMPHERE(quit);  JUMPHERE(quit);
2963    
2964  if (firstline)  if (firstline)
2965    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2966  }  }
2967    
2968  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 3651  return cc; Line 3700  return cc;
3700      } \      } \
3701    charoffset = (value);    charoffset = (value);
3702    
3703  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)
3704  {  {
3705  DEFINE_COMPILER;  DEFINE_COMPILER;
3706  jump_list *found = NULL;  jump_list *found = NULL;
# Line 3992  if (found != NULL) Line 4041  if (found != NULL)
4041    
4042  #endif  #endif
4043    
4044  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)
4045  {  {
4046  DEFINE_COMPILER;  DEFINE_COMPILER;
4047  int length;  int length;
# Line 4124  switch(type) Line 4173  switch(type)
4173    propdata[2] = cc[0];    propdata[2] = cc[0];
4174    propdata[3] = cc[1];    propdata[3] = cc[1];
4175    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4176    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4177    return cc + 2;    return cc + 2;
4178  #endif  #endif
4179  #endif  #endif
# Line 4170  switch(type) Line 4219  switch(type)
4219    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4220    read_char(common);    read_char(common);
4221    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4222    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));
4223    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4224      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4225      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4226    
4227    label = LABEL();    label = LABEL();
4228    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);
4229    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
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    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);
4234    
4235      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4236      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4237      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4238      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4239      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4240      JUMPTO(SLJIT_C_NOT_ZERO, label);
4241    
4242    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4243    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4244      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4245    
4246    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4247      {      {
4248      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 4368  switch(type)
4368    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));
4369    
4370    if (!common->endonly)    if (!common->endonly)
4371      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4372    else    else
4373      {      {
4374      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 4456  switch(type)
4456      }      }
4457    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);
4458    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4459    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);
4460    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4461    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4462    return cc + length;    return cc + length;
# Line 4499  switch(type) Line 4559  switch(type)
4559    
4560  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4561    case OP_XCLASS:    case OP_XCLASS:
4562    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4563    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4564  #endif  #endif
4565    
# Line 4533  SLJIT_ASSERT_STOP(); Line 4593  SLJIT_ASSERT_STOP();
4593  return cc;  return cc;
4594  }  }
4595    
4596  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)
4597  {  {
4598  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4599  /* 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 4656  if (context.length > 0)
4656    }    }
4657    
4658  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4659  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4660  }  }
4661    
4662  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 4682  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4682  }  }
4683    
4684  /* Forward definitions. */  /* Forward definitions. */
4685  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4686  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4687    
4688  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4689    do \    do \
# Line 4653  static void compile_backtrackpath(compil Line 4713  static void compile_backtrackpath(compil
4713    
4714  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4715    
4716  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)
4717  {  {
4718  DEFINE_COMPILER;  DEFINE_COMPILER;
4719  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 4735  if (jump != NULL) Line 4795  if (jump != NULL)
4795  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4796  }  }
4797    
4798  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)
4799  {  {
4800  DEFINE_COMPILER;  DEFINE_COMPILER;
4801  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4806  if (!minimize) Line 4866  if (!minimize)
4866      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4867    
4868    label = LABEL();    label = LABEL();
4869    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4870    
4871    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4872      {      {
# Line 4834  if (!minimize) Line 4894  if (!minimize)
4894      }      }
4895    
4896    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4897    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4898    
4899    decrease_call_count(common);    decrease_call_count(common);
4900    return cc;    return cc;
# Line 4854  if (min == 0) Line 4914  if (min == 0)
4914  else  else
4915    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4916    
4917  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4918  if (max > 0)  if (max > 0)
4919    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));
4920    
4921  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4922  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4923    
4924  if (min > 1)  if (min > 1)
# Line 4866  if (min > 1) Line 4926  if (min > 1)
4926    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4927    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4928    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4929    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);
4930    }    }
4931  else if (max > 0)  else if (max > 0)
4932    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 4939  decrease_call_count(common);
4939  return cc;  return cc;
4940  }  }
4941    
4942  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)
4943  {  {
4944  DEFINE_COMPILER;  DEFINE_COMPILER;
4945  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4936  add_jump(compiler, &backtrack->topbacktr Line 4996  add_jump(compiler, &backtrack->topbacktr
4996  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4997  }  }
4998    
4999  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)
5000  {  {
5001  DEFINE_COMPILER;  DEFINE_COMPILER;
5002  int framesize;  int framesize;
5003  int localptr;  int private_data_ptr;
5004  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5005  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5006  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4962  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5022  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5022    bra = *cc;    bra = *cc;
5023    cc++;    cc++;
5024    }    }
5025  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5026  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5027  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5028  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5029  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5030  opcode = *cc;  opcode = *cc;
5031  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5032  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 5043  if (bra == OP_BRAMINZERO)
5043    
5044  if (framesize < 0)  if (framesize < 0)
5045    {    {
5046    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);
5047    allocate_stack(common, 1);    allocate_stack(common, 1);
5048    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5049    }    }
5050  else  else
5051    {    {
5052    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5053    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5054    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));
5055    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5056    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5057    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5058    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
# Line 5012  while (1) Line 5072  while (1)
5072      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5073    
5074    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5075    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5076    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5077      {      {
5078      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5027  while (1) Line 5087  while (1)
5087    
5088    /* Reset stack. */    /* Reset stack. */
5089    if (framesize < 0)    if (framesize < 0)
5090      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);
5091    else {    else {
5092      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5093        {        {
5094        /* 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. */
5095        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));
5096        }        }
5097      else      else
5098        {        {
5099        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);
5100        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5101        }        }
5102    }    }
# Line 5054  while (1) Line 5114  while (1)
5114          {          {
5115          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));
5116          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));
5117          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5118          }          }
5119        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));
5120        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 5122  while (1)
5122      else if (framesize >= 0)      else if (framesize >= 0)
5123        {        {
5124        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5125        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));
5126        }        }
5127      }      }
5128    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5129    
5130    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5131    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5132      {      {
5133      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5113  if (opcode == OP_ASSERT || opcode == OP_ Line 5173  if (opcode == OP_ASSERT || opcode == OP_
5173        }        }
5174      else      else
5175        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5176      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5177      }      }
5178    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5179    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 5138  if (opcode == OP_ASSERT || opcode == OP_ Line 5198  if (opcode == OP_ASSERT || opcode == OP_
5198      {      {
5199      if (bra == OP_BRA)      if (bra == OP_BRA)
5200        {        {
5201        /* 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. */
5202        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));
5203        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5204        }        }
5205      else      else
5206        {        {
5207        /* 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. */
5208        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));
5209        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5210        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);
5211        }        }
# Line 5153  if (opcode == OP_ASSERT || opcode == OP_ Line 5213  if (opcode == OP_ASSERT || opcode == OP_
5213    
5214    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5215      {      {
5216      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5217      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5218      }      }
5219    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5220      {      {
5221      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5222      JUMPHERE(brajump);      JUMPHERE(brajump);
5223      if (framesize >= 0)      if (framesize >= 0)
5224        {        {
5225        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);
5226        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5227        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));
5228        }        }
5229      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5230      }      }
# Line 5192  else Line 5252  else
5252        }        }
5253      else      else
5254        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5255      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5256      }      }
5257    
5258    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5259      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5260    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5261      {      {
5262      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5263      JUMPHERE(brajump);      JUMPHERE(brajump);
5264      }      }
5265    
# Line 5382  return condition; Line 5442  return condition;
5442                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5443  */  */
5444    
5445  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)
5446  {  {
5447  DEFINE_COMPILER;  DEFINE_COMPILER;
5448  backtrack_common *backtrack;  backtrack_common *backtrack;
5449  pcre_uchar opcode;  pcre_uchar opcode;
5450  int localptr = 0;  int private_data_ptr = 0;
5451  int offset = 0;  int offset = 0;
5452  int stacksize;  int stacksize;
5453  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5454  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5455  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5456  pcre_uchar ket;  pcre_uchar ket;
5457  assert_backtrack *assert;  assert_backtrack *assert;
# Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5472  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5472    
5473  opcode = *cc;  opcode = *cc;
5474  ccbegin = cc;  ccbegin = cc;
5475  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5476    
5477  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)
5478    {    {
# Line 5429  cc += GET(cc, 1); Line 5489  cc += GET(cc, 1);
5489  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5490  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5491    {    {
5492    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5493    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5494      {      {
5495      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5496      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5497        has_alternatives = FALSE;        has_alternatives = FALSE;
5498      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 5451  if (opcode == OP_CBRA || opcode == OP_SC Line 5511  if (opcode == OP_CBRA || opcode == OP_SC
5511    {    {
5512    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5513    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5514    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5515    offset <<= 1;      {
5516    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5517    trypath += IMM2_SIZE;      offset <<= 1;
5518        }
5519      else
5520        {
5521        offset <<= 1;
5522        private_data_ptr = OVECTOR(offset);
5523        }
5524      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5525      matchingpath += IMM2_SIZE;
5526    }    }
5527  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5528    {    {
5529    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5530    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5531    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5532    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5533    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5534      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5535    }    }
# Line 5507  if (bra == OP_BRAMINZERO) Line 5575  if (bra == OP_BRAMINZERO)
5575        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5576        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5577          {          {
5578          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5579          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);
5580          }          }
5581        else        else
5582          {          {
5583          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5584          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5585          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));
5586          }          }
5587        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5528  if (bra == OP_BRAMINZERO) Line 5596  if (bra == OP_BRAMINZERO)
5596    }    }
5597    
5598  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5599    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5600    
5601  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5602    {    {
5603    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5604    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5605      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5606    }    }
5607    
5608  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 5545  if (opcode == OP_ONCE) Line 5613  if (opcode == OP_ONCE)
5613      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5614      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5615        {        {
5616        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5617        allocate_stack(common, 2);        allocate_stack(common, 2);
5618        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5619        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5620        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));
5621        }        }
5622      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5623        {        {
5624        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);
5625        allocate_stack(common, 1);        allocate_stack(common, 1);
5626        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5627        }        }
5628      else      else
5629        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);
5630      }      }
5631    else    else
5632      {      {
5633      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5634        {        {
5635        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5636        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5637        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));
5638        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5640        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5641        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);
5642        }        }
5643      else      else
5644        {        {
5645        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
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));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5648        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5649        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5650        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5651        }        }
# Line 5586  if (opcode == OP_ONCE) Line 5654  if (opcode == OP_ONCE)
5654  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5655    {    {
5656    /* Saving the previous values. */    /* Saving the previous values. */
5657    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5658    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5659    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5660    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5661    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5662    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5663    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);
5664    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5665        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5666        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5667        }
5668      else
5669        {
5670        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5671        allocate_stack(common, 2);
5672        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5673        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5674        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5675        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5676        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5677        }
5678    }    }
5679  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5680    {    {
5681    /* Saving the previous value. */    /* Saving the previous value. */
5682    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5683    allocate_stack(common, 1);    allocate_stack(common, 1);
5684    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);
5685    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5686    }    }
5687  else if (has_alternatives)  else if (has_alternatives)
# Line 5613  else if (has_alternatives) Line 5694  else if (has_alternatives)
5694  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5695  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5696    {    {
5697    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5698      {      {
5699      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5700      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5701        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)));
5702      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5703      }      }
5704    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5705      {      {
5706      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5707      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5708      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));
5709    
5710      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 5718  if (opcode == OP_COND || opcode == OP_SC
5718      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));
5719    
5720      JUMPHERE(jump);      JUMPHERE(jump);
5721      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5722      }      }
5723    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5724      {      {
5725      /* Never has other case. */      /* Never has other case. */
5726      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5727    
5728      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5729      if (common->currententry == NULL)      if (common->currententry == NULL)
5730        stacksize = 0;        stacksize = 0;
5731      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 5654  if (opcode == OP_COND || opcode == OP_SC Line 5735  if (opcode == OP_COND || opcode == OP_SC
5735      else      else
5736        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5737    
5738      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5739        {        {
5740        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5741        if (stacksize != 0)        if (stacksize != 0)
5742          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5743        else        else
5744          {          {
5745          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5746            {            {
5747            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5748            cc += GET(cc, 1);            cc += GET(cc, 1);
5749            }            }
5750          else          else
5751            trypath = cc;            matchingpath = cc;
5752          }          }
5753        }        }
5754      else      else
5755        {        {
5756        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5757    
5758        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5759        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5760        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);
5761        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 5766  if (opcode == OP_COND || opcode == OP_SC
5766        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));
5767        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5768        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));
5769        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5770        }        }
5771      }      }
5772    else    else
5773      {      {
5774      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5775      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5776      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5777      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5778        return NULL;        return NULL;
5779      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5780      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5781      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5782      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5783      }      }
5784    }    }
5785    
5786  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5787  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5788    return NULL;    return NULL;
5789    
# Line 5710  if (opcode == OP_ONCE) Line 5791  if (opcode == OP_ONCE)
5791    {    {
5792    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5793      {      {
5794      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);
5795      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5796      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5797        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5798      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5799        {        {
5800        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5801        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);
5802        }        }
5803      }      }
5804    else    else
5805      {      {
5806      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5807      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));
5808      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5809        {        {
5810        /* 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 5839  if (has_alternatives)
5839    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5840      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5841    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5842      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5843    }    }
5844    
5845  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5846  if (offset != 0)  if (offset != 0)
5847    {    {
5848    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5849    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);
5850    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);
5851    }    }
# Line 5774  if (ket == OP_KETRMAX) Line 5855  if (ket == OP_KETRMAX)
5855    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5856      {      {
5857      if (has_alternatives)      if (has_alternatives)
5858        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5859      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5860      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5861        {        {
5862        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);
5863        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5864        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5865          free_stack(common, 1);          free_stack(common, 1);
# Line 5789  if (ket == OP_KETRMAX) Line 5870  if (ket == OP_KETRMAX)
5870      }      }
5871    else    else
5872      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5873    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5874    }    }
5875    
5876  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5877    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5878    
5879  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5880    {    {
5881    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5882    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5883    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5884      {      {
5885      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5807  if (bra == OP_BRAMINZERO) Line 5888  if (bra == OP_BRAMINZERO)
5888      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5889      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5890        {        {
5891        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);
5892        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5893        }        }
5894      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5826  cc += 1 + LINK_SIZE; Line 5907  cc += 1 + LINK_SIZE;
5907  return cc;  return cc;
5908  }  }
5909    
5910  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)
5911  {  {
5912  DEFINE_COMPILER;  DEFINE_COMPILER;
5913  backtrack_common *backtrack;  backtrack_common *backtrack;
5914  pcre_uchar opcode;  pcre_uchar opcode;
5915  int localptr;  int private_data_ptr;
5916  int cbraprivptr = 0;  int cbraprivptr = 0;
5917  int framesize;  int framesize;
5918  int stacksize;  int stacksize;
# Line 5850  if (*cc == OP_BRAPOSZERO) Line 5931  if (*cc == OP_BRAPOSZERO)
5931    }    }
5932    
5933  opcode = *cc;  opcode = *cc;
5934  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5935  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5936  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5937  switch(opcode)  switch(opcode)
5938    {    {
5939    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5863  switch(opcode) Line 5944  switch(opcode)
5944    case OP_CBRAPOS:    case OP_CBRAPOS:
5945    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5946    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5947      /* This case cannot be optimized in the same was as
5948      normal capturing brackets. */
5949      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5950    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5951    offset <<= 1;    offset <<= 1;
5952    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5882  if (framesize < 0) Line 5966  if (framesize < 0)
5966      stacksize++;      stacksize++;
5967    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5968    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5969    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);
5970    
5971    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5972      {      {
# Line 5907  else Line 5991  else
5991    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5992    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5993    
5994    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5995    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));
5996    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5997    stack = 0;    stack = 0;
5998    if (!zero)    if (!zero)
5999      {      {
# Line 5935  while (*cc != OP_KETRPOS) Line 6019  while (*cc != OP_KETRPOS)
6019    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6020    cc += GET(cc, 1);    cc += GET(cc, 1);
6021    
6022    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6023    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6024      return NULL;      return NULL;
6025    
6026    if (framesize < 0)    if (framesize < 0)
6027      {      {
6028      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);
6029    
6030      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6031        {        {
# Line 5967  while (*cc != OP_KETRPOS) Line 6051  while (*cc != OP_KETRPOS)
6051      {      {
6052      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6053        {        {
6054        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));
6055        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6056        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);
6057        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 6059  while (*cc != OP_KETRPOS)
6059        }        }
6060      else      else
6061        {        {
6062        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6063        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));
6064        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6065          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 6080  while (*cc != OP_KETRPOS)
6080    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6081    flush_stubs(common);    flush_stubs(common);
6082    
6083    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6084    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6085      return NULL;      return NULL;
6086    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 6014  while (*cc != OP_KETRPOS) Line 6098  while (*cc != OP_KETRPOS)
6098        {        {
6099        /* Last alternative. */        /* Last alternative. */
6100        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6101          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6102        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6103        }        }
6104      else      else
6105        {        {
6106        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6107        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));
6108        }        }
6109      }      }
# Line 6034  if (!zero) Line 6118  if (!zero)
6118    {    {
6119    if (framesize < 0)    if (framesize < 0)
6120      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));
6121    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6122      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));
6123    }    }
6124    
# Line 6136  if (end != NULL) Line 6220  if (end != NULL)
6220  return cc;  return cc;
6221  }  }
6222    
6223  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)
6224  {  {
6225  DEFINE_COMPILER;  DEFINE_COMPILER;
6226  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6147  pcre_uchar* end; Line 6231  pcre_uchar* end;
6231  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6232  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6233  struct sljit_label *label;  struct sljit_label *label;
6234  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6235  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);
6236  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6237  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);
6238  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6239    
6240  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6204  switch(opcode) Line 6288  switch(opcode)
6288    case OP_CRRANGE:    case OP_CRRANGE:
6289    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6290      {      {
6291      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6292      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6293        {        {
6294        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6221  switch(opcode) Line 6305  switch(opcode)
6305        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6306    
6307      label = LABEL();      label = LABEL();
6308      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6309      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6310        {        {
6311        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 6327  switch(opcode)
6327    else    else
6328      {      {
6329      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6330        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6331      if (localptr == 0)      if (private_data_ptr == 0)
6332        allocate_stack(common, 2);        allocate_stack(common, 2);
6333      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6334      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6252  switch(opcode) Line 6336  switch(opcode)
6336      else      else
6337        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6338      label = LABEL();      label = LABEL();
6339      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6340      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6341      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
6342        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6273  switch(opcode) Line 6357  switch(opcode)
6357        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));
6358      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6359      }      }
6360    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6361    break;    break;
6362    
6363    case OP_MINSTAR:    case OP_MINSTAR:
6364    case OP_MINPLUS:    case OP_MINPLUS:
6365    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6366      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6367    if (localptr == 0)    if (private_data_ptr == 0)
6368      allocate_stack(common, 1);      allocate_stack(common, 1);
6369    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6370    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6371    break;    break;
6372    
6373    case OP_MINUPTO:    case OP_MINUPTO:
6374    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6375    if (localptr == 0)    if (private_data_ptr == 0)
6376      allocate_stack(common, 2);      allocate_stack(common, 2);
6377    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6378    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6379    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6380      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6381    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6382    break;    break;
6383    
6384    case OP_QUERY:    case OP_QUERY:
6385    case OP_MINQUERY:    case OP_MINQUERY:
6386    if (localptr == 0)    if (private_data_ptr == 0)
6387      allocate_stack(common, 1);      allocate_stack(common, 1);
6388    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6389    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6390      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6391    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6392    break;    break;
6393    
6394    case OP_EXACT:    case OP_EXACT:
6395    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6396    label = LABEL();    label = LABEL();
6397    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6398    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);
6399    JUMPTO(SLJIT_C_NOT_ZERO, label);    JUMPTO(SLJIT_C_NOT_ZERO, label);
6400    break;    break;
# Line 6319  switch(opcode) Line 6403  switch(opcode)
6403    case OP_POSPLUS:    case OP_POSPLUS:
6404    case OP_POSUPTO:    case OP_POSUPTO:
6405    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
6406      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6407    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
6408      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6409    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6410    label = LABEL();    label = LABEL();
6411    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6412    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6413    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
6414      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6339  switch(opcode) Line 6423  switch(opcode)
6423    
6424    case OP_POSQUERY:    case OP_POSQUERY:
6425    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6426    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6427    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6428    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6429    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 6438  decrease_call_count(common);
6438  return end;  return end;
6439  }  }
6440    
6441  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)
6442  {  {
6443  DEFINE_COMPILER;  DEFINE_COMPILER;
6444  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6398  add_jump(compiler, &backtrack->topbacktr Line 6482  add_jump(compiler, &backtrack->topbacktr
6482  return cc + 1;  return cc + 1;
6483  }  }
6484    
6485  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)
6486  {  {
6487  DEFINE_COMPILER;  DEFINE_COMPILER;
6488  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6489    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6490    
6491  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6492  if (common->currententry != NULL)  if (common->currententry != NULL)
6493    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6494    
6495  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6496      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6497  offset <<= 1;  offset <<= 1;
6498  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);
6499  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6500      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6501  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6502  }  }
6503    
6504  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)
6505  {  {
6506  DEFINE_COMPILER;  DEFINE_COMPILER;
6507  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6453  while (cc < ccend) Line 6540  while (cc < ccend)
6540      case OP_NOT:      case OP_NOT:
6541      case OP_NOTI:      case OP_NOTI:
6542      case OP_REVERSE:      case OP_REVERSE:
6543      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);
6544      break;      break;
6545    
6546      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6468  while (cc < ccend) Line 6555  while (cc < ccend)
6555      case OP_CHAR:      case OP_CHAR:
6556      case OP_CHARI:      case OP_CHARI:
6557      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6558        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);
6559      else      else
6560        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);
6561      break;      break;
6562    
6563      case OP_STAR:      case OP_STAR:
# Line 6538  while (cc < ccend) Line 6625  while (cc < ccend)
6625      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6626      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6627      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6628      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6629      break;      break;
6630    
6631      case OP_CLASS:      case OP_CLASS:
6632      case OP_NCLASS:      case OP_NCLASS:
6633      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)
6634        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6635      else      else
6636        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);
6637      break;      break;
6638    
6639  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6640      case OP_XCLASS:      case OP_XCLASS:
6641      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)
6642        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6643      else      else
6644        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);
6645      break;      break;
6646  #endif  #endif
6647    
6648      case OP_REF:      case OP_REF:
6649      case OP_REFI:      case OP_REFI:
6650      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)
6651        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6652      else      else
6653        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);
6654      break;      break;
6655    
6656      case OP_RECURSE:      case OP_RECURSE:
6657      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6658      break;      break;
6659    
6660      case OP_ASSERT:      case OP_ASSERT:
# Line 6575  while (cc < ccend) Line 6662  while (cc < ccend)
6662      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6663      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6664      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6665      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6666      break;      break;
6667    
6668      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 6592  while (cc < ccend) Line 6679  while (cc < ccend)
6679        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6680        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6681        }        }
6682      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6683      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6684        decrease_call_count(common);        decrease_call_count(common);
6685      break;      break;
# Line 6605  while (cc < ccend) Line 6692  while (cc < ccend)
6692      case OP_SBRA:      case OP_SBRA:
6693      case OP_SCBRA:      case OP_SCBRA:
6694      case OP_SCOND:      case OP_SCOND:
6695      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6696      break;      break;
6697    
6698      case OP_BRAZERO:      case OP_BRAZERO:
6699      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6700        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6701      else      else
6702        {        {
6703        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6704        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6705        }        }
6706      break;      break;
6707    
# Line 6623  while (cc < ccend) Line 6710  while (cc < ccend)
6710      case OP_SBRAPOS:      case OP_SBRAPOS:
6711      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6712      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6713      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6714      break;      break;
6715    
6716      case OP_MARK:      case OP_MARK:
# Line 6647  while (cc < ccend) Line 6734  while (cc < ccend)
6734      case OP_FAIL:      case OP_FAIL:
6735      case OP_ACCEPT:      case OP_ACCEPT:
6736      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6737      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6738      break;      break;
6739    
6740      case OP_CLOSE:      case OP_CLOSE:
6741      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6742      break;      break;
6743    
6744      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 6672  SLJIT_ASSERT(cc == ccend); Line 6759  SLJIT_ASSERT(cc == ccend);
6759  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6760  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6761    
6762  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6763    do \    do \
6764      { \      { \
6765      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6766      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6767        return; \        return; \
6768      } \      } \
# Line 6683  SLJIT_ASSERT(cc == ccend); Line 6770  SLJIT_ASSERT(cc == ccend);
6770    
6771  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6772    
6773  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6774  {  {
6775  DEFINE_COMPILER;  DEFINE_COMPILER;
6776  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6693  int arg1 = -1, arg2 = -1; Line 6780  int arg1 = -1, arg2 = -1;
6780  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6781  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6782  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6783  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6784  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);
6785  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6786  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);
6787    
6788  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6789    
# Line 6708  switch(opcode) Line 6795  switch(opcode)
6795    case OP_CRRANGE:    case OP_CRRANGE:
6796    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6797      {      {
6798      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6799      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6800      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6801      free_stack(common, 1);      free_stack(common, 1);
6802      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);
6803      }      }
6804    else    else
6805      {      {
# Line 6732  switch(opcode) Line 6819  switch(opcode)
6819        }        }
6820      skip_char_back(common);      skip_char_back(common);
6821      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6822      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6823      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6824        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6825      JUMPHERE(jump);      JUMPHERE(jump);
6826      if (localptr == 0)      if (private_data_ptr == 0)
6827        free_stack(common, 2);        free_stack(common, 2);
6828      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6829        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6746  switch(opcode) Line 6833  switch(opcode)
6833    case OP_MINSTAR:    case OP_MINSTAR:
6834    case OP_MINPLUS:    case OP_MINPLUS:
6835    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6836    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6837    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6838    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6839    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6840    if (localptr == 0)    if (private_data_ptr == 0)
6841      free_stack(common, 1);      free_stack(common, 1);
6842    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6843      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6764  switch(opcode) Line 6851  switch(opcode)
6851      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6852      }      }
6853    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6854    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6855    
6856    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6857    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6775  switch(opcode) Line 6862  switch(opcode)
6862      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6863    
6864    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6865      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6866    else    else
6867      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);
6868    
6869    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6870    if (localptr == 0)    if (private_data_ptr == 0)
6871      free_stack(common, 2);      free_stack(common, 2);
6872    break;    break;
6873    
6874    case OP_QUERY:    case OP_QUERY:
6875    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6876    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6877    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);
6878    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6879    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6880    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6881    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6882    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6883    JUMPHERE(jump);    JUMPHERE(jump);
6884    if (localptr == 0)    if (private_data_ptr == 0)
6885      free_stack(common, 1);      free_stack(common, 1);
6886    break;    break;
6887    
# Line 6802  switch(opcode) Line 6889  switch(opcode)
6889    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6890    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6891    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6892    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6893    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6894    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6895    JUMPHERE(jump);    JUMPHERE(jump);
6896    if (localptr == 0)    if (private_data_ptr == 0)
6897      free_stack(common, 1);      free_stack(common, 1);
6898    break;    break;
6899    
# Line 6826  switch(opcode) Line 6913  switch(opcode)
6913    }    }
6914  }  }
6915    
6916  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)
6917  {  {
6918  DEFINE_COMPILER;  DEFINE_COMPILER;
6919  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6838  if ((type & 0x1) == 0) Line 6925  if ((type & 0x1) == 0)
6925    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6926    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6927    free_stack(common, 1);    free_stack(common, 1);
6928    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);
6929    return;    return;
6930    }    }
6931    
6932  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6933  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);
6934  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6935  free_stack(common, 2);  free_stack(common, 2);
6936  }  }
6937    
6938  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6939  {  {
6940  DEFINE_COMPILER;  DEFINE_COMPILER;
6941    
# Line 6870  else if (common->has_set_som || common-> Line 6957  else if (common->has_set_som || common->
6957    }    }
6958  }  }
6959    
6960  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6961  {  {
6962  DEFINE_COMPILER;  DEFINE_COMPILER;
6963  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6897  if (CURRENT_AS(assert_backtrack)->frames Line 6984  if (CURRENT_AS(assert_backtrack)->frames
6984    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6985      {      {
6986      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6987      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);
6988      free_stack(common, 1);      free_stack(common, 1);
6989      }      }
6990    return;    return;
# Line 6908  if (bra == OP_BRAZERO) Line 6995  if (bra == OP_BRAZERO)
6995    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6996      {      {
6997      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6998      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);
6999      free_stack(common, 1);      free_stack(common, 1);
7000      return;      return;
7001      }      }
# Line 6918  if (bra == OP_BRAZERO) Line 7005  if (bra == OP_BRAZERO)
7005    
7006  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7007    {    {
7008    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);
7009    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7010    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));
7011    
7012    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7013    }    }
# Line 6932  if (bra == OP_BRAZERO) Line 7019  if (bra == OP_BRAZERO)
7019    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
7020    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));
7021    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7022    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
7023    JUMPHERE(brajump);    JUMPHERE(brajump);
7024    }    }
7025  }  }
7026    
7027  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7028  {  {
7029  DEFINE_COMPILER;  DEFINE_COMPILER;
7030  int opcode;  int opcode;
7031  int offset = 0;  int offset = 0;
7032  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7033  int stacksize;  int stacksize;
7034  int count;  int count;
7035  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6997  else if (ket == OP_KETRMIN) Line 7084  else if (ket == OP_KETRMIN)
7084        {        {
7085        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7086        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7087          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);
7088        else        else
7089          {          {
7090          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7091          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);
7092          }          }
7093        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7094          free_stack(common, 1);          free_stack(common, 1);
7095        }        }
7096      else      else
7097        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7098      }      }
7099    rminlabel = LABEL();    rminlabel = LABEL();
7100    }    }
# Line 7022  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7109  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7109    {    {
7110    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7111      {      {
7112      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);
7113      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7114      }      }
7115    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 7075  else if (*cc == OP_ALT) Line 7162  else if (*cc == OP_ALT)
7162    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7163    }    }
7164    
7165  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7166  if (current->topbacktracks)  if (current->topbacktracks)
7167    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7168    
# Line 7088  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7175  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7175      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7176      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))
7177        {        {
7178        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);
7179        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7180        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));
7181        }        }
7182      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7183      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 7206  if (has_alternatives)
7206        cc += GET(cc, 1);        cc += GET(cc, 1);
7207        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7208          {          {
7209          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7210            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);
7211          else          else
7212            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7213          }          }
7214        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7215        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7216          return;          return;
7217        }        }
7218    
7219      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7220      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7221      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7222        {        {
7223        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7224          {          {
7225          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);
7226          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7227          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7228            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7229          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7230            {            {
7231            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7232            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);
7233            }            }
7234          }          }
7235        else        else
7236          {          {
7237          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));
7238          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7239            {            {
7240            /* 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 7275  if (has_alternatives)
7275    
7276      if (offset != 0)      if (offset != 0)
7277        {        {
7278        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7279        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);
7280        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);
7281        }        }
7282    
7283      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7284    
7285      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7286        {        {
# Line 7202  if (has_alternatives) Line 7289  if (has_alternatives)
7289        jumplist = jumplist->next;        jumplist = jumplist->next;
7290        }        }
7291    
7292      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7293      if (current->topbacktracks)      if (current->topbacktracks)
7294        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7295      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 7217  if (has_alternatives) Line 7304  if (has_alternatives)
7304      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)
7305    
7306        {        {
7307        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);
7308        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7309        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));
7310        }        }
7311      JUMPHERE(cond);      JUMPHERE(cond);
7312      }      }
7313    
7314    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7315    if (localptr == 0)    if (private_data_ptr == 0)
7316      free_stack(common, 1);      free_stack(common, 1);
7317    }    }
7318    
7319  if (offset != 0)  if (offset != 0)
7320    {    {
7321    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7322    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7323    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7324    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7325    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7326    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);
7327    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7328        free_stack(common, 3);
7329        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7330        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7331        }
7332      else
7333        {
7334        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7335        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7336        free_stack(common, 2);
7337        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7338        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7339        }
7340    }    }
7341  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7342    {    {
7343    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));
7344    free_stack(common, 1);    free_stack(common, 1);
7345    }    }
7346  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7260  else if (opcode == OP_ONCE) Line 7359  else if (opcode == OP_ONCE)
7359      }      }
7360    
7361    JUMPHERE(once);    JUMPHERE(once);
7362    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7363    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7364      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));
7365    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7366      {      {
7367      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7368      /* See the comment below. */      /* See the comment below. */
7369      free_stack(common, 2);      free_stack(common, 2);
7370      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7371      }      }
7372    }    }
7373    
# Line 7277  if (ket == OP_KETRMAX) Line 7376  if (ket == OP_KETRMAX)
7376    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7377    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7378      free_stack(common, 1);      free_stack(common, 1);
7379    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);
7380    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7381      {      {
7382      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7383      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7384      JUMPHERE(brazero);      JUMPHERE(brazero);
7385      free_stack(common, 1);      free_stack(common, 1);
7386      }      }
# Line 7304  else if (ket == OP_KETRMIN) Line 7403  else if (ket == OP_KETRMIN)
7403  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7404    {    {
7405    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7406    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7407    JUMPHERE(brazero);    JUMPHERE(brazero);
7408    }    }
7409  }  }
7410    
7411  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7412  {  {
7413  DEFINE_COMPILER;  DEFINE_COMPILER;
7414  int offset;  int offset;
# Line 7330  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7429  if (CURRENT_AS(bracketpos_backtrack)->fr
7429    return;    return;
7430    }    }
7431    
7432  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);
7433  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7434    
7435  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7341  if (current->topbacktracks) Line 7440  if (current->topbacktracks)
7440    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7441    JUMPHERE(jump);    JUMPHERE(jump);
7442    }    }
7443  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));
7444  }  }
7445    
7446  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7447  {  {
7448  assert_backtrack backtrack;  assert_backtrack backtrack;
7449    
# Line 7353  current->topbacktracks = NULL; Line 7452  current->topbacktracks = NULL;
7452  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7453  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7454    {    {
7455    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7456    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7457    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7458    }    }
7459  else  else
7460    {    {
7461    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7462    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7463    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7464    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7465    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7466    }    }
7467  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7468  }  }
7469    
7470  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7471  {  {
7472  DEFINE_COMPILER;  DEFINE_COMPILER;
7473    
# Line 7454  while (current) Line 7553  while (current)
7553  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7554      case OP_XCLASS:      case OP_XCLASS:
7555  #endif  #endif
7556      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7557      break;      break;
7558    
7559      case OP_REF:      case OP_REF:
7560      case OP_REFI:      case OP_REFI:
7561      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7562      break;      break;
7563    
7564      case OP_RECURSE:      case OP_RECURSE:
7565      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7566      break;      break;
7567    
7568      case OP_ASSERT:      case OP_ASSERT:
7569      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7570      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7571      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7572      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7573      break;      break;
7574    
7575      case OP_ONCE:      case OP_ONCE:
# Line 7481  while (current) Line 7580  while (current)
7580      case OP_SBRA:      case OP_SBRA:
7581      case OP_SCBRA:      case OP_SCBRA:
7582      case OP_SCOND:      case OP_SCOND:
7583      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7584      break;      break;
7585    
7586      case OP_BRAZERO:      case OP_BRAZERO:
7587      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7588        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7589      else      else
7590        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7591      break;      break;
7592    
7593      case OP_BRAPOS:      case OP_BRAPOS:
# Line 7496  while (current) Line 7595  while (current)
7595      case OP_SBRAPOS:      case OP_SBRAPOS:
7596      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7597      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7598      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7599      break;      break;
7600    
7601      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7602      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7603      break;      break;
7604    
7605      case OP_MARK:      case OP_MARK:
# Line 7537  DEFINE_COMPILER; Line 7636  DEFINE_COMPILER;
7636  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7637  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);
7638  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7639  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7640  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7641  int alternativesize;  int alternativesize;
7642  BOOL needsframe;  BOOL needsframe;
# Line 7557  common->currententry->entry = LABEL(); Line 7656  common->currententry->entry = LABEL();
7656  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7657    
7658  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7659  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7660  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);
7661  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);
7662  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);
7663  if (needsframe)  if (needsframe)
7664    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 7582  while (1) Line 7681  while (1)
7681    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7682      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7683    
7684    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7685    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7686      {      {
7687      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7592  while (1) Line 7691  while (1)
7691    
7692    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7693    
7694    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
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 7625  if (needsframe) Line 7724  if (needsframe)
7724  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
7725    
7726  JUMPHERE(jump);  JUMPHERE(jump);
7727  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);
7728  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7729  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
7730  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7731  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 7735  common->quitlabel = save_quitlabel;
7735  common->quit = save_quit;  common->quit = save_quit;
7736  }  }
7737    
7738  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKINGPATH
7739  #undef CURRENT_AS  #undef CURRENT_AS
7740    
7741  void  void
# Line 7648  compiler_common common_data; Line 7747  compiler_common common_data;
7747  compiler_common *common = &common_data;  compiler_common *common = &common_data;
7748  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
7749  pcre_study_data *study;  pcre_study_data *study;
7750  int localsize;  int private_data_size;
7751  pcre_uchar *ccend;  pcre_uchar *ccend;
7752  executable_functions *functions;  executable_functions *functions;
7753  void *executable_func;  void *executable_func;
# Line 7724  ccend = bracketend(rootbacktrack.cc); Line 7823  ccend = bracketend(rootbacktrack.cc);
7823    
7824  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7825  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7826    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7827    if (!common->optimized_cbracket)
7828      return;
7829    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7830    
7831  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7832  localsize = get_localspace(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7833  if (localsize < 0)  if (private_data_size < 0)
7834      {
7835      SLJIT_FREE(common->optimized_cbracket);
7836    return;    return;
7837      }
7838    
7839  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7840  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 7864  if ((common->ovector_start & sizeof(slji
7864    
7865  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
7866  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7867  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7868  if (localsize > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7869      {
7870      SLJIT_FREE(common->optimized_cbracket);
7871    return;    return;
7872  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));    }
7873  if (!common->localptrs)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7874    if (!common->private_data_ptrs)
7875      {
7876      SLJIT_FREE(common->optimized_cbracket);
7877    return;    return;
7878  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));    }
7879  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7880    set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7881    
7882  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7883  if (!compiler)  if (!compiler)
7884    {    {
7885    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7886      SLJIT_FREE(common->private_data_ptrs);
7887    return;    return;
7888    }    }
7889  common->compiler = compiler;  common->compiler = compiler;
7890    
7891  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
7892  sljit_emit_enter(compiler, 1, 5, 5, localsize);  sljit_emit_enter(compiler, 1, 5, 5, private_data_size);
7893    
7894  /* Register init. */  /* Register init. */
7895  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
# Line 7804  if ((re->options & PCRE_ANCHORED) == 0) Line 7917  if ((re->options & PCRE_ANCHORED) == 0)
7917    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7918      {      {
7919      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7920        /* Do nothing */;        { /* Do nothing */ }
7921      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7922        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);
7923      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
# Line 7832  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7945  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7945  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
7946    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);
7947    
7948  compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7949  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7950    {    {
7951    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7952    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7953      SLJIT_FREE(common->private_data_ptrs);
7954    return;    return;
7955    }    }
7956    
# Line 7862  if (mode != JIT_COMPILE) Line 7976  if (mode != JIT_COMPILE)
7976    }    }
7977    
7978  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
7979  compile_backtrackpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
7980  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7981    {    {
7982    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7983    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7984      SLJIT_FREE(common->private_data_ptrs);
7985    return;    return;
7986    }    }
7987    
# Line 7944  while (common->currententry != NULL) Line 8059  while (common->currententry != NULL)
8059    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8060      {      {
8061      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8062      SLJIT_FREE(common->localptrs);      SLJIT_FREE(common->optimized_cbracket);
8063        SLJIT_FREE(common->private_data_ptrs);
8064      return;      return;
8065      }      }
8066    flush_stubs(common);    flush_stubs(common);
# Line 8039  if (common->getucd != NULL) Line 8155  if (common->getucd != NULL)
8155    }    }
8156  #endif  #endif
8157    
8158  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->optimized_cbracket);
8159    SLJIT_FREE(common->private_data_ptrs);
8160  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8161  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
8162  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8083  union { Line 8200  union {
8200     void* executable_func;     void* executable_func;
8201     jit_function call_executable_func;     jit_function call_executable_func;
8202  } convert_executable_func;  } convert_executable_func;
8203  pcre_uint8 local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_space[MACHINE_STACK_SIZE];
8204  struct sljit_stack local_stack;  struct sljit_stack local_stack;
8205    
8206  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_space;
8207  local_stack.base = local_stack.top;  local_stack.base = local_stack.top;
8208  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
8209  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
8210  arguments->stack = &local_stack;  arguments->stack = &local_stack;
8211  convert_executable_func.executable_func = executable_func;  convert_executable_func.executable_func = executable_func;

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

  ViewVC Help
Powered by ViewVC 1.1.5