/[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 989 by zherczeg, Sat Jul 7 11:11:02 2012 UTC revision 1012 by zherczeg, Sat Aug 25 15:34:13 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 181  typedef struct stub_list { Line 184  typedef struct stub_list {
184    enum stub_types type;    enum stub_types type;
185    int data;    int data;
186    struct sljit_jump *start;    struct sljit_jump *start;
187    struct sljit_label *leave;    struct sljit_label *quit;
188    struct stub_list *next;    struct stub_list *next;
189  } stub_list;  } stub_list;
190    
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 268  typedef struct recurse_backtrack { Line 271  typedef struct recurse_backtrack {
271    backtrack_common common;    backtrack_common common;
272  } recurse_backtrack;  } recurse_backtrack;
273    
274    #define MAX_RANGE_SIZE 6
275    
276  typedef struct compiler_common {  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 290  typedef struct compiler_common { Line 298  typedef struct compiler_common {
298    /* Points to the marked string. */    /* Points to the marked string. */
299    int mark_ptr;    int mark_ptr;
300    
301    /* Other  */    /* Flipped and lower case tables. */
302    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
303    sljit_w lcc;    sljit_w lcc;
304      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
305    int mode;    int mode;
306      /* Newline control. */
307    int nltype;    int nltype;
308    int newline;    int newline;
309    int bsr_nltype;    int bsr_nltype;
310      /* Dollar endonly. */
311    int endonly;    int endonly;
312    BOOL has_set_som;    BOOL has_set_som;
313      /* Tables. */
314    sljit_w ctypes;    sljit_w ctypes;
315      int digits[2 + MAX_RANGE_SIZE];
316      /* Named capturing brackets. */
317    sljit_uw name_table;    sljit_uw name_table;
318    sljit_w name_count;    sljit_w name_count;
319    sljit_w name_entry_size;    sljit_w name_entry_size;
320    
321    /* Labels and jump lists. */    /* Labels and jump lists. */
322    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
323    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
324    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
325    stub_list *stubs;    stub_list *stubs;
326    recurse_entry *entries;    recurse_entry *entries;
327    recurse_entry *currententry;    recurse_entry *currententry;
328    jump_list *partialmatch;    jump_list *partialmatch;
329    jump_list *leave;    jump_list *quit;
330    jump_list *accept;    jump_list *accept;
331    jump_list *calllimit;    jump_list *calllimit;
332    jump_list *stackalloc;    jump_list *stackalloc;
# Line 396  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 412  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 461  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 667  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 685  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 695  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 705  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 744  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 764  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 773  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 801  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 873  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 899  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 926  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 943  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 958  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 1011  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 1214  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 1235  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 1255  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 1312  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 1324  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 1397  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 1424  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 1442  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 1455  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 1468  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 1505  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 1628  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 1645  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 1672  if (list_item) Line 1729  if (list_item)
1729    list_item->type = type;    list_item->type = type;
1730    list_item->data = data;    list_item->data = data;
1731    list_item->start = start;    list_item->start = start;
1732    list_item->leave = LABEL();    list_item->quit = LABEL();
1733    list_item->next = common->stubs;    list_item->next = common->stubs;
1734    common->stubs = list_item;    common->stubs = list_item;
1735    }    }
# Line 1692  while (list_item) Line 1749  while (list_item)
1749      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1750      break;      break;
1751      }      }
1752    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1753    list_item = list_item->next;    list_item = list_item->next;
1754    }    }
1755  common->stubs = NULL;  common->stubs = NULL;
# Line 1802  else Line 1859  else
1859    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1860  }  }
1861    
1862  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1863  {  {
1864  DEFINE_COMPILER;  DEFINE_COMPILER;
1865    
# Line 1812  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1869  SLJIT_ASSERT(common->start_used_ptr != 0
1869  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1870  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1871  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1872  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1873    
1874  /* Store match begin and end. */  /* Store match begin and end. */
1875  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 1830  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1887  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1887  #endif  #endif
1888  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1889    
1890  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1891  }  }
1892    
1893  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 2411  if (firstline) Line 2468  if (firstline)
2468    {    {
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, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 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 2423  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 2434  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    
2499    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2500    }    }
2501    
2502  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2510  static SLJIT_INLINE BOOL fast_forward_fi Line 2567  static SLJIT_INLINE BOOL fast_forward_fi
2567  {  {
2568  DEFINE_COMPILER;  DEFINE_COMPILER;
2569  struct sljit_label *start;  struct sljit_label *start;
2570  struct sljit_jump *leave;  struct sljit_jump *quit;
2571  struct sljit_jump *found;  struct sljit_jump *found;
2572  pcre_int32 chars[4];  pcre_int32 chars[4];
2573  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
# Line 2639  while (TRUE) Line 2696  while (TRUE)
2696    
2697  if (firstline)  if (firstline)
2698    {    {
2699    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2700      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2701    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2702    }    }
2703  else  else
2704    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    
2706  start = LABEL();  start = LABEL();
2707  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2708  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2709  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
2710  OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2687  found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJI Line 2745  found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJI
2745  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2746  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2747  JUMPHERE(found);  JUMPHERE(found);
2748  JUMPHERE(leave);  JUMPHERE(quit);
2749    
2750  if (firstline)  if (firstline)
2751    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2752  OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);  else
2753      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2754  return TRUE;  return TRUE;
2755  }  }
2756    
# Line 2699  static SLJIT_INLINE void fast_forward_fi Line 2758  static SLJIT_INLINE void fast_forward_fi
2758  {  {
2759  DEFINE_COMPILER;  DEFINE_COMPILER;
2760  struct sljit_label *start;  struct sljit_label *start;
2761  struct sljit_jump *leave;  struct sljit_jump *quit;
2762  struct sljit_jump *found;  struct sljit_jump *found;
2763  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2764    
2765  if (firstline)  if (firstline)
2766    {    {
2767    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2768      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2769    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);
2770    }    }
2771    
2772  start = LABEL();  start = LABEL();
2773  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2774  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2775    
2776  oc = first_char;  oc = first_char;
# Line 2745  else Line 2805  else
2805  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2806  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2807  JUMPHERE(found);  JUMPHERE(found);
2808  JUMPHERE(leave);  JUMPHERE(quit);
2809    
2810  if (firstline)  if (firstline)
2811    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2812  }  }
2813    
2814  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2757  DEFINE_COMPILER; Line 2817  DEFINE_COMPILER;
2817  struct sljit_label *loop;  struct sljit_label *loop;
2818  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2819  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2820  struct sljit_jump *leave;  struct sljit_jump *quit;
2821  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2822  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2823  jump_list *newline = NULL;  jump_list *newline = NULL;
2824    
2825  if (firstline)  if (firstline)
2826    {    {
2827    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2828      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2829    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);
2830    }    }
2831    
# Line 2786  if (common->nltype == NLTYPE_FIXED && co Line 2847  if (common->nltype == NLTYPE_FIXED && co
2847    
2848    loop = LABEL();    loop = LABEL();
2849    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2850    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2851    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2852    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2853    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2854    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2855    
2856    JUMPHERE(leave);    JUMPHERE(quit);
2857    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2858    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2859    
# Line 2816  set_jumps(newline, loop); Line 2877  set_jumps(newline, loop);
2877    
2878  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2879    {    {
2880    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2881    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2882    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2883    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2827  if (common->nltype == NLTYPE_ANY || comm Line 2888  if (common->nltype == NLTYPE_ANY || comm
2888  #endif  #endif
2889    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2890    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2891    JUMPHERE(leave);    JUMPHERE(quit);
2892    }    }
2893  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2894  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2895    
2896  if (firstline)  if (firstline)
2897    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2898  }  }
2899    
2900  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2901  {  {
2902  DEFINE_COMPILER;  DEFINE_COMPILER;
2903  struct sljit_label *start;  struct sljit_label *start;
2904  struct sljit_jump *leave;  struct sljit_jump *quit;
2905  struct sljit_jump *found;  struct sljit_jump *found;
2906  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2907  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2848  struct sljit_jump *jump; Line 2909  struct sljit_jump *jump;
2909    
2910  if (firstline)  if (firstline)
2911    {    {
2912    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2913      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    
2917  start = LABEL();  start = LABEL();
2918  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2919  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2920  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2921  if (common->utf)  if (common->utf)
# Line 2897  if (common->utf) Line 2959  if (common->utf)
2959  #endif  #endif
2960  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2961  JUMPHERE(found);  JUMPHERE(found);
2962  JUMPHERE(leave);  JUMPHERE(quit);
2963    
2964  if (firstline)  if (firstline)
2965    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    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 3124  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3186  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3186  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3187  }  }
3188    
3189    /*
3190      range format:
3191    
3192      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3193      ranges[1] = first bit (0 or 1)
3194      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3195    */
3196    
3197    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3198    {
3199    DEFINE_COMPILER;
3200    struct sljit_jump *jump;
3201    
3202    if (ranges[0] < 0)
3203      return FALSE;
3204    
3205    switch(ranges[0])
3206      {
3207      case 1:
3208      if (readch)
3209        read_char(common);
3210      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3211      return TRUE;
3212    
3213      case 2:
3214      if (readch)
3215        read_char(common);
3216      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3217      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3218      return TRUE;
3219    
3220      case 4:
3221      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3222        {
3223        if (readch)
3224          read_char(common);
3225        if (ranges[1] != 0)
3226          {
3227          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3228          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3229          }
3230        else
3231          {
3232          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3233          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3234          JUMPHERE(jump);
3235          }
3236        return TRUE;
3237        }
3238      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3239        {
3240        if (readch)
3241          read_char(common);
3242        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3243        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3244        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3245        return TRUE;
3246        }
3247      return FALSE;
3248    
3249      default:
3250      return FALSE;
3251      }
3252    }
3253    
3254    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3255    {
3256    int i, bit, length;
3257    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3258    
3259    bit = ctypes[0] & flag;
3260    ranges[0] = -1;
3261    ranges[1] = bit != 0 ? 1 : 0;
3262    length = 0;
3263    
3264    for (i = 1; i < 256; i++)
3265      if ((ctypes[i] & flag) != bit)
3266        {
3267        if (length >= MAX_RANGE_SIZE)
3268          return;
3269        ranges[2 + length] = i;
3270        length++;
3271        bit ^= flag;
3272        }
3273    
3274    if (bit != 0)
3275      {
3276      if (length >= MAX_RANGE_SIZE)
3277        return;
3278      ranges[2 + length] = 256;
3279      length++;
3280      }
3281    ranges[0] = length;
3282    }
3283    
3284    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3285    {
3286    int ranges[2 + MAX_RANGE_SIZE];
3287    pcre_uint8 bit, cbit, all;
3288    int i, byte, length = 0;
3289    
3290    bit = bits[0] & 0x1;
3291    ranges[1] = bit;
3292    /* Can be 0 or 255. */
3293    all = -bit;
3294    
3295    for (i = 0; i < 256; )
3296      {
3297      byte = i >> 3;
3298      if ((i & 0x7) == 0 && bits[byte] == all)
3299        i += 8;
3300      else
3301        {
3302        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3303        if (cbit != bit)
3304          {
3305          if (length >= MAX_RANGE_SIZE)
3306            return FALSE;
3307          ranges[2 + length] = i;
3308          length++;
3309          bit = cbit;
3310          all = -cbit;
3311          }
3312        i++;
3313        }
3314      }
3315    
3316    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3317      {
3318      if (length >= MAX_RANGE_SIZE)
3319        return FALSE;
3320      ranges[2 + length] = 256;
3321      length++;
3322      }
3323    ranges[0] = length;
3324    
3325    return check_ranges(common, ranges, backtracks, FALSE);
3326    }
3327    
3328  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3329  {  {
3330  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 3499  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 3517  unsigned int typeoffset; Line 3718  unsigned int typeoffset;
3718  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3719  unsigned int charoffset;  unsigned int charoffset;
3720    
3721  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3722       not necessary in utf mode even in 8 bit mode. */
3723  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3724  read_char(common);  read_char(common);
3725    
# Line 3531  if ((*cc++ & XCL_MAP) != 0) Line 3733  if ((*cc++ & XCL_MAP) != 0)
3733      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3734  #endif  #endif
3735    
3736    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3737    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3738    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3739    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3740    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3741    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3742        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3743        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3744        }
3745    
3746  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3747    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3836  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 3872  switch(type) Line 4077  switch(type)
4077    
4078    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4079    case OP_DIGIT:    case OP_DIGIT:
4080      /* Digits are usually 0-9, so it is worth to optimize them. */
4081      if (common->digits[0] == -2)
4082        get_ctype_ranges(common, ctype_digit, common->digits);
4083    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4084    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4085    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4086    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4087      if (!check_ranges(common, common->digits, backtracks, TRUE))
4088        {
4089        read_char8_type(common);
4090        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4091        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4092        }
4093      if (type == OP_NOT_DIGIT)
4094        common->digits[1] ^= 1;
4095    return cc;    return cc;
4096    
4097    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3957  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 4003  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));    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4224    
4225    label = LABEL();    label = LABEL();
4226    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);
4227    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
4228    read_char(common);    read_char(common);
4229    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4230    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));
4231    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);
4232    
4233    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP2(SLJIT_MUL, TMP1, 0, TMP3, 0, SLJIT_IMM, ucp_gbCount);
4234      OP1(SLJIT_MOV, TMP3, 0, TMP2, 0);
4235      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
4236      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(ucp_gbtable));
4237      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, label);
4238    
4239      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4240    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4241    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4242      {      {
# Line 4141  switch(type) Line 4363  switch(type)
4363    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));
4364    
4365    if (!common->endonly)    if (!common->endonly)
4366      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4367    else    else
4368      {      {
4369      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 4229  switch(type) Line 4451  switch(type)
4451      }      }
4452    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);
4453    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4454    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);
4455    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4456    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4457    return cc + length;    return cc + length;
# Line 4299  switch(type) Line 4521  switch(type)
4521    case OP_NCLASS:    case OP_NCLASS:
4522    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4523    read_char(common);    read_char(common);
4524      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4525        return cc + 32 / sizeof(pcre_uchar);
4526    
4527  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4528    jump[0] = NULL;    jump[0] = NULL;
4529  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 4329  switch(type) Line 4554  switch(type)
4554    
4555  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4556    case OP_XCLASS:    case OP_XCLASS:
4557    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4558    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4559  #endif  #endif
4560    
# Line 4363  SLJIT_ASSERT_STOP(); Line 4588  SLJIT_ASSERT_STOP();
4588  return cc;  return cc;
4589  }  }
4590    
4591  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)
4592  {  {
4593  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4594  /* 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 4426  if (context.length > 0) Line 4651  if (context.length > 0)
4651    }    }
4652    
4653  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4654  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4655  }  }
4656    
4657  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 4452  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4677  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4677  }  }
4678    
4679  /* Forward definitions. */  /* Forward definitions. */
4680  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4681  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4682    
4683  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4684    do \    do \
# Line 4483  static void compile_backtrackpath(compil Line 4708  static void compile_backtrackpath(compil
4708    
4709  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4710    
4711  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)
4712  {  {
4713  DEFINE_COMPILER;  DEFINE_COMPILER;
4714  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 4565  if (jump != NULL) Line 4790  if (jump != NULL)
4790  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4791  }  }
4792    
4793  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)
4794  {  {
4795  DEFINE_COMPILER;  DEFINE_COMPILER;
4796  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4636  if (!minimize) Line 4861  if (!minimize)
4861      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4862    
4863    label = LABEL();    label = LABEL();
4864    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4865    
4866    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4867      {      {
# Line 4664  if (!minimize) Line 4889  if (!minimize)
4889      }      }
4890    
4891    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4892    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4893    
4894    decrease_call_count(common);    decrease_call_count(common);
4895    return cc;    return cc;
# Line 4684  if (min == 0) Line 4909  if (min == 0)
4909  else  else
4910    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4911    
4912  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4913  if (max > 0)  if (max > 0)
4914    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));
4915    
4916  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4917  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4918    
4919  if (min > 1)  if (min > 1)
# Line 4696  if (min > 1) Line 4921  if (min > 1)
4921    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4922    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4923    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4924    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);
4925    }    }
4926  else if (max > 0)  else if (max > 0)
4927    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 4709  decrease_call_count(common); Line 4934  decrease_call_count(common);
4934  return cc;  return cc;
4935  }  }
4936    
4937  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)
4938  {  {
4939  DEFINE_COMPILER;  DEFINE_COMPILER;
4940  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4766  add_jump(compiler, &backtrack->topbacktr Line 4991  add_jump(compiler, &backtrack->topbacktr
4991  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4992  }  }
4993    
4994  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)
4995  {  {
4996  DEFINE_COMPILER;  DEFINE_COMPILER;
4997  int framesize;  int framesize;
4998  int localptr;  int private_data_ptr;
4999  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5000  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5001  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4779  jump_list *tmp = NULL; Line 5004  jump_list *tmp = NULL;
5004  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5005  jump_list **found;  jump_list **found;
5006  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5007  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5008  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5009  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5010  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5011  struct sljit_jump *jump;  struct sljit_jump *jump;
5012  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4792  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5017  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5017    bra = *cc;    bra = *cc;
5018    cc++;    cc++;
5019    }    }
5020  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5021  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5022  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5023  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5024  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5025  opcode = *cc;  opcode = *cc;
5026  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5027  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4813  if (bra == OP_BRAMINZERO) Line 5038  if (bra == OP_BRAMINZERO)
5038    
5039  if (framesize < 0)  if (framesize < 0)
5040    {    {
5041    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);
5042    allocate_stack(common, 1);    allocate_stack(common, 1);
5043    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5044    }    }
5045  else  else
5046    {    {
5047    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5048    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5049    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));
5050    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5051    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5052    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5053    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5054    }    }
5055    
5056  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5057  common->leavelabel = NULL;  common->quitlabel = NULL;
5058  common->leave = NULL;  common->quit = NULL;
5059  while (1)  while (1)
5060    {    {
5061    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4842  while (1) Line 5067  while (1)
5067      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5068    
5069    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5070    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5074      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5075      common->leave = save_leave;      common->quit = save_quit;
5076      common->accept = save_accept;      common->accept = save_accept;
5077      return NULL;      return NULL;
5078      }      }
# Line 4857  while (1) Line 5082  while (1)
5082    
5083    /* Reset stack. */    /* Reset stack. */
5084    if (framesize < 0)    if (framesize < 0)
5085      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);
5086    else {    else {
5087      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5088        {        {
5089        /* 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. */
5090        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));
5091        }        }
5092      else      else
5093        {        {
5094        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);
5095        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5096        }        }
5097    }    }
# Line 4884  while (1) Line 5109  while (1)
5109          {          {
5110          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));
5111          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));
5112          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5113          }          }
5114        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));
5115        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 4892  while (1) Line 5117  while (1)
5117      else if (framesize >= 0)      else if (framesize >= 0)
5118        {        {
5119        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5120        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));
5121        }        }
5122      }      }
5123    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5124    
5125    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5126    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5127      {      {
5128      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5129      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5130      common->leave = save_leave;      common->quit = save_quit;
5131      common->accept = save_accept;      common->accept = save_accept;
5132      return NULL;      return NULL;
5133      }      }
# Line 4915  while (1) Line 5140  while (1)
5140    cc += GET(cc, 1);    cc += GET(cc, 1);
5141    }    }
5142  /* None of them matched. */  /* None of them matched. */
5143  if (common->leave != NULL)  if (common->quit != NULL)
5144    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5145    
5146  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5147    {    {
# Line 4943  if (opcode == OP_ASSERT || opcode == OP_ Line 5168  if (opcode == OP_ASSERT || opcode == OP_
5168        }        }
5169      else      else
5170        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5171      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5172      }      }
5173    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5174    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4968  if (opcode == OP_ASSERT || opcode == OP_ Line 5193  if (opcode == OP_ASSERT || opcode == OP_
5193      {      {
5194      if (bra == OP_BRA)      if (bra == OP_BRA)
5195        {        {
5196        /* 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. */
5197        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));
5198        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5199        }        }
5200      else      else
5201        {        {
5202        /* 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. */
5203        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));
5204        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5205        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);
5206        }        }
# Line 4983  if (opcode == OP_ASSERT || opcode == OP_ Line 5208  if (opcode == OP_ASSERT || opcode == OP_
5208    
5209    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5210      {      {
5211      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5212      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5213      }      }
5214    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5215      {      {
5216      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5217      JUMPHERE(brajump);      JUMPHERE(brajump);
5218      if (framesize >= 0)      if (framesize >= 0)
5219        {        {
5220        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);
5221        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5222        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));
5223        }        }
5224      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5225      }      }
# Line 5022  else Line 5247  else
5247        }        }
5248      else      else
5249        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5250      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5251      }      }
5252    
5253    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5254      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5255    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5256      {      {
5257      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5258      JUMPHERE(brajump);      JUMPHERE(brajump);
5259      }      }
5260    
# Line 5041  else Line 5266  else
5266      }      }
5267    }    }
5268    
5269  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5270  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5271  common->leave = save_leave;  common->quit = save_quit;
5272  common->accept = save_accept;  common->accept = save_accept;
5273  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5274  }  }
# Line 5212  return condition; Line 5437  return condition;
5437                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5438  */  */
5439    
5440  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)
5441  {  {
5442  DEFINE_COMPILER;  DEFINE_COMPILER;
5443  backtrack_common *backtrack;  backtrack_common *backtrack;
5444  pcre_uchar opcode;  pcre_uchar opcode;
5445  int localptr = 0;  int private_data_ptr = 0;
5446  int offset = 0;  int offset = 0;
5447  int stacksize;  int stacksize;
5448  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5449  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5450  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5451  pcre_uchar ket;  pcre_uchar ket;
5452  assert_backtrack *assert;  assert_backtrack *assert;
# Line 5242  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5467  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5467    
5468  opcode = *cc;  opcode = *cc;
5469  ccbegin = cc;  ccbegin = cc;
5470  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5471    
5472  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)
5473    {    {
# Line 5259  cc += GET(cc, 1); Line 5484  cc += GET(cc, 1);
5484  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5485  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5486    {    {
5487    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5488    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5489      {      {
5490      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5491      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5492        has_alternatives = FALSE;        has_alternatives = FALSE;
5493      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 5281  if (opcode == OP_CBRA || opcode == OP_SC Line 5506  if (opcode == OP_CBRA || opcode == OP_SC
5506    {    {
5507    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5508    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5509    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5510    offset <<= 1;      {
5511    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5512    trypath += IMM2_SIZE;      offset <<= 1;
5513        }
5514      else
5515        {
5516        offset <<= 1;
5517        private_data_ptr = OVECTOR(offset);
5518        }
5519      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5520      matchingpath += IMM2_SIZE;
5521    }    }
5522  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5523    {    {
5524    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5525    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5526    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5527    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5528    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5529      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5530    }    }
# Line 5337  if (bra == OP_BRAMINZERO) Line 5570  if (bra == OP_BRAMINZERO)
5570        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5571        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5572          {          {
5573          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5574          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);
5575          }          }
5576        else        else
5577          {          {
5578          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5579          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5580          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));
5581          }          }
5582        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5358  if (bra == OP_BRAMINZERO) Line 5591  if (bra == OP_BRAMINZERO)
5591    }    }
5592    
5593  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5594    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5595    
5596  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5597    {    {
5598    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5599    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5600      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5601    }    }
5602    
5603  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 5375  if (opcode == OP_ONCE) Line 5608  if (opcode == OP_ONCE)
5608      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5609      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5610        {        {
5611        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5612        allocate_stack(common, 2);        allocate_stack(common, 2);
5613        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5614        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5615        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));
5616        }        }
5617      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5618        {        {
5619        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);
5620        allocate_stack(common, 1);        allocate_stack(common, 1);
5621        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5622        }        }
5623      else      else
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      }      }
5626    else    else
5627      {      {
5628      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5629        {        {
5630        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5631        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5632        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));
5633        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5634        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5635        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5636        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);
5637        }        }
5638      else      else
5639        {        {
5640        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5641        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5642        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));
5643        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5644        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5645        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5646        }        }
# Line 5416  if (opcode == OP_ONCE) Line 5649  if (opcode == OP_ONCE)
5649  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5650    {    {
5651    /* Saving the previous values. */    /* Saving the previous values. */
5652    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5653    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5654    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5655    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5656    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5657    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5658    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);
5659    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5660        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5661        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5662        }
5663      else
5664        {
5665        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5666        allocate_stack(common, 2);
5667        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5668        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5669        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5670        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5671        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5672        }
5673    }    }
5674  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5675    {    {
5676    /* Saving the previous value. */    /* Saving the previous value. */
5677    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5678    allocate_stack(common, 1);    allocate_stack(common, 1);
5679    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);
5680    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5681    }    }
5682  else if (has_alternatives)  else if (has_alternatives)
# Line 5443  else if (has_alternatives) Line 5689  else if (has_alternatives)
5689  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5690  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5691    {    {
5692    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5693      {      {
5694      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5695      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5696        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)));
5697      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5698      }      }
5699    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5700      {      {
5701      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5702      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5703      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));
5704    
5705      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 5467  if (opcode == OP_COND || opcode == OP_SC Line 5713  if (opcode == OP_COND || opcode == OP_SC
5713      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));
5714    
5715      JUMPHERE(jump);      JUMPHERE(jump);
5716      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5717      }      }
5718    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5719      {      {
5720      /* Never has other case. */      /* Never has other case. */
5721      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5722    
5723      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5724      if (common->currententry == NULL)      if (common->currententry == NULL)
5725        stacksize = 0;        stacksize = 0;
5726      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 5484  if (opcode == OP_COND || opcode == OP_SC Line 5730  if (opcode == OP_COND || opcode == OP_SC
5730      else      else
5731        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5732    
5733      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5734        {        {
5735        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5736        if (stacksize != 0)        if (stacksize != 0)
5737          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5738        else        else
5739          {          {
5740          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5741            {            {
5742            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5743            cc += GET(cc, 1);            cc += GET(cc, 1);
5744            }            }
5745          else          else
5746            trypath = cc;            matchingpath = cc;
5747          }          }
5748        }        }
5749      else      else
5750        {        {
5751        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5752    
5753        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5754        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5755        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);
5756        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 5515  if (opcode == OP_COND || opcode == OP_SC Line 5761  if (opcode == OP_COND || opcode == OP_SC
5761        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));
5762        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5763        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));
5764        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5765        }        }
5766      }      }
5767    else    else
5768      {      {
5769      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5770      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5771      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5772      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5773        return NULL;        return NULL;
5774      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5775      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5776      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5777      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5778      }      }
5779    }    }
5780    
5781  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5782  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5783    return NULL;    return NULL;
5784    
# Line 5540  if (opcode == OP_ONCE) Line 5786  if (opcode == OP_ONCE)
5786    {    {
5787    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5788      {      {
5789      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);
5790      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5791      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5792        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5793      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5794        {        {
5795        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5796        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);
5797        }        }
5798      }      }
5799    else    else
5800      {      {
5801      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5802      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));
5803      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5804        {        {
5805        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5588  if (has_alternatives) Line 5834  if (has_alternatives)
5834    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5835      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5836    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5837      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5838    }    }
5839    
5840  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5841  if (offset != 0)  if (offset != 0)
5842    {    {
5843    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5844    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);
5845    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);
5846    }    }
# Line 5604  if (ket == OP_KETRMAX) Line 5850  if (ket == OP_KETRMAX)
5850    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5851      {      {
5852      if (has_alternatives)      if (has_alternatives)
5853        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5854      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5855      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5856        {        {
5857        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);
5858        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5859        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5860          free_stack(common, 1);          free_stack(common, 1);
# Line 5619  if (ket == OP_KETRMAX) Line 5865  if (ket == OP_KETRMAX)
5865      }      }
5866    else    else
5867      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5868    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5869    }    }
5870    
5871  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5872    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5873    
5874  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5875    {    {
5876    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5877    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5878    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5879      {      {
5880      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5637  if (bra == OP_BRAMINZERO) Line 5883  if (bra == OP_BRAMINZERO)
5883      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5884      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5885        {        {
5886        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);
5887        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5888        }        }
5889      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5656  cc += 1 + LINK_SIZE; Line 5902  cc += 1 + LINK_SIZE;
5902  return cc;  return cc;
5903  }  }
5904    
5905  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)
5906  {  {
5907  DEFINE_COMPILER;  DEFINE_COMPILER;
5908  backtrack_common *backtrack;  backtrack_common *backtrack;
5909  pcre_uchar opcode;  pcre_uchar opcode;
5910  int localptr;  int private_data_ptr;
5911  int cbraprivptr = 0;  int cbraprivptr = 0;
5912  int framesize;  int framesize;
5913  int stacksize;  int stacksize;
# Line 5680  if (*cc == OP_BRAPOSZERO) Line 5926  if (*cc == OP_BRAPOSZERO)
5926    }    }
5927    
5928  opcode = *cc;  opcode = *cc;
5929  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5930  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5931  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5932  switch(opcode)  switch(opcode)
5933    {    {
5934    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5693  switch(opcode) Line 5939  switch(opcode)
5939    case OP_CBRAPOS:    case OP_CBRAPOS:
5940    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5941    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5942      /* This case cannot be optimized in the same was as
5943      normal capturing brackets. */
5944      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5945    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5946    offset <<= 1;    offset <<= 1;
5947    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5712  if (framesize < 0) Line 5961  if (framesize < 0)
5961      stacksize++;      stacksize++;
5962    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5963    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5964    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);
5965    
5966    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5967      {      {
# Line 5737  else Line 5986  else
5986    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5987    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5988    
5989    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5990    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));
5991    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5992    stack = 0;    stack = 0;
5993    if (!zero)    if (!zero)
5994      {      {
# Line 5765  while (*cc != OP_KETRPOS) Line 6014  while (*cc != OP_KETRPOS)
6014    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6015    cc += GET(cc, 1);    cc += GET(cc, 1);
6016    
6017    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6018    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6019      return NULL;      return NULL;
6020    
6021    if (framesize < 0)    if (framesize < 0)
6022      {      {
6023      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);
6024    
6025      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6026        {        {
# Line 5797  while (*cc != OP_KETRPOS) Line 6046  while (*cc != OP_KETRPOS)
6046      {      {
6047      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6048        {        {
6049        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));
6050        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6051        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);
6052        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 5805  while (*cc != OP_KETRPOS) Line 6054  while (*cc != OP_KETRPOS)
6054        }        }
6055      else      else
6056        {        {
6057        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6058        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));
6059        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6060          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 5826  while (*cc != OP_KETRPOS) Line 6075  while (*cc != OP_KETRPOS)
6075    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6076    flush_stubs(common);    flush_stubs(common);
6077    
6078    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6079    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6080      return NULL;      return NULL;
6081    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 5844  while (*cc != OP_KETRPOS) Line 6093  while (*cc != OP_KETRPOS)
6093        {        {
6094        /* Last alternative. */        /* Last alternative. */
6095        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6096          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6097        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6098        }        }
6099      else      else
6100        {        {
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(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6103        }        }
6104      }      }
# Line 5864  if (!zero) Line 6113  if (!zero)
6113    {    {
6114    if (framesize < 0)    if (framesize < 0)
6115      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));
6116    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6117      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));
6118    }    }
6119    
# Line 5966  if (end != NULL) Line 6215  if (end != NULL)
6215  return cc;  return cc;
6216  }  }
6217    
6218  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)
6219  {  {
6220  DEFINE_COMPILER;  DEFINE_COMPILER;
6221  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5977  pcre_uchar* end; Line 6226  pcre_uchar* end;
6226  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6227  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6228  struct sljit_label *label;  struct sljit_label *label;
6229  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6230  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);
6231  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6232  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);
6233  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6234    
6235  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6034  switch(opcode) Line 6283  switch(opcode)
6283    case OP_CRRANGE:    case OP_CRRANGE:
6284    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6285      {      {
6286      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6287      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6288        {        {
6289        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6051  switch(opcode) Line 6300  switch(opcode)
6300        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6301    
6302      label = LABEL();      label = LABEL();
6303      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6304      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6305        {        {
6306        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 6073  switch(opcode) Line 6322  switch(opcode)
6322    else    else
6323      {      {
6324      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6325        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6326      if (localptr == 0)      if (private_data_ptr == 0)
6327        allocate_stack(common, 2);        allocate_stack(common, 2);
6328      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6329      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6082  switch(opcode) Line 6331  switch(opcode)
6331      else      else
6332        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6333      label = LABEL();      label = LABEL();
6334      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6335      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6336      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
6337        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6103  switch(opcode) Line 6352  switch(opcode)
6352        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));
6353      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6354      }      }
6355    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6356    break;    break;
6357    
6358    case OP_MINSTAR:    case OP_MINSTAR:
6359    case OP_MINPLUS:    case OP_MINPLUS:
6360    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6361      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6362    if (localptr == 0)    if (private_data_ptr == 0)
6363      allocate_stack(common, 1);      allocate_stack(common, 1);
6364    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6365    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6366    break;    break;
6367    
6368    case OP_MINUPTO:    case OP_MINUPTO:
6369    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6370    if (localptr == 0)    if (private_data_ptr == 0)
6371      allocate_stack(common, 2);      allocate_stack(common, 2);
6372    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6373    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6374    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6375      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6376    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6377    break;    break;
6378    
6379    case OP_QUERY:    case OP_QUERY:
6380    case OP_MINQUERY:    case OP_MINQUERY:
6381    if (localptr == 0)    if (private_data_ptr == 0)
6382      allocate_stack(common, 1);      allocate_stack(common, 1);
6383    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6384    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6385      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6386    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6387    break;    break;
6388    
6389    case OP_EXACT:    case OP_EXACT:
6390    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6391    label = LABEL();    label = LABEL();
6392    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6393    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);
6394    JUMPTO(SLJIT_C_NOT_ZERO, label);    JUMPTO(SLJIT_C_NOT_ZERO, label);
6395    break;    break;
# Line 6149  switch(opcode) Line 6398  switch(opcode)
6398    case OP_POSPLUS:    case OP_POSPLUS:
6399    case OP_POSUPTO:    case OP_POSUPTO:
6400    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
6401      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6402    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
6403      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6404    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6405    label = LABEL();    label = LABEL();
6406    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6407    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6408    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
6409      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6169  switch(opcode) Line 6418  switch(opcode)
6418    
6419    case OP_POSQUERY:    case OP_POSQUERY:
6420    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6421    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6422    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6423    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6424    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
# Line 6184  decrease_call_count(common); Line 6433  decrease_call_count(common);
6433  return end;  return end;
6434  }  }
6435    
6436  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)
6437  {  {
6438  DEFINE_COMPILER;  DEFINE_COMPILER;
6439  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6228  add_jump(compiler, &backtrack->topbacktr Line 6477  add_jump(compiler, &backtrack->topbacktr
6477  return cc + 1;  return cc + 1;
6478  }  }
6479    
6480  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)
6481  {  {
6482  DEFINE_COMPILER;  DEFINE_COMPILER;
6483  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6484    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6485    
6486  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6487  if (common->currententry != NULL)  if (common->currententry != NULL)
6488    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6489    
6490  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6491      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6492  offset <<= 1;  offset <<= 1;
6493  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);
6494  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6495      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6496  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6497  }  }
6498    
6499  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)
6500  {  {
6501  DEFINE_COMPILER;  DEFINE_COMPILER;
6502  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6283  while (cc < ccend) Line 6535  while (cc < ccend)
6535      case OP_NOT:      case OP_NOT:
6536      case OP_NOTI:      case OP_NOTI:
6537      case OP_REVERSE:      case OP_REVERSE:
6538      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);
6539      break;      break;
6540    
6541      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6298  while (cc < ccend) Line 6550  while (cc < ccend)
6550      case OP_CHAR:      case OP_CHAR:
6551      case OP_CHARI:      case OP_CHARI:
6552      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6553        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);
6554      else      else
6555        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);
6556      break;      break;
6557    
6558      case OP_STAR:      case OP_STAR:
# Line 6368  while (cc < ccend) Line 6620  while (cc < ccend)
6620      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6621      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6622      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6623      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6624      break;      break;
6625    
6626      case OP_CLASS:      case OP_CLASS:
6627      case OP_NCLASS:      case OP_NCLASS:
6628      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)
6629        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6630      else      else
6631        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);
6632      break;      break;
6633    
6634  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6635      case OP_XCLASS:      case OP_XCLASS:
6636      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)
6637        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6638      else      else
6639        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);
6640      break;      break;
6641  #endif  #endif
6642    
6643      case OP_REF:      case OP_REF:
6644      case OP_REFI:      case OP_REFI:
6645      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)
6646        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6647      else      else
6648        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);
6649      break;      break;
6650    
6651      case OP_RECURSE:      case OP_RECURSE:
6652      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6653      break;      break;
6654    
6655      case OP_ASSERT:      case OP_ASSERT:
# Line 6405  while (cc < ccend) Line 6657  while (cc < ccend)
6657      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6658      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6659      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6660      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6661      break;      break;
6662    
6663      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 6422  while (cc < ccend) Line 6674  while (cc < ccend)
6674        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6675        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6676        }        }
6677      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6678      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6679        decrease_call_count(common);        decrease_call_count(common);
6680      break;      break;
# Line 6435  while (cc < ccend) Line 6687  while (cc < ccend)
6687      case OP_SBRA:      case OP_SBRA:
6688      case OP_SCBRA:      case OP_SCBRA:
6689      case OP_SCOND:      case OP_SCOND:
6690      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6691      break;      break;
6692    
6693      case OP_BRAZERO:      case OP_BRAZERO:
6694      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6695        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6696      else      else
6697        {        {
6698        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6699        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6700        }        }
6701      break;      break;
6702    
# Line 6453  while (cc < ccend) Line 6705  while (cc < ccend)
6705      case OP_SBRAPOS:      case OP_SBRAPOS:
6706      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6707      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6708      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6709      break;      break;
6710    
6711      case OP_MARK:      case OP_MARK:
# Line 6477  while (cc < ccend) Line 6729  while (cc < ccend)
6729      case OP_FAIL:      case OP_FAIL:
6730      case OP_ACCEPT:      case OP_ACCEPT:
6731      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6732      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6733      break;      break;
6734    
6735      case OP_CLOSE:      case OP_CLOSE:
6736      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6737      break;      break;
6738    
6739      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 6502  SLJIT_ASSERT(cc == ccend); Line 6754  SLJIT_ASSERT(cc == ccend);
6754  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6755  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6756    
6757  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6758    do \    do \
6759      { \      { \
6760      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6761      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6762        return; \        return; \
6763      } \      } \
# Line 6513  SLJIT_ASSERT(cc == ccend); Line 6765  SLJIT_ASSERT(cc == ccend);
6765    
6766  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6767    
6768  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6769  {  {
6770  DEFINE_COMPILER;  DEFINE_COMPILER;
6771  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6523  int arg1 = -1, arg2 = -1; Line 6775  int arg1 = -1, arg2 = -1;
6775  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6776  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6777  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6778  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6779  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);
6780  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6781  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);
6782    
6783  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6784    
# Line 6538  switch(opcode) Line 6790  switch(opcode)
6790    case OP_CRRANGE:    case OP_CRRANGE:
6791    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6792      {      {
6793      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6794      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6795      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6796      free_stack(common, 1);      free_stack(common, 1);
6797      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);
6798      }      }
6799    else    else
6800      {      {
# Line 6562  switch(opcode) Line 6814  switch(opcode)
6814        }        }
6815      skip_char_back(common);      skip_char_back(common);
6816      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6817      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6818      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6819        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6820      JUMPHERE(jump);      JUMPHERE(jump);
6821      if (localptr == 0)      if (private_data_ptr == 0)
6822        free_stack(common, 2);        free_stack(common, 2);
6823      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6824        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6576  switch(opcode) Line 6828  switch(opcode)
6828    case OP_MINSTAR:    case OP_MINSTAR:
6829    case OP_MINPLUS:    case OP_MINPLUS:
6830    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6831    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6832    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6833    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6834    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6835    if (localptr == 0)    if (private_data_ptr == 0)
6836      free_stack(common, 1);      free_stack(common, 1);
6837    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6838      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6594  switch(opcode) Line 6846  switch(opcode)
6846      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6847      }      }
6848    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6849    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6850    
6851    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6852    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6605  switch(opcode) Line 6857  switch(opcode)
6857      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6858    
6859    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6860      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6861    else    else
6862      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);
6863    
6864    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6865    if (localptr == 0)    if (private_data_ptr == 0)
6866      free_stack(common, 2);      free_stack(common, 2);
6867    break;    break;
6868    
6869    case OP_QUERY:    case OP_QUERY:
6870    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6871    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6872    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);
6873    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6874    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
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    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6878    JUMPHERE(jump);    JUMPHERE(jump);
6879    if (localptr == 0)    if (private_data_ptr == 0)
6880      free_stack(common, 1);      free_stack(common, 1);
6881    break;    break;
6882    
# Line 6632  switch(opcode) Line 6884  switch(opcode)
6884    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6885    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6886    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6887    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6888    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6889    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6890    JUMPHERE(jump);    JUMPHERE(jump);
6891    if (localptr == 0)    if (private_data_ptr == 0)
6892      free_stack(common, 1);      free_stack(common, 1);
6893    break;    break;
6894    
# Line 6656  switch(opcode) Line 6908  switch(opcode)
6908    }    }
6909  }  }
6910    
6911  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)
6912  {  {
6913  DEFINE_COMPILER;  DEFINE_COMPILER;
6914  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6668  if ((type & 0x1) == 0) Line 6920  if ((type & 0x1) == 0)
6920    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6921    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6922    free_stack(common, 1);    free_stack(common, 1);
6923    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);
6924    return;    return;
6925    }    }
6926    
6927  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
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  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6930  free_stack(common, 2);  free_stack(common, 2);
6931  }  }
6932    
6933  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6934  {  {
6935  DEFINE_COMPILER;  DEFINE_COMPILER;
6936    
# Line 6700  else if (common->has_set_som || common-> Line 6952  else if (common->has_set_som || common->
6952    }    }
6953  }  }
6954    
6955  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6956  {  {
6957  DEFINE_COMPILER;  DEFINE_COMPILER;
6958  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6727  if (CURRENT_AS(assert_backtrack)->frames Line 6979  if (CURRENT_AS(assert_backtrack)->frames
6979    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6980      {      {
6981      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6982      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);
6983      free_stack(common, 1);      free_stack(common, 1);
6984      }      }
6985    return;    return;
# Line 6738  if (bra == OP_BRAZERO) Line 6990  if (bra == OP_BRAZERO)
6990    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6991      {      {
6992      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6993      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);
6994      free_stack(common, 1);      free_stack(common, 1);
6995      return;      return;
6996      }      }
# Line 6748  if (bra == OP_BRAZERO) Line 7000  if (bra == OP_BRAZERO)
7000    
7001  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7002    {    {
7003    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);
7004    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7005    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));
7006    
7007    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7008    }    }
# Line 6762  if (bra == OP_BRAZERO) Line 7014  if (bra == OP_BRAZERO)
7014    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
7015    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));
7016    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7017    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
7018    JUMPHERE(brajump);    JUMPHERE(brajump);
7019    }    }
7020  }  }
7021    
7022  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7023  {  {
7024  DEFINE_COMPILER;  DEFINE_COMPILER;
7025  int opcode;  int opcode;
7026  int offset = 0;  int offset = 0;
7027  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7028  int stacksize;  int stacksize;
7029  int count;  int count;
7030  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6827  else if (ket == OP_KETRMIN) Line 7079  else if (ket == OP_KETRMIN)
7079        {        {
7080        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7081        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7082          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);
7083        else        else
7084          {          {
7085          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7086          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);
7087          }          }
7088        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7089          free_stack(common, 1);          free_stack(common, 1);
7090        }        }
7091      else      else
7092        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7093      }      }
7094    rminlabel = LABEL();    rminlabel = LABEL();
7095    }    }
# Line 6852  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7104  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7104    {    {
7105    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7106      {      {
7107      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);
7108      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7109      }      }
7110    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 6905  else if (*cc == OP_ALT) Line 7157  else if (*cc == OP_ALT)
7157    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7158    }    }
7159    
7160  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7161  if (current->topbacktracks)  if (current->topbacktracks)
7162    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7163    
# Line 6918  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7170  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7170      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7171      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))
7172        {        {
7173        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);
7174        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7175        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));
7176        }        }
7177      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7178      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
# Line 6949  if (has_alternatives) Line 7201  if (has_alternatives)
7201        cc += GET(cc, 1);        cc += GET(cc, 1);
7202        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7203          {          {
7204          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7205            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);
7206          else          else
7207            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7208          }          }
7209        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7210        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7211          return;          return;
7212        }        }
7213    
7214      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7215      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7216      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7217        {        {
7218        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7219          {          {
7220          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);
7221          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7222          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7223            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7224          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7225            {            {
7226            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7227            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);
7228            }            }
7229          }          }
7230        else        else
7231          {          {
7232          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));
7233          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7234            {            {
7235            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 7018  if (has_alternatives) Line 7270  if (has_alternatives)
7270    
7271      if (offset != 0)      if (offset != 0)
7272        {        {
7273        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7274        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);
7275        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);
7276        }        }
7277    
7278      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7279    
7280      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7281        {        {
# Line 7032  if (has_alternatives) Line 7284  if (has_alternatives)
7284        jumplist = jumplist->next;        jumplist = jumplist->next;
7285        }        }
7286    
7287      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7288      if (current->topbacktracks)      if (current->topbacktracks)
7289        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7290      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 7047  if (has_alternatives) Line 7299  if (has_alternatives)
7299      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)
7300    
7301        {        {
7302        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);
7303        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7304        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));
7305        }        }
7306      JUMPHERE(cond);      JUMPHERE(cond);
7307      }      }
7308    
7309    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7310    if (localptr == 0)    if (private_data_ptr == 0)
7311      free_stack(common, 1);      free_stack(common, 1);
7312    }    }
7313    
7314  if (offset != 0)  if (offset != 0)
7315    {    {
7316    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7317    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7318    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7319    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7320    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7321    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);
7322    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7323        free_stack(common, 3);
7324        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7325        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7326        }
7327      else
7328        {
7329        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7330        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7331        free_stack(common, 2);
7332        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7333        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7334        }
7335    }    }
7336  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7337    {    {
7338    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));
7339    free_stack(common, 1);    free_stack(common, 1);
7340    }    }
7341  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7090  else if (opcode == OP_ONCE) Line 7354  else if (opcode == OP_ONCE)
7354      }      }
7355    
7356    JUMPHERE(once);    JUMPHERE(once);
7357    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7358    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7359      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));
7360    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7361      {      {
7362      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7363      /* See the comment below. */      /* See the comment below. */
7364      free_stack(common, 2);      free_stack(common, 2);
7365      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7366      }      }
7367    }    }
7368    
# Line 7107  if (ket == OP_KETRMAX) Line 7371  if (ket == OP_KETRMAX)
7371    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7372    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7373      free_stack(common, 1);      free_stack(common, 1);
7374    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);
7375    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7376      {      {
7377      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7378      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7379      JUMPHERE(brazero);      JUMPHERE(brazero);
7380      free_stack(common, 1);      free_stack(common, 1);
7381      }      }
# Line 7134  else if (ket == OP_KETRMIN) Line 7398  else if (ket == OP_KETRMIN)
7398  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7399    {    {
7400    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7401    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7402    JUMPHERE(brazero);    JUMPHERE(brazero);
7403    }    }
7404  }  }
7405    
7406  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7407  {  {
7408  DEFINE_COMPILER;  DEFINE_COMPILER;
7409  int offset;  int offset;
# Line 7160  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7424  if (CURRENT_AS(bracketpos_backtrack)->fr
7424    return;    return;
7425    }    }
7426    
7427  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);
7428  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7429    
7430  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7171  if (current->topbacktracks) Line 7435  if (current->topbacktracks)
7435    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7436    JUMPHERE(jump);    JUMPHERE(jump);
7437    }    }
7438  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));
7439  }  }
7440    
7441  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7442  {  {
7443  assert_backtrack backtrack;  assert_backtrack backtrack;
7444    
# Line 7183  current->topbacktracks = NULL; Line 7447  current->topbacktracks = NULL;
7447  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7448  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7449    {    {
7450    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7451    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7452    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7453    }    }
7454  else  else
7455    {    {
7456    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7457    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7458    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7459    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7460    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7461    }    }
7462  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7463  }  }
7464    
7465  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7466  {  {
7467  DEFINE_COMPILER;  DEFINE_COMPILER;
7468    
# Line 7284  while (current) Line 7548  while (current)
7548  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7549      case OP_XCLASS:      case OP_XCLASS:
7550  #endif  #endif
7551      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7552      break;      break;
7553    
7554      case OP_REF:      case OP_REF:
7555      case OP_REFI:      case OP_REFI:
7556      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7557      break;      break;
7558    
7559      case OP_RECURSE:      case OP_RECURSE:
7560      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7561      break;      break;
7562    
7563      case OP_ASSERT:      case OP_ASSERT:
7564      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7565      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7566      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7567      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7568      break;      break;
7569    
7570      case OP_ONCE:      case OP_ONCE:
# Line 7311  while (current) Line 7575  while (current)
7575      case OP_SBRA:      case OP_SBRA:
7576      case OP_SCBRA:      case OP_SCBRA:
7577      case OP_SCOND:      case OP_SCOND:
7578      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7579      break;      break;
7580    
7581      case OP_BRAZERO:      case OP_BRAZERO:
7582      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7583        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7584      else      else
7585        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7586      break;      break;
7587    
7588      case OP_BRAPOS:      case OP_BRAPOS:
# Line 7326  while (current) Line 7590  while (current)
7590      case OP_SBRAPOS:      case OP_SBRAPOS:
7591      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7592      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7593      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7594      break;      break;
7595    
7596      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7597      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7598      break;      break;
7599    
7600      case OP_MARK:      case OP_MARK:
# Line 7341  while (current) Line 7605  while (current)
7605    
7606      case OP_COMMIT:      case OP_COMMIT:
7607      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7608      if (common->leavelabel == NULL)      if (common->quitlabel == NULL)
7609        add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7610      else      else
7611        JUMPTO(SLJIT_JUMP, common->leavelabel);        JUMPTO(SLJIT_JUMP, common->quitlabel);
7612      break;      break;
7613    
7614      case OP_FAIL:      case OP_FAIL:
# Line 7367  DEFINE_COMPILER; Line 7631  DEFINE_COMPILER;
7631  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7632  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);
7633  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7634  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7635  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7636  int alternativesize;  int alternativesize;
7637  BOOL needsframe;  BOOL needsframe;
7638  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7639  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
7640  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
7641  struct sljit_jump *jump;  struct sljit_jump *jump;
7642    
7643  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
# Line 7387  common->currententry->entry = LABEL(); Line 7651  common->currententry->entry = LABEL();
7651  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7652    
7653  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7654  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7655  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);
7656  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);
7657  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);
7658  if (needsframe)  if (needsframe)
7659    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 7398  if (alternativesize > 0) Line 7662  if (alternativesize > 0)
7662    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7663    
7664  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7665  common->leavelabel = NULL;  common->quitlabel = NULL;
7666  common->acceptlabel = NULL;  common->acceptlabel = NULL;
7667  common->leave = NULL;  common->quit = NULL;
7668  common->accept = NULL;  common->accept = NULL;
7669  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
7670  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 7412  while (1) Line 7676  while (1)
7676    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7677      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7678    
7679    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7680    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7681      {      {
7682      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7683      common->leave = save_leave;      common->quit = save_quit;
7684      return;      return;
7685      }      }
7686    
7687    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7688    
7689    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7690    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7691      {      {
7692      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7693      common->leave = save_leave;      common->quit = save_quit;
7694      return;      return;
7695      }      }
7696    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
# Line 7438  while (1) Line 7702  while (1)
7702    cc += GET(cc, 1);    cc += GET(cc, 1);
7703    }    }
7704  /* None of them matched. */  /* None of them matched. */
7705  if (common->leave != NULL)  if (common->quit != NULL)
7706    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
7707    
7708  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
7709  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
# Line 7455  if (needsframe) Line 7719  if (needsframe)
7719  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
7720    
7721  JUMPHERE(jump);  JUMPHERE(jump);
7722  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);
7723  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7724  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
7725  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7726  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);
7727  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
7728    
7729  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
7730  common->leave = save_leave;  common->quit = save_quit;
7731  }  }
7732    
7733  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKINGPATH
7734  #undef CURRENT_AS  #undef CURRENT_AS
7735    
7736  void  void
# Line 7478  compiler_common common_data; Line 7742  compiler_common common_data;
7742  compiler_common *common = &common_data;  compiler_common *common = &common_data;
7743  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
7744  pcre_study_data *study;  pcre_study_data *study;
7745  int localsize;  int private_data_size;
7746  pcre_uchar *ccend;  pcre_uchar *ccend;
7747  executable_functions *functions;  executable_functions *functions;
7748  void *executable_func;  void *executable_func;
# Line 7538  else Line 7802  else
7802    }    }
7803  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
7804  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
7805    common->digits[0] = -2;
7806  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
7807  common->name_count = re->name_count;  common->name_count = re->name_count;
7808  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
# Line 7553  ccend = bracketend(rootbacktrack.cc); Line 7818  ccend = bracketend(rootbacktrack.cc);
7818    
7819  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7820  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7821    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7822    if (!common->optimized_cbracket)
7823      return;
7824    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7825    
7826  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7827  localsize = get_localspace(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7828  if (localsize < 0)  if (private_data_size < 0)
7829      {
7830      SLJIT_FREE(common->optimized_cbracket);
7831    return;    return;
7832      }
7833    
7834  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7835  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 7587  if ((common->ovector_start & sizeof(slji Line 7859  if ((common->ovector_start & sizeof(slji
7859    
7860  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
7861  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7862  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7863  if (localsize > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7864      {
7865      SLJIT_FREE(common->optimized_cbracket);
7866    return;    return;
7867  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));    }
7868  if (!common->localptrs)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7869    if (!common->private_data_ptrs)
7870      {
7871      SLJIT_FREE(common->optimized_cbracket);
7872    return;    return;
7873  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));    }
7874  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7875    set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7876    
7877  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7878  if (!compiler)  if (!compiler)
7879    {    {
7880    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7881      SLJIT_FREE(common->private_data_ptrs);
7882    return;    return;
7883    }    }
7884  common->compiler = compiler;  common->compiler = compiler;
7885    
7886  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
7887  sljit_emit_enter(compiler, 1, 5, 5, localsize);  sljit_emit_enter(compiler, 1, 5, 5, private_data_size);
7888    
7889  /* Register init. */  /* Register init. */
7890  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
# Line 7633  if ((re->options & PCRE_ANCHORED) == 0) Line 7912  if ((re->options & PCRE_ANCHORED) == 0)
7912    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7913      {      {
7914      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))
7915        /* Do nothing */;        { /* Do nothing */ }
7916      if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7917        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);
7918      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
7919        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
# Line 7661  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7940  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7940  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
7941    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);
7942    
7943  compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7944  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7945    {    {
7946    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7947    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7948      SLJIT_FREE(common->private_data_ptrs);
7949    return;    return;
7950    }    }
7951    
# Line 7678  if (common->accept != NULL) Line 7958  if (common->accept != NULL)
7958    
7959  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7960  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7961  common->leavelabel = LABEL();  common->quitlabel = LABEL();
7962  if (common->leave != NULL)  if (common->quit != NULL)
7963    set_jumps(common->leave, common->leavelabel);    set_jumps(common->quit, common->quitlabel);
7964  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7965    
7966  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7967    {    {
7968    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7969    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7970    return_with_partial_match(common, common->leavelabel);    return_with_partial_match(common, common->quitlabel);
7971    }    }
7972    
7973  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
7974  compile_backtrackpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
7975  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7976    {    {
7977    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7978    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7979      SLJIT_FREE(common->private_data_ptrs);
7980    return;    return;
7981    }    }
7982    
# Line 7751  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 8032  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8032    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
8033    
8034  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8035  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
8036    
8037  flush_stubs(common);  flush_stubs(common);
8038    
# Line 7773  while (common->currententry != NULL) Line 8054  while (common->currententry != NULL)
8054    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8055      {      {
8056      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8057      SLJIT_FREE(common->localptrs);      SLJIT_FREE(common->optimized_cbracket);
8058        SLJIT_FREE(common->private_data_ptrs);
8059      return;      return;
8060      }      }
8061    flush_stubs(common);    flush_stubs(common);
# Line 7804  sljit_emit_fast_return(compiler, SLJIT_M Line 8086  sljit_emit_fast_return(compiler, SLJIT_M
8086  JUMPHERE(jump);  JUMPHERE(jump);
8087  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
8088  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
8089  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
8090    
8091  /* Call limit reached. */  /* Call limit reached. */
8092  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
8093  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
8094  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
8095    
8096  if (common->revertframes != NULL)  if (common->revertframes != NULL)
8097    {    {
# Line 7868  if (common->getucd != NULL) Line 8150  if (common->getucd != NULL)
8150    }    }
8151  #endif  #endif
8152    
8153  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->optimized_cbracket);
8154    SLJIT_FREE(common->private_data_ptrs);
8155  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8156  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
8157  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 7912  union { Line 8195  union {
8195     void* executable_func;     void* executable_func;
8196     jit_function call_executable_func;     jit_function call_executable_func;
8197  } convert_executable_func;  } convert_executable_func;
8198  pcre_uint8 local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_space[MACHINE_STACK_SIZE];
8199  struct sljit_stack local_stack;  struct sljit_stack local_stack;
8200    
8201  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_space;
8202  local_stack.base = local_stack.top;  local_stack.base = local_stack.top;
8203  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
8204  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
8205  arguments->stack = &local_stack;  arguments->stack = &local_stack;
8206  convert_executable_func.executable_func = executable_func;  convert_executable_func.executable_func = executable_func;

Legend:
Removed from v.989  
changed lines
  Added in v.1012

  ViewVC Help
Powered by ViewVC 1.1.5