/[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 970 by zherczeg, Sun May 27 05:28:19 2012 UTC revision 1015 by ph10, Sun Aug 26 16:07:14 2012 UTC
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 89  vertical (sub-expression) (See struct ba Line 92  vertical (sub-expression) (See struct ba
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
95  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
97  branches on the try path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Try path: match happens.     Matching path: match happens.
101     Backtrack path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Try path: no need to perform a match.     Matching path: no need to perform a match.
104     Backtrack path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A try path   A matching path
115   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B try path   B matching path
117   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D try path   D matching path
119   return with successful match   return with successful match
120    
121   D backtrack path   D backtrack path
122   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
123   B backtrack path   B backtrack path
124   C expected path   C expected path
125   jump to D try path   jump to D matching path
126   C backtrack path   C backtrack path
127   A backtrack path   A backtrack path
128    
# Line 127  The generated code will be the following Line 130  The generated code will be the following
130   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
131   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
132   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
133   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 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  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
685        case OP_MINSTAR: \
686        case OP_MINPLUS: \
687        case OP_QUERY: \
688        case OP_MINQUERY: \
689        case OP_MINSTARI: \
690        case OP_MINPLUSI: \
691        case OP_QUERYI: \
692        case OP_MINQUERYI: \
693        case OP_NOTMINSTAR: \
694        case OP_NOTMINPLUS: \
695        case OP_NOTQUERY: \
696        case OP_NOTMINQUERY: \
697        case OP_NOTMINSTARI: \
698        case OP_NOTMINPLUSI: \
699        case OP_NOTQUERYI: \
700        case OP_NOTMINQUERYI:
701    
702    #define CASE_ITERATOR_PRIVATE_DATA_2A \
703        case OP_STAR: \
704        case OP_PLUS: \
705        case OP_STARI: \
706        case OP_PLUSI: \
707        case OP_NOTSTAR: \
708        case OP_NOTPLUS: \
709        case OP_NOTSTARI: \
710        case OP_NOTPLUSI:
711    
712    #define CASE_ITERATOR_PRIVATE_DATA_2B \
713        case OP_UPTO: \
714        case OP_MINUPTO: \
715        case OP_UPTOI: \
716        case OP_MINUPTOI: \
717        case OP_NOTUPTO: \
718        case OP_NOTMINUPTO: \
719        case OP_NOTUPTOI: \
720        case OP_NOTMINUPTOI:
721    
722    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
723        case OP_TYPEMINSTAR: \
724        case OP_TYPEMINPLUS: \
725        case OP_TYPEQUERY: \
726        case OP_TYPEMINQUERY:
727    
728    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
729        case OP_TYPESTAR: \
730        case OP_TYPEPLUS:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
733        case OP_TYPEUPTO: \
734        case OP_TYPEMINUPTO:
735    
736    static int get_class_iterator_size(pcre_uchar *cc)
737  {  {
738  int localspace = 0;  switch(*cc)
739      {
740      case OP_CRSTAR:
741      case OP_CRPLUS:
742      return 2;
743    
744      case OP_CRMINSTAR:
745      case OP_CRMINPLUS:
746      case OP_CRQUERY:
747      case OP_CRMINQUERY:
748      return 1;
749    
750      case OP_CRRANGE:
751      case OP_CRMINRANGE:
752      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
753        return 0;
754      return 2;
755    
756      default:
757      return 0;
758      }
759    }
760    
761    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
762    {
763    int private_data_length = 0;
764  pcre_uchar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766    pcre_uchar *end = NULL;
767    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)
771    {    {
772      space = 0;
773      size = 0;
774      bracketlen = 0;
775    switch(*cc)    switch(*cc)
776      {      {
777      case OP_SET_SOM:      case OP_SET_SOM:
# Line 681  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 690  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);
798      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 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      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805        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      cc += 1 + LINK_SIZE;        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;
846        break;
847    
848        case OP_BRA:
849        bracketlen = 1 + LINK_SIZE;
850        break;
851    
852        case OP_CBRA:
853        case OP_SCBRA:
854        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
855        break;
856    
857        CASE_ITERATOR_PRIVATE_DATA_1
858        space = 1;
859        size = -2;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_2A
863        space = 2;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2B
868        space = 2;
869        size = -(2 + IMM2_SIZE);
870        break;
871    
872        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
873        space = 1;
874        size = 1;
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
878        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
879          space = 2;
880        size = 1;
881        break;
882    
883        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
884        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
885          space = 2;
886        size = 1 + IMM2_SIZE;
887        break;
888    
889        case OP_CLASS:
890        case OP_NCLASS:
891        size += 1 + 32 / sizeof(pcre_uchar);
892        space = get_class_iterator_size(cc + size);
893        break;
894    
895    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
896        case OP_XCLASS:
897        size = GET(cc, 1);
898        space = get_class_iterator_size(cc + size);
899      break;      break;
900    #endif
901    
902      case OP_RECURSE:      case OP_RECURSE:
903      /* Set its value only once. */      /* Set its value only once. */
# Line 734  while (cc < ccend) Line 924  while (cc < ccend)
924        return -1;        return -1;
925      break;      break;
926      }      }
927    
928      if (space > 0 && cc >= end)
929        private_data_length += sizeof(sljit_w) * space;
930    
931      if (size != 0)
932        {
933        if (size < 0)
934          {
935          cc += -size;
936    #ifdef SUPPORT_UTF
937          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
938    #endif
939          }
940        else
941          cc += size;
942        }
943    
944      if (bracketlen > 0)
945        {
946        if (cc >= end)
947          {
948          end = bracketend(cc);
949          if (end[-1 - LINK_SIZE] == OP_KET)
950            end = NULL;
951          }
952        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;
962    pcre_uchar *end = NULL;
963    int space, size, bracketlen;
964    
965  while (cc < ccend)  while (cc < ccend)
966    {    {
967      space = 0;
968      size = 0;
969      bracketlen = 0;
970    switch(*cc)    switch(*cc)
971      {      {
972      case OP_ASSERT:      case OP_ASSERT:
# Line 756  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      cc += 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      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
994      case OP_COND:      case OP_COND:
# Line 773  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      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1003        break;
1004    
1005        case OP_BRA:
1006        bracketlen = 1 + LINK_SIZE;
1007        break;
1008    
1009        case OP_CBRA:
1010        case OP_SCBRA:
1011        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1012        break;
1013    
1014        CASE_ITERATOR_PRIVATE_DATA_1
1015        space = 1;
1016        size = -2;
1017        break;
1018    
1019        CASE_ITERATOR_PRIVATE_DATA_2A
1020        space = 2;
1021        size = -2;
1022        break;
1023    
1024        CASE_ITERATOR_PRIVATE_DATA_2B
1025        space = 2;
1026        size = -(2 + IMM2_SIZE);
1027        break;
1028    
1029        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1030        space = 1;
1031        size = 1;
1032        break;
1033    
1034        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1035        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1036          space = 2;
1037        size = 1;
1038        break;
1039    
1040        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1041        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1042          space = 2;
1043        size = 1 + IMM2_SIZE;
1044        break;
1045    
1046        case OP_CLASS:
1047        case OP_NCLASS:
1048        size += 1 + 32 / sizeof(pcre_uchar);
1049        space = get_class_iterator_size(cc + size);
1050      break;      break;
1051    
1052    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1053        case OP_XCLASS:
1054        size = GET(cc, 1);
1055        space = get_class_iterator_size(cc + size);
1056        break;
1057    #endif
1058    
1059      default:      default:
1060      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1061      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1062      break;      break;
1063      }      }
1064    
1065      if (space > 0 && cc >= end)
1066        {
1067        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1068        private_data_ptr += sizeof(sljit_w) * space;
1069        }
1070    
1071      if (size != 0)
1072        {
1073        if (size < 0)
1074          {
1075          cc += -size;
1076    #ifdef SUPPORT_UTF
1077          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1078    #endif
1079          }
1080        else
1081          cc += size;
1082        }
1083    
1084      if (bracketlen > 0)
1085        {
1086        if (cc >= end)
1087          {
1088          end = bracketend(cc);
1089          if (end[-1 - LINK_SIZE] == OP_KET)
1090            end = NULL;
1091          }
1092        cc += bracketlen;
1093        }
1094    }    }
1095  }  }
1096    
# Line 960  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;
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;
1279    switch(*cc)    switch(*cc)
1280      {      {
1281      case OP_ASSERT:      case OP_ASSERT:
# Line 979  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 999  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_PRIVATE_DATA_1
1317        if (PRIVATE_DATA(cc))
1318          private_data_length++;
1319        cc += 2;
1320    #ifdef SUPPORT_UTF
1321        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1322    #endif
1323        break;
1324    
1325        CASE_ITERATOR_PRIVATE_DATA_2A
1326        if (PRIVATE_DATA(cc))
1327          private_data_length += 2;
1328        cc += 2;
1329    #ifdef SUPPORT_UTF
1330        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1331    #endif
1332        break;
1333    
1334        CASE_ITERATOR_PRIVATE_DATA_2B
1335        if (PRIVATE_DATA(cc))
1336          private_data_length += 2;
1337        cc += 2 + IMM2_SIZE;
1338    #ifdef SUPPORT_UTF
1339        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1340    #endif
1341        break;
1342    
1343        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1344        if (PRIVATE_DATA(cc))
1345          private_data_length++;
1346        cc += 1;
1347        break;
1348    
1349        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1350        if (PRIVATE_DATA(cc))
1351          private_data_length += 2;
1352        cc += 1;
1353        break;
1354    
1355        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1356        if (PRIVATE_DATA(cc))
1357          private_data_length += 2;
1358        cc += 1 + IMM2_SIZE;
1359        break;
1360    
1361        case OP_CLASS:
1362        case OP_NCLASS:
1363    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1364        case OP_XCLASS:
1365        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1366    #else
1367        size = 1 + 32 / (int)sizeof(pcre_uchar);
1368    #endif
1369        if (PRIVATE_DATA(cc))
1370          private_data_length += get_class_iterator_size(cc + size);
1371        cc += size;
1372        break;
1373    
1374      default:      default:
1375      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1376      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1010  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;
1388  int srcw[2];  int srcw[2];
1389  int count;  int count, size;
1390  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1391  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1392  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1083  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] = PRIVATE_DATA(cc);
1473        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1474        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1475        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1476        break;        break;
1477    
# Line 1110  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_PRIVATE_DATA_1
1491          if (PRIVATE_DATA(cc))
1492            {
1493            count = 1;
1494            srcw[0] = PRIVATE_DATA(cc);
1495            }
1496          cc += 2;
1497    #ifdef SUPPORT_UTF
1498          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1499    #endif
1500          break;
1501    
1502          CASE_ITERATOR_PRIVATE_DATA_2A
1503          if (PRIVATE_DATA(cc))
1504            {
1505            count = 2;
1506            srcw[0] = PRIVATE_DATA(cc);
1507            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1508            }
1509          cc += 2;
1510    #ifdef SUPPORT_UTF
1511          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1512    #endif
1513          break;
1514    
1515          CASE_ITERATOR_PRIVATE_DATA_2B
1516          if (PRIVATE_DATA(cc))
1517            {
1518            count = 2;
1519            srcw[0] = PRIVATE_DATA(cc);
1520            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1521            }
1522          cc += 2 + IMM2_SIZE;
1523    #ifdef SUPPORT_UTF
1524          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1525    #endif
1526          break;
1527    
1528          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1529          if (PRIVATE_DATA(cc))
1530            {
1531            count = 1;
1532            srcw[0] = PRIVATE_DATA(cc);
1533            }
1534          cc += 1;
1535          break;
1536    
1537          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1538          if (PRIVATE_DATA(cc))
1539            {
1540            count = 2;
1541            srcw[0] = PRIVATE_DATA(cc);
1542            srcw[1] = srcw[0] + sizeof(sljit_w);
1543            }
1544          cc += 1;
1545          break;
1546    
1547          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1548          if (PRIVATE_DATA(cc))
1549            {
1550            count = 2;
1551            srcw[0] = PRIVATE_DATA(cc);
1552            srcw[1] = srcw[0] + sizeof(sljit_w);
1553            }
1554          cc += 1 + IMM2_SIZE;
1555          break;
1556    
1557          case OP_CLASS:
1558          case OP_NCLASS:
1559    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1560          case OP_XCLASS:
1561          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1562    #else
1563          size = 1 + 32 / (int)sizeof(pcre_uchar);
1564    #endif
1565          if (PRIVATE_DATA(cc))
1566            switch(get_class_iterator_size(cc + size))
1567              {
1568              case 1:
1569              count = 1;
1570              srcw[0] = PRIVATE_DATA(cc);
1571              break;
1572    
1573              case 2:
1574              count = 2;
1575              srcw[0] = PRIVATE_DATA(cc);
1576              srcw[1] = srcw[0] + sizeof(sljit_w);
1577              break;
1578    
1579              default:
1580              SLJIT_ASSERT_STOP();
1581              break;
1582              }
1583          cc += size;
1584          break;
1585    
1586        default:        default:
1587        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1588        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1218  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_PRIVATE_DATA_1
1689    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1690    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1691    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1692    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1693    #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  {  {
1697  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1228  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 1255  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 1275  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 1385  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 1395  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 1413  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 1994  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 2006  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 2017  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 2086  if (newlinecheck) Line 2560  if (newlinecheck)
2560    JUMPHERE(nl);    JUMPHERE(nl);
2561    }    }
2562    
2563  return mainloop;  return mainloop;
2564    }
2565    
2566    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2567    {
2568    DEFINE_COMPILER;
2569    struct sljit_label *start;
2570    struct sljit_jump *quit;
2571    struct sljit_jump *found;
2572    pcre_int32 chars[4];
2573    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2574    int location = 0;
2575    pcre_int32 len, c, bit, caseless;
2576    BOOL must_end;
2577    
2578    #ifdef COMPILE_PCRE8
2579    union {
2580        sljit_uh ascombined;
2581        sljit_ub asuchars[2];
2582    } pair;
2583    #else
2584    union {
2585        sljit_ui ascombined;
2586        sljit_uh asuchars[2];
2587    } pair;
2588    #endif
2589    
2590    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2591      return FALSE;
2592    
2593    while (TRUE)
2594      {
2595      caseless = 0;
2596      must_end = TRUE;
2597      switch(*cc)
2598        {
2599        case OP_CHAR:
2600        must_end = FALSE;
2601        cc++;
2602        break;
2603    
2604        case OP_CHARI:
2605        caseless = 1;
2606        must_end = FALSE;
2607        cc++;
2608        break;
2609    
2610        case OP_SOD:
2611        case OP_SOM:
2612        case OP_SET_SOM:
2613        case OP_NOT_WORD_BOUNDARY:
2614        case OP_WORD_BOUNDARY:
2615        case OP_EODN:
2616        case OP_EOD:
2617        case OP_CIRC:
2618        case OP_CIRCM:
2619        case OP_DOLL:
2620        case OP_DOLLM:
2621        /* Zero width assertions. */
2622        cc++;
2623        continue;
2624    
2625        case OP_PLUS:
2626        case OP_MINPLUS:
2627        case OP_POSPLUS:
2628        cc++;
2629        break;
2630    
2631        case OP_EXACT:
2632        cc += 1 + IMM2_SIZE;
2633        break;
2634    
2635        case OP_PLUSI:
2636        case OP_MINPLUSI:
2637        case OP_POSPLUSI:
2638        caseless = 1;
2639        cc++;
2640        break;
2641    
2642        case OP_EXACTI:
2643        caseless = 1;
2644        cc += 1 + IMM2_SIZE;
2645        break;
2646    
2647        default:
2648        return FALSE;
2649        }
2650    
2651      len = 1;
2652    #ifdef SUPPORT_UTF
2653      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2654    #endif
2655    
2656      if (caseless && char_has_othercase(common, cc))
2657        {
2658        caseless = char_get_othercase_bit(common, cc);
2659        if (caseless == 0)
2660          return FALSE;
2661    #ifdef COMPILE_PCRE8
2662        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2663    #else
2664        if ((caseless & 0x100) != 0)
2665          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2666        else
2667          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2668    #endif
2669        }
2670      else
2671        caseless = 0;
2672    
2673      while (len > 0 && location < 2 * 2)
2674        {
2675        c = *cc;
2676        bit = 0;
2677        if (len == (caseless & 0xff))
2678          {
2679          bit = caseless >> 8;
2680          c |= bit;
2681          }
2682    
2683        chars[location] = c;
2684        chars[location + 1] = bit;
2685    
2686        len--;
2687        location += 2;
2688        cc++;
2689        }
2690    
2691      if (location == 2 * 2)
2692        break;
2693      else if (must_end)
2694        return FALSE;
2695      }
2696    
2697    if (firstline)
2698      {
2699      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);
2702      }
2703    else
2704      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    
2706    start = LABEL();
2707    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2708    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2709    #ifdef COMPILE_PCRE8
2710    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2711    #else /* COMPILE_PCRE8 */
2712    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2713    #endif
2714    
2715    #else /* SLJIT_UNALIGNED */
2716    
2717    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2718    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2719    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2720    #else /* SLJIT_BIG_ENDIAN */
2721    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2722    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2723    #endif /* SLJIT_BIG_ENDIAN */
2724    
2725    #ifdef COMPILE_PCRE8
2726    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2727    #else /* COMPILE_PCRE8 */
2728    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2729    #endif
2730    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2731    
2732    #endif
2733    
2734    if (chars[1] != 0 || chars[3] != 0)
2735      {
2736      pair.asuchars[0] = chars[1];
2737      pair.asuchars[1] = chars[3];
2738      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2739      }
2740    
2741    pair.asuchars[0] = chars[0];
2742    pair.asuchars[1] = chars[2];
2743    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2744    
2745    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2746    JUMPTO(SLJIT_JUMP, start);
2747    JUMPHERE(found);
2748    JUMPHERE(quit);
2749    
2750    if (firstline)
2751      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2752    else
2753      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2754    return TRUE;
2755  }  }
2756    
2757  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
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 2137  else Line 2803  else
2803    }    }
2804    
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));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
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 2170  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 2199  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 2229  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 2240  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 2261  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 2310  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 2537  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 2912  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 2930  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 2944  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 3249  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 3285  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 3370  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 3416  switch(type) Line 4219  switch(type)
4219    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4220    read_char(common);    read_char(common);
4221    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4222    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4223    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4224      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4225      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4226    
4227    label = LABEL();    label = LABEL();
4228    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4229    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4230    read_char(common);    read_char(common);
4231    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4232    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4233    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4234    
4235      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4236      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4237      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4238      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4239      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4240      JUMPTO(SLJIT_C_NOT_ZERO, label);
4241    
4242    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4243    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4244      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4245    
4246    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4247      {      {
4248      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 3554  switch(type) Line 4368  switch(type)
4368    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4369    
4370    if (!common->endonly)    if (!common->endonly)
4371      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4372    else    else
4373      {      {
4374      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
# Line 3642  switch(type) Line 4456  switch(type)
4456      }      }
4457    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4458    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4459    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4460    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4461    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4462    return cc + length;    return cc + length;
# Line 3712  switch(type) Line 4526  switch(type)
4526    case OP_NCLASS:    case OP_NCLASS:
4527    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4528    read_char(common);    read_char(common);
4529      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4530        return cc + 32 / sizeof(pcre_uchar);
4531    
4532  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4533    jump[0] = NULL;    jump[0] = NULL;
4534  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3742  switch(type) Line 4559  switch(type)
4559    
4560  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4561    case OP_XCLASS:    case OP_XCLASS:
4562    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4563    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4564  #endif  #endif
4565    
# Line 3776  SLJIT_ASSERT_STOP(); Line 4593  SLJIT_ASSERT_STOP();
4593  return cc;  return cc;
4594  }  }
4595    
4596  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4597  {  {
4598  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4599  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3839  if (context.length > 0) Line 4656  if (context.length > 0)
4656    }    }
4657    
4658  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4659  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4660  }  }
4661    
4662  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 3865  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4682  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4682  }  }
4683    
4684  /* Forward definitions. */  /* Forward definitions. */
4685  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4686  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4687    
4688  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4689    do \    do \
# Line 3896  static void compile_backtrackpath(compil Line 4713  static void compile_backtrackpath(compil
4713    
4714  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4715    
4716  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4717  {  {
4718  DEFINE_COMPILER;  DEFINE_COMPILER;
4719  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3978  if (jump != NULL) Line 4795  if (jump != NULL)
4795  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4796  }  }
4797    
4798  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4799  {  {
4800  DEFINE_COMPILER;  DEFINE_COMPILER;
4801  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4049  if (!minimize) Line 4866  if (!minimize)
4866      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4867    
4868    label = LABEL();    label = LABEL();
4869    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4870    
4871    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4872      {      {
# Line 4077  if (!minimize) Line 4894  if (!minimize)
4894      }      }
4895    
4896    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4897    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4898    
4899    decrease_call_count(common);    decrease_call_count(common);
4900    return cc;    return cc;
# Line 4097  if (min == 0) Line 4914  if (min == 0)
4914  else  else
4915    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4916    
4917  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4918  if (max > 0)  if (max > 0)
4919    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4920    
4921  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4922  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4923    
4924  if (min > 1)  if (min > 1)
# Line 4109  if (min > 1) Line 4926  if (min > 1)
4926    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4927    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4928    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4929    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4930    }    }
4931  else if (max > 0)  else if (max > 0)
4932    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4122  decrease_call_count(common); Line 4939  decrease_call_count(common);
4939  return cc;  return cc;
4940  }  }
4941    
4942  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4943  {  {
4944  DEFINE_COMPILER;  DEFINE_COMPILER;
4945  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4179  add_jump(compiler, &backtrack->topbacktr Line 4996  add_jump(compiler, &backtrack->topbacktr
4996  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4997  }  }
4998    
4999  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5000  {  {
5001  DEFINE_COMPILER;  DEFINE_COMPILER;
5002  int framesize;  int framesize;
5003  int localptr;  int private_data_ptr;
5004  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5005  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5006  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4192  jump_list *tmp = NULL; Line 5009  jump_list *tmp = NULL;
5009  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5010  jump_list **found;  jump_list **found;
5011  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5012  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5013  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5014  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5015  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5016  struct sljit_jump *jump;  struct sljit_jump *jump;
5017  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5022  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5022    bra = *cc;    bra = *cc;
5023    cc++;    cc++;
5024    }    }
5025  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5026  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5027  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5028  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5029  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5030  opcode = *cc;  opcode = *cc;
5031  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5032  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4226  if (bra == OP_BRAMINZERO) Line 5043  if (bra == OP_BRAMINZERO)
5043    
5044  if (framesize < 0)  if (framesize < 0)
5045    {    {
5046    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5047    allocate_stack(common, 1);    allocate_stack(common, 1);
5048    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5049    }    }
5050  else  else
5051    {    {
5052    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5053    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5054    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
5055    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5056    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5057    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5058    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5059    }    }
5060    
5061  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5062  common->leavelabel = NULL;  common->quitlabel = NULL;
5063  common->leave = NULL;  common->quit = NULL;
5064  while (1)  while (1)
5065    {    {
5066    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4255  while (1) Line 5072  while (1)
5072      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5073    
5074    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5075    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5076    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5077      {      {
5078      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5079      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5080      common->leave = save_leave;      common->quit = save_quit;
5081      common->accept = save_accept;      common->accept = save_accept;
5082      return NULL;      return NULL;
5083      }      }
# Line 4270  while (1) Line 5087  while (1)
5087    
5088    /* Reset stack. */    /* Reset stack. */
5089    if (framesize < 0)    if (framesize < 0)
5090      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5091    else {    else {
5092      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5093        {        {
5094        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5095        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5096        }        }
5097      else      else
5098        {        {
5099        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5100        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5101        }        }
5102    }    }
# Line 4297  while (1) Line 5114  while (1)
5114          {          {
5115          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5116          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
5117          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5118          }          }
5119        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5120        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 4305  while (1) Line 5122  while (1)
5122      else if (framesize >= 0)      else if (framesize >= 0)
5123        {        {
5124        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5125        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5126        }        }
5127      }      }
5128    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5129    
5130    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5131    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5132      {      {
5133      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5134      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5135      common->leave = save_leave;      common->quit = save_quit;
5136      common->accept = save_accept;      common->accept = save_accept;
5137      return NULL;      return NULL;
5138      }      }
# Line 4328  while (1) Line 5145  while (1)
5145    cc += GET(cc, 1);    cc += GET(cc, 1);
5146    }    }
5147  /* None of them matched. */  /* None of them matched. */
5148  if (common->leave != NULL)  if (common->quit != NULL)
5149    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5150    
5151  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5152    {    {
# Line 4356  if (opcode == OP_ASSERT || opcode == OP_ Line 5173  if (opcode == OP_ASSERT || opcode == OP_
5173        }        }
5174      else      else
5175        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5176      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5177      }      }
5178    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5179    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4381  if (opcode == OP_ASSERT || opcode == OP_ Line 5198  if (opcode == OP_ASSERT || opcode == OP_
5198      {      {
5199      if (bra == OP_BRA)      if (bra == OP_BRA)
5200        {        {
5201        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5202        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5203        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5204        }        }
5205      else      else
5206        {        {
5207        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5208        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5209        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5210        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5211        }        }
# Line 4396  if (opcode == OP_ASSERT || opcode == OP_ Line 5213  if (opcode == OP_ASSERT || opcode == OP_
5213    
5214    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5215      {      {
5216      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5217      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5218      }      }
5219    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5220      {      {
5221      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5222      JUMPHERE(brajump);      JUMPHERE(brajump);
5223      if (framesize >= 0)      if (framesize >= 0)
5224        {        {
5225        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5226        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5227        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5228        }        }
5229      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5230      }      }
# Line 4435  else Line 5252  else
5252        }        }
5253      else      else
5254        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5255      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5256      }      }
5257    
5258    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5259      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5260    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5261      {      {
5262      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5263      JUMPHERE(brajump);      JUMPHERE(brajump);
5264      }      }
5265    
# Line 4454  else Line 5271  else
5271      }      }
5272    }    }
5273    
5274  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5275  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5276  common->leave = save_leave;  common->quit = save_quit;
5277  common->accept = save_accept;  common->accept = save_accept;
5278  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5279  }  }
# Line 4625  return condition; Line 5442  return condition;
5442                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5443  */  */
5444    
5445  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5446  {  {
5447  DEFINE_COMPILER;  DEFINE_COMPILER;
5448  backtrack_common *backtrack;  backtrack_common *backtrack;
5449  pcre_uchar opcode;  pcre_uchar opcode;
5450  int localptr = 0;  int private_data_ptr = 0;
5451  int offset = 0;  int offset = 0;
5452  int stacksize;  int stacksize;
5453  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5454  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5455  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5456  pcre_uchar ket;  pcre_uchar ket;
5457  assert_backtrack *assert;  assert_backtrack *assert;
# Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5472  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5472    
5473  opcode = *cc;  opcode = *cc;
5474  ccbegin = cc;  ccbegin = cc;
5475  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5476    
5477  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5478    {    {
# Line 4672  cc += GET(cc, 1); Line 5489  cc += GET(cc, 1);
5489  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5490  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5491    {    {
5492    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5493    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5494      {      {
5495      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5496      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5497        has_alternatives = FALSE;        has_alternatives = FALSE;
5498      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4694  if (opcode == OP_CBRA || opcode == OP_SC Line 5511  if (opcode == OP_CBRA || opcode == OP_SC
5511    {    {
5512    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5513    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5514    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5515    offset <<= 1;      {
5516    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5517    trypath += IMM2_SIZE;      offset <<= 1;
5518        }
5519      else
5520        {
5521        offset <<= 1;
5522        private_data_ptr = OVECTOR(offset);
5523        }
5524      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5525      matchingpath += IMM2_SIZE;
5526    }    }
5527  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5528    {    {
5529    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5530    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5531    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5532    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5533    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5534      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5535    }    }
# Line 4750  if (bra == OP_BRAMINZERO) Line 5575  if (bra == OP_BRAMINZERO)
5575        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5576        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5577          {          {
5578          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5579          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5580          }          }
5581        else        else
5582          {          {
5583          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5584          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5585          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5586          }          }
5587        JUMPHERE(skip);        JUMPHERE(skip);
# Line 4771  if (bra == OP_BRAMINZERO) Line 5596  if (bra == OP_BRAMINZERO)
5596    }    }
5597    
5598  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5599    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5600    
5601  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5602    {    {
5603    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5604    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5605      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5606    }    }
5607    
5608  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 4788  if (opcode == OP_ONCE) Line 5613  if (opcode == OP_ONCE)
5613      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5614      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5615        {        {
5616        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5617        allocate_stack(common, 2);        allocate_stack(common, 2);
5618        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5619        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5620        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5621        }        }
5622      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5623        {        {
5624        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5625        allocate_stack(common, 1);        allocate_stack(common, 1);
5626        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5627        }        }
5628      else      else
5629        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5630      }      }
5631    else    else
5632      {      {
5633      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5634        {        {
5635        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5636        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5637        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5638        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5640        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5641        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5642        }        }
5643      else      else
5644        {        {
5645        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5646        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5647        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5648        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5649        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5650        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5651        }        }
# Line 4829  if (opcode == OP_ONCE) Line 5654  if (opcode == OP_ONCE)
5654  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5655    {    {
5656    /* Saving the previous values. */    /* Saving the previous values. */
5657    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5658    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5659    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5660    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5661    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5662    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5663    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5664    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5665        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5666        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5667        }
5668      else
5669        {
5670        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5671        allocate_stack(common, 2);
5672        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5673        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5674        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5675        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5676        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5677        }
5678    }    }
5679  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5680    {    {
5681    /* Saving the previous value. */    /* Saving the previous value. */
5682    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5683    allocate_stack(common, 1);    allocate_stack(common, 1);
5684    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5685    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5686    }    }
5687  else if (has_alternatives)  else if (has_alternatives)
# Line 4856  else if (has_alternatives) Line 5694  else if (has_alternatives)
5694  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5695  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5696    {    {
5697    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5698      {      {
5699      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5700      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5701        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5702      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5703      }      }
5704    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5705      {      {
5706      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5707      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5708      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5709    
5710      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 4880  if (opcode == OP_COND || opcode == OP_SC Line 5718  if (opcode == OP_COND || opcode == OP_SC
5718      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5719    
5720      JUMPHERE(jump);      JUMPHERE(jump);
5721      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5722      }      }
5723    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5724      {      {
5725      /* Never has other case. */      /* Never has other case. */
5726      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5727    
5728      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5729      if (common->currententry == NULL)      if (common->currententry == NULL)
5730        stacksize = 0;        stacksize = 0;
5731      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4897  if (opcode == OP_COND || opcode == OP_SC Line 5735  if (opcode == OP_COND || opcode == OP_SC
5735      else      else
5736        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5737    
5738      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5739        {        {
5740        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5741        if (stacksize != 0)        if (stacksize != 0)
5742          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5743        else        else
5744          {          {
5745          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5746            {            {
5747            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5748            cc += GET(cc, 1);            cc += GET(cc, 1);
5749            }            }
5750          else          else
5751            trypath = cc;            matchingpath = cc;
5752          }          }
5753        }        }
5754      else      else
5755        {        {
5756        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5757    
5758        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5759        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5760        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5761        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 4928  if (opcode == OP_COND || opcode == OP_SC Line 5766  if (opcode == OP_COND || opcode == OP_SC
5766        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5767        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5768        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5769        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5770        }        }
5771      }      }
5772    else    else
5773      {      {
5774      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5775      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5776      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5777      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5778        return NULL;        return NULL;
5779      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5780      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5781      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5782      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5783      }      }
5784    }    }
5785    
5786  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5787  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5788    return NULL;    return NULL;
5789    
# Line 4953  if (opcode == OP_ONCE) Line 5791  if (opcode == OP_ONCE)
5791    {    {
5792    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5793      {      {
5794      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5795      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5796      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5797        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5798      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5799        {        {
5800        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5801        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5802        }        }
5803      }      }
5804    else    else
5805      {      {
5806      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5807      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5808      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5809        {        {
5810        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5001  if (has_alternatives) Line 5839  if (has_alternatives)
5839    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5840      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5841    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5842      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5843    }    }
5844    
5845  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5846  if (offset != 0)  if (offset != 0)
5847    {    {
5848    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5849    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5850    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5851    }    }
# Line 5017  if (ket == OP_KETRMAX) Line 5855  if (ket == OP_KETRMAX)
5855    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5856      {      {
5857      if (has_alternatives)      if (has_alternatives)
5858        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5859      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5860      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5861        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        {
5862          CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5863          /* Drop STR_PTR for greedy plus quantifier. */
5864          if (bra != OP_BRAZERO)
5865            free_stack(common, 1);
5866          }
5867      else      else
5868        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5869        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5870      }      }
5871    else    else
5872      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5873    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5874    }    }
5875    
5876  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5877    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5878    
5879  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5880    {    {
5881    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5882    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5883    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5884      {      {
5885      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5045  if (bra == OP_BRAMINZERO) Line 5888  if (bra == OP_BRAMINZERO)
5888      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5889      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5890        {        {
5891        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5892        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5893        }        }
5894      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5064  cc += 1 + LINK_SIZE; Line 5907  cc += 1 + LINK_SIZE;
5907  return cc;  return cc;
5908  }  }
5909    
5910  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5911  {  {
5912  DEFINE_COMPILER;  DEFINE_COMPILER;
5913  backtrack_common *backtrack;  backtrack_common *backtrack;
5914  pcre_uchar opcode;  pcre_uchar opcode;
5915  int localptr;  int private_data_ptr;
5916  int cbraprivptr = 0;  int cbraprivptr = 0;
5917  int framesize;  int framesize;
5918  int stacksize;  int stacksize;
# Line 5088  if (*cc == OP_BRAPOSZERO) Line 5931  if (*cc == OP_BRAPOSZERO)
5931    }    }
5932    
5933  opcode = *cc;  opcode = *cc;
5934  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5935  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5936  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5937  switch(opcode)  switch(opcode)
5938    {    {
5939    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5101  switch(opcode) Line 5944  switch(opcode)
5944    case OP_CBRAPOS:    case OP_CBRAPOS:
5945    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5946    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5947      /* This case cannot be optimized in the same was as
5948      normal capturing brackets. */
5949      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5950    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5951    offset <<= 1;    offset <<= 1;
5952    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5120  if (framesize < 0) Line 5966  if (framesize < 0)
5966      stacksize++;      stacksize++;
5967    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5968    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5969    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5970    
5971    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5972      {      {
# Line 5145  else Line 5991  else
5991    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5992    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5993    
5994    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5995    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
5996    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5997    stack = 0;    stack = 0;
5998    if (!zero)    if (!zero)
5999      {      {
# Line 5173  while (*cc != OP_KETRPOS) Line 6019  while (*cc != OP_KETRPOS)
6019    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6020    cc += GET(cc, 1);    cc += GET(cc, 1);
6021    
6022    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6023    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6024      return NULL;      return NULL;
6025    
6026    if (framesize < 0)    if (framesize < 0)
6027      {      {
6028      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6029    
6030      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6031        {        {
# Line 5205  while (*cc != OP_KETRPOS) Line 6051  while (*cc != OP_KETRPOS)
6051      {      {
6052      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6053        {        {
6054        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
6055        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6056        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6057        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5213  while (*cc != OP_KETRPOS) Line 6059  while (*cc != OP_KETRPOS)
6059        }        }
6060      else      else
6061        {        {
6062        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6063        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
6064        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6065          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
# Line 5234  while (*cc != OP_KETRPOS) Line 6080  while (*cc != OP_KETRPOS)
6080    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6081    flush_stubs(common);    flush_stubs(common);
6082    
6083    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6084    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6085      return NULL;      return NULL;
6086    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 5252  while (*cc != OP_KETRPOS) Line 6098  while (*cc != OP_KETRPOS)
6098        {        {
6099        /* Last alternative. */        /* Last alternative. */
6100        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6101          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6102        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6103        }        }
6104      else      else
6105        {        {
6106        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6107        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6108        }        }
6109      }      }
# Line 5272  if (!zero) Line 6118  if (!zero)
6118    {    {
6119    if (framesize < 0)    if (framesize < 0)
6120      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
6121    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6122      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
6123    }    }
6124    
# Line 5374  if (end != NULL) Line 6220  if (end != NULL)
6220  return cc;  return cc;
6221  }  }
6222    
6223  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6224  {  {
6225  DEFINE_COMPILER;  DEFINE_COMPILER;
6226  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5385  pcre_uchar* end; Line 6231  pcre_uchar* end;
6231  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6232  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6233  struct sljit_label *label;  struct sljit_label *label;
6234    int private_data_ptr = PRIVATE_DATA(cc);
6235    int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6236    int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6237    int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6238    int tmp_base, tmp_offset;
6239    
6240  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6241    
6242  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6243    
6244    switch (type)
6245      {
6246      case OP_NOT_DIGIT:
6247      case OP_DIGIT:
6248      case OP_NOT_WHITESPACE:
6249      case OP_WHITESPACE:
6250      case OP_NOT_WORDCHAR:
6251      case OP_WORDCHAR:
6252      case OP_ANY:
6253      case OP_ALLANY:
6254      case OP_ANYBYTE:
6255      case OP_ANYNL:
6256      case OP_NOT_HSPACE:
6257      case OP_HSPACE:
6258      case OP_NOT_VSPACE:
6259      case OP_VSPACE:
6260      case OP_CHAR:
6261      case OP_CHARI:
6262      case OP_NOT:
6263      case OP_NOTI:
6264      case OP_CLASS:
6265      case OP_NCLASS:
6266      tmp_base = TMP3;
6267      tmp_offset = 0;
6268      break;
6269    
6270      default:
6271      SLJIT_ASSERT_STOP();
6272      /* Fall through. */
6273    
6274      case OP_EXTUNI:
6275      case OP_XCLASS:
6276      case OP_NOTPROP:
6277      case OP_PROP:
6278      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6279      tmp_offset = POSSESSIVE0;
6280      break;
6281      }
6282    
6283  switch(opcode)  switch(opcode)
6284    {    {
6285    case OP_STAR:    case OP_STAR:
# Line 5398  switch(opcode) Line 6288  switch(opcode)
6288    case OP_CRRANGE:    case OP_CRRANGE:
6289    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6290      {      {
6291        SLJIT_ASSERT(private_data_ptr == 0);
6292      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6293        {        {
6294        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5409  switch(opcode) Line 6300  switch(opcode)
6300        allocate_stack(common, 1);        allocate_stack(common, 1);
6301        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6302        }        }
6303    
6304      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6305        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6306    
6307      label = LABEL();      label = LABEL();
6308      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6309      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6310        {        {
6311        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5425  switch(opcode) Line 6317  switch(opcode)
6317        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6318        }        }
6319    
6320        /* We cannot use TMP3 because of this allocate_stack. */
6321      allocate_stack(common, 1);      allocate_stack(common, 1);
6322      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6323      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5433  switch(opcode) Line 6326  switch(opcode)
6326      }      }
6327    else    else
6328      {      {
6329      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6330      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6331      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (private_data_ptr == 0)
6332          allocate_stack(common, 2);
6333        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6334        if (opcode <= OP_PLUS)
6335          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6336        else
6337          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6338      label = LABEL();      label = LABEL();
6339      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6340      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6341      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6342          JUMPTO(SLJIT_JUMP, label);
6343        else if (opcode == OP_CRRANGE && arg1 == 0)
6344        {        {
6345        OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6346        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6347        }        }
6348      else      else
6349        {        {
6350        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6351        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6352        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6353        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6354        }        }
6355      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6356      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6357        add_jump(compiler, &backtrack->topbacktracks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6358          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6359      }      }
6360    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6361    break;    break;
6362    
6363    case OP_MINSTAR:    case OP_MINSTAR:
6364    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6365    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6366      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6367    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    if (private_data_ptr == 0)
6368        allocate_stack(common, 1);
6369      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6370      BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6371    break;    break;
6372    
6373    case OP_MINUPTO:    case OP_MINUPTO:
6374    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6375    allocate_stack(common, 2);    if (private_data_ptr == 0)
6376    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6377    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6378      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6379    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6380      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6381    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6382    break;    break;
6383    
6384    case OP_QUERY:    case OP_QUERY:
6385    case OP_MINQUERY:    case OP_MINQUERY:
6386    allocate_stack(common, 1);    if (private_data_ptr == 0)
6387    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6388      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6389    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6390      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6391    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6392    break;    break;
6393    
6394    case OP_EXACT:    case OP_EXACT:
6395    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6396    label = LABEL();    label = LABEL();
6397    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6398    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6399    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6400    break;    break;
6401    
6402    case OP_POSSTAR:    case OP_POSSTAR:
6403    case OP_POSPLUS:    case OP_POSPLUS:
6404    case OP_POSUPTO:    case OP_POSUPTO:
6405    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6406      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6407    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6408        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6409      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6410    label = LABEL();    label = LABEL();
6411    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6412    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6413    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6414      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6415    else    else
6416      {      {
6417      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6418      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6419      }      }
6420    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6421    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6422    break;    break;
6423    
6424    case OP_POSQUERY:    case OP_POSQUERY:
6425    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6426    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6427    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6428    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6429    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6430    break;    break;
6431    
6432    default:    default:
# Line 5543  decrease_call_count(common); Line 6438  decrease_call_count(common);
6438  return end;  return end;
6439  }  }
6440    
6441  static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6442  {  {
6443  DEFINE_COMPILER;  DEFINE_COMPILER;
6444  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5587  add_jump(compiler, &backtrack->topbacktr Line 6482  add_jump(compiler, &backtrack->topbacktr
6482  return cc + 1;  return cc + 1;
6483  }  }
6484    
6485  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
6486  {  {
6487  DEFINE_COMPILER;  DEFINE_COMPILER;
6488  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6489    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6490    
6491  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6492  if (common->currententry != NULL)  if (common->currententry != NULL)
6493    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6494    
6495  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6496      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6497  offset <<= 1;  offset <<= 1;
6498  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6499  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6500      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6501  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6502  }  }
6503    
6504  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6505  {  {
6506  DEFINE_COMPILER;  DEFINE_COMPILER;
6507  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5642  while (cc < ccend) Line 6540  while (cc < ccend)
6540      case OP_NOT:      case OP_NOT:
6541      case OP_NOTI:      case OP_NOTI:
6542      case OP_REVERSE:      case OP_REVERSE:
6543      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6544      break;      break;
6545    
6546      case OP_SET_SOM:      case OP_SET_SOM:
# Line 5657  while (cc < ccend) Line 6555  while (cc < ccend)
6555      case OP_CHAR:      case OP_CHAR:
6556      case OP_CHARI:      case OP_CHARI:
6557      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6558        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6559      else      else
6560        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6561      break;      break;
6562    
6563      case OP_STAR:      case OP_STAR:
# Line 5727  while (cc < ccend) Line 6625  while (cc < ccend)
6625      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6626      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6627      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6628      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6629      break;      break;
6630    
6631      case OP_CLASS:      case OP_CLASS:
6632      case OP_NCLASS:      case OP_NCLASS:
6633      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
6634        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6635      else      else
6636        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6637      break;      break;
6638    
6639  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6640      case OP_XCLASS:      case OP_XCLASS:
6641      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6642        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6643      else      else
6644        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6645      break;      break;
6646  #endif  #endif
6647    
6648      case OP_REF:      case OP_REF:
6649      case OP_REFI:      case OP_REFI:
6650      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
6651        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6652      else      else
6653        cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
6654      break;      break;
6655    
6656      case OP_RECURSE:      case OP_RECURSE:
6657      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6658      break;      break;
6659    
6660      case OP_ASSERT:      case OP_ASSERT:
# Line 5764  while (cc < ccend) Line 6662  while (cc < ccend)
6662      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6663      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6664      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6665      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6666      break;      break;
6667    
6668      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 5781  while (cc < ccend) Line 6679  while (cc < ccend)
6679        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6680        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6681        }        }
6682      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6683      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6684        decrease_call_count(common);        decrease_call_count(common);
6685      break;      break;
# Line 5794  while (cc < ccend) Line 6692  while (cc < ccend)
6692      case OP_SBRA:      case OP_SBRA:
6693      case OP_SCBRA:      case OP_SCBRA:
6694      case OP_SCOND:      case OP_SCOND:
6695      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6696      break;      break;
6697    
6698      case OP_BRAZERO:      case OP_BRAZERO:
6699      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6700        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6701      else      else
6702        {        {
6703        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6704        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6705        }        }
6706      break;      break;
6707    
# Line 5812  while (cc < ccend) Line 6710  while (cc < ccend)
6710      case OP_SBRAPOS:      case OP_SBRAPOS:
6711      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6712      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6713      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6714      break;      break;
6715    
6716      case OP_MARK:      case OP_MARK:
# Line 5836  while (cc < ccend) Line 6734  while (cc < ccend)
6734      case OP_FAIL:      case OP_FAIL:
6735      case OP_ACCEPT:      case OP_ACCEPT:
6736      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6737      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6738      break;      break;
6739    
6740      case OP_CLOSE:      case OP_CLOSE:
6741      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6742      break;      break;
6743    
6744      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 5861  SLJIT_ASSERT(cc == ccend); Line 6759  SLJIT_ASSERT(cc == ccend);
6759  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6760  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6761    
6762  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6763    do \    do \
6764      { \      { \
6765      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6766      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6767        return; \        return; \
6768      } \      } \
# Line 5872  SLJIT_ASSERT(cc == ccend); Line 6770  SLJIT_ASSERT(cc == ccend);
6770    
6771  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6772    
6773  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6774  {  {
6775  DEFINE_COMPILER;  DEFINE_COMPILER;
6776  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5881  pcre_uchar type; Line 6779  pcre_uchar type;
6779  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
6780  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6781  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6782    jump_list *jumplist = NULL;
6783    int private_data_ptr = PRIVATE_DATA(cc);
6784    int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6785    int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6786    int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6787    
6788  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6789    
# Line 5892  switch(opcode) Line 6795  switch(opcode)
6795    case OP_CRRANGE:    case OP_CRRANGE:
6796    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6797      {      {
6798        SLJIT_ASSERT(private_data_ptr == 0);
6799      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6800      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6801      free_stack(common, 1);      free_stack(common, 1);
6802      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6803      }      }
6804    else    else
6805      {      {
6806      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_UPTO)
6807        arg2 = 0;        arg2 = 0;
6808      else if (opcode == OP_PLUS)      if (opcode <= OP_PLUS)
6809        arg2 = 1;        {
6810      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6811      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1);
6812      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        }
6813        else
6814          {
6815          OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6816          OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6817          jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
6818          OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
6819          }
6820      skip_char_back(common);      skip_char_back(common);
6821      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6822      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6823      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6824        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6825      JUMPHERE(jump);      JUMPHERE(jump);
6826      free_stack(common, 2);      if (private_data_ptr == 0)
6827          free_stack(common, 2);
6828        if (opcode == OP_PLUS)
6829          set_jumps(current->topbacktracks, LABEL());
6830      }      }
6831    break;    break;
6832    
6833    case OP_MINSTAR:    case OP_MINSTAR:
6834    case OP_MINPLUS:    case OP_MINPLUS:
6835    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6836      compile_char1_matchingpath(common, type, cc, &jumplist);
6837      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6838      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6839      set_jumps(jumplist, LABEL());
6840      if (private_data_ptr == 0)
6841        free_stack(common, 1);
6842    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
     {  
6843      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
     current->topbacktracks = NULL;  
     }  
   compile_char1_trypath(common, type, cc, &current->topbacktracks);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);  
   set_jumps(current->topbacktracks, LABEL());  
   free_stack(common, 1);  
6844    break;    break;
6845    
6846    case OP_MINUPTO:    case OP_MINUPTO:
6847    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6848    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6849      {      {
     set_jumps(current->topbacktracks, LABEL());  
     current->topbacktracks = NULL;  
6850      label = LABEL();      label = LABEL();
6851        set_jumps(current->topbacktracks, label);
6852      }      }
6853    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6854    compile_char1_trypath(common, type, cc, &current->topbacktracks);    compile_char1_matchingpath(common, type, cc, &jumplist);
6855    
6856    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6857    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6858    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6859    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6860    
6861    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6862      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6863    
6864    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6865      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6866    else    else
6867      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
6868    
6869    set_jumps(current->topbacktracks, LABEL());    set_jumps(jumplist, LABEL());
6870    free_stack(common, 2);    if (private_data_ptr == 0)
6871        free_stack(common, 2);
6872    break;    break;
6873    
6874    case OP_QUERY:    case OP_QUERY:
6875    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6876    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6877    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6878    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6879    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6880    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6881    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6882    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6883    JUMPHERE(jump);    JUMPHERE(jump);
6884    free_stack(common, 1);    if (private_data_ptr == 0)
6885        free_stack(common, 1);
6886    break;    break;
6887    
6888    case OP_MINQUERY:    case OP_MINQUERY:
6889    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6890    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6891    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6892    compile_char1_trypath(common, type, cc, &current->topbacktracks);    compile_char1_matchingpath(common, type, cc, &jumplist);
6893    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6894    set_jumps(current->topbacktracks, LABEL());    set_jumps(jumplist, LABEL());
6895    JUMPHERE(jump);    JUMPHERE(jump);
6896    free_stack(common, 1);    if (private_data_ptr == 0)
6897        free_stack(common, 1);
6898    break;    break;
6899    
6900    case OP_EXACT:    case OP_EXACT:
# Line 5999  switch(opcode) Line 6913  switch(opcode)
6913    }    }
6914  }  }
6915    
6916  static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6917  {  {
6918  DEFINE_COMPILER;  DEFINE_COMPILER;
6919  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6011  if ((type & 0x1) == 0) Line 6925  if ((type & 0x1) == 0)
6925    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6926    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6927    free_stack(common, 1);    free_stack(common, 1);
6928    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6929    return;    return;
6930    }    }
6931    
6932  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6933  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6934  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6935  free_stack(common, 2);  free_stack(common, 2);
6936  }  }
6937    
6938  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6939  {  {
6940  DEFINE_COMPILER;  DEFINE_COMPILER;
6941    
# Line 6043  else if (common->has_set_som || common-> Line 6957  else if (common->has_set_som || common->
6957    }    }
6958  }  }
6959    
6960  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6961  {  {
6962  DEFINE_COMPILER;  DEFINE_COMPILER;
6963  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6070  if (CURRENT_AS(assert_backtrack)->frames Line 6984  if (CURRENT_AS(assert_backtrack)->frames
6984    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6985      {      {
6986      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6987      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6988      free_stack(common, 1);      free_stack(common, 1);
6989      }      }
6990    return;    return;
# Line 6081  if (bra == OP_BRAZERO) Line 6995  if (bra == OP_BRAZERO)
6995    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6996      {      {
6997      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6998      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6999      free_stack(common, 1);      free_stack(common, 1);
7000      return;      return;
7001      }      }
# Line 6091  if (bra == OP_BRAZERO) Line 7005  if (bra == OP_BRAZERO)
7005    
7006  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7007    {    {
7008    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr);
7009    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7010    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
7011    
7012    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7013    }    }
# Line 6105  if (bra == OP_BRAZERO) Line 7019  if (bra == OP_BRAZERO)
7019    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
7020    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
7021    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7022    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
7023    JUMPHERE(brajump);    JUMPHERE(brajump);
7024    }    }
7025  }  }
7026    
7027  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7028  {  {
7029  DEFINE_COMPILER;  DEFINE_COMPILER;
7030  int opcode;  int opcode;
7031  int offset = 0;  int offset = 0;
7032  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7033  int stacksize;  int stacksize;
7034  int count;  int count;
7035  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6154  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC) Line 7068  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)
7068    
7069  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7070    {    {
7071    if (bra != OP_BRAZERO)    if (bra == OP_BRAZERO)
     free_stack(common, 1);  
   else  
7072      {      {
7073      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7074      free_stack(common, 1);      free_stack(common, 1);
# Line 6172  else if (ket == OP_KETRMIN) Line 7084  else if (ket == OP_KETRMIN)
7084        {        {
7085        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7086        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7087          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7088        else        else
7089          {          {
7090          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7091          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7092          }          }
7093        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7094          free_stack(common, 1);          free_stack(common, 1);
7095        }        }
7096      else      else
7097        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7098      }      }
7099    rminlabel = LABEL();    rminlabel = LABEL();
7100    }    }
# Line 6197  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7109  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7109    {    {
7110    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7111      {      {
7112      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7113      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7114      }      }
7115    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 6250  else if (*cc == OP_ALT) Line 7162  else if (*cc == OP_ALT)
7162    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7163    }    }
7164    
7165  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7166  if (current->topbacktracks)  if (current->topbacktracks)
7167    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7168    
# Line 6263  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7175  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7175      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7176      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
7177        {        {
7178        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7179        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7180        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
7181        }        }
7182      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7183      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
# Line 6294  if (has_alternatives) Line 7206  if (has_alternatives)
7206        cc += GET(cc, 1);        cc += GET(cc, 1);
7207        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7208          {          {
7209          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7210            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7211          else          else
7212            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7213          }          }
7214        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7215        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7216          return;          return;
7217        }        }
7218    
7219      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7220      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7221      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7222        {        {
7223        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7224          {          {
7225          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7226          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7227          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7228            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7229          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7230            {            {
7231            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7232            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
7233            }            }
7234          }          }
7235        else        else
7236          {          {
7237          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
7238          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7239            {            {
7240            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 6363  if (has_alternatives) Line 7275  if (has_alternatives)
7275    
7276      if (offset != 0)      if (offset != 0)
7277        {        {
7278        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7279        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7280        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
7281        }        }
7282    
7283      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7284    
7285      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7286        {        {
# Line 6377  if (has_alternatives) Line 7289  if (has_alternatives)
7289        jumplist = jumplist->next;        jumplist = jumplist->next;
7290        }        }
7291    
7292      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7293      if (current->topbacktracks)      if (current->topbacktracks)
7294        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7295      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 6392  if (has_alternatives) Line 7304  if (has_alternatives)
7304      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
7305    
7306        {        {
7307        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7308        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7309        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
7310        }        }
7311      JUMPHERE(cond);      JUMPHERE(cond);
7312      }      }
7313    
7314    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7315    if (localptr == 0)    if (private_data_ptr == 0)
7316      free_stack(common, 1);      free_stack(common, 1);
7317    }    }
7318    
7319  if (offset != 0)  if (offset != 0)
7320    {    {
7321    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7322    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7323    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7324    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7325    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7326    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7327    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7328        free_stack(common, 3);
7329        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7330        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7331        }
7332      else
7333        {
7334        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7335        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7336        free_stack(common, 2);
7337        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7338        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7339        }
7340    }    }
7341  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7342    {    {
7343    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
7344    free_stack(common, 1);    free_stack(common, 1);
7345    }    }
7346  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 6435  else if (opcode == OP_ONCE) Line 7359  else if (opcode == OP_ONCE)
7359      }      }
7360    
7361    JUMPHERE(once);    JUMPHERE(once);
7362    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7363    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7364      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
7365    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7366      {      {
7367      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7368      /* See the comment below. */      /* See the comment below. */
7369      free_stack(common, 2);      free_stack(common, 2);
7370      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7371      }      }
7372    }    }
7373    
7374  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7375    {    {
7376    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7377    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);    if (bra != OP_BRAZERO)
7378        free_stack(common, 1);
7379      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7380    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7381      {      {
7382      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7383      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7384      JUMPHERE(brazero);      JUMPHERE(brazero);
7385        free_stack(common, 1);
7386      }      }
   free_stack(common, 1);  
7387    }    }
7388  else if (ket == OP_KETRMIN)  else if (ket == OP_KETRMIN)
7389    {    {
# Line 6477  else if (ket == OP_KETRMIN) Line 7403  else if (ket == OP_KETRMIN)
7403  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7404    {    {
7405    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7406    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7407    JUMPHERE(brazero);    JUMPHERE(brazero);
7408    }    }
7409  }  }
7410    
7411  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7412  {  {
7413  DEFINE_COMPILER;  DEFINE_COMPILER;
7414  int offset;  int offset;
# Line 6503  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7429  if (CURRENT_AS(bracketpos_backtrack)->fr
7429    return;    return;
7430    }    }
7431    
7432  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
7433  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7434    
7435  if (current->topbacktracks)  if (current->topbacktracks)
# Line 6514  if (current->topbacktracks) Line 7440  if (current->topbacktracks)
7440    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7441    JUMPHERE(jump);    JUMPHERE(jump);
7442    }    }
7443  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
7444  }  }
7445    
7446  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7447  {  {
7448  assert_backtrack backtrack;  assert_backtrack backtrack;
7449    
# Line 6526  current->topbacktracks = NULL; Line 7452  current->topbacktracks = NULL;
7452  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7453  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7454    {    {
7455    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7456    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7457    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7458    }    }
7459  else  else
7460    {    {
7461    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7462    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7463    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7464    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7465    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7466    }    }
7467  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7468  }  }
7469    
7470  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7471  {  {
7472  DEFINE_COMPILER;  DEFINE_COMPILER;
7473    
# Line 6627  while (current) Line 7553  while (current)
7553  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7554      case OP_XCLASS:      case OP_XCLASS:
7555  #endif  #endif
7556      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7557      break;      break;
7558    
7559      case OP_REF:      case OP_REF:
7560      case OP_REFI:      case OP_REFI:
7561      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7562      break;      break;
7563    
7564      case OP_RECURSE:      case OP_RECURSE:
7565      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7566      break;      break;
7567    
7568      case OP_ASSERT:      case OP_ASSERT:
7569      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7570      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7571      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7572      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7573      break;      break;
7574    
7575      case OP_ONCE:      case OP_ONCE:
# Line 6654  while (current) Line 7580  while (current)
7580      case OP_SBRA:      case OP_SBRA:
7581      case OP_SCBRA:      case OP_SCBRA:
7582      case OP_SCOND:      case OP_SCOND:
7583      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7584      break;      break;
7585    
7586      case OP_BRAZERO:      case OP_BRAZERO:
7587      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7588        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7589      else      else
7590        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7591      break;      break;
7592    
7593      case OP_BRAPOS:      case OP_BRAPOS:
# Line 6669  while (current) Line 7595  while (current)
7595      case OP_SBRAPOS:      case OP_SBRAPOS:
7596      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7597      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7598      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7599      break;      break;
7600    
7601      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7602      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7603      break;      break;
7604    
7605      case OP_MARK:      case OP_MARK:
# Line 6684  while (current) Line 7610  while (current)
7610    
7611      case OP_COMMIT:      case OP_COMMIT:
7612      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7613      if (common->leavelabel == NULL)      if (common->quitlabel == NULL)
7614        add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7615      else      else
7616        JUMPTO(SLJIT_JUMP, common->leavelabel);        JUMPTO(SLJIT_JUMP, common->quitlabel);
7617      break;      break;
7618    
7619      case OP_FAIL:      case OP_FAIL:
# Line 6710  DEFINE_COMPILER; Line 7636  DEFINE_COMPILER;
7636  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7637  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
7638  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7639  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7640  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7641  int alternativesize;  int alternativesize;
7642  BOOL needsframe;  BOOL needsframe;
7643  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7644  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
7645  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
7646  struct sljit_jump *jump;  struct sljit_jump *jump;
7647    
7648  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 6730  common->currententry->entry = LABEL(); Line 7656  common->currententry->entry = LABEL();
7656  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7657    
7658  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7659  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7660  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
7661  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7662  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
7663  if (needsframe)  if (needsframe)
7664    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 6741  if (alternativesize > 0) Line 7667  if (alternativesize > 0)
7667    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7668    
7669  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7670  common->leavelabel = NULL;  common->quitlabel = NULL;
7671  common->acceptlabel = NULL;  common->acceptlabel = NULL;
7672  common->leave = NULL;  common->quit = NULL;
7673  common->accept = NULL;  common->accept = NULL;
7674  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
7675  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6755  while (1) Line 7681  while (1)
7681    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7682      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7683    
7684    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7685    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7686      {      {
7687      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7688      common->leave = save_leave;      common->quit = save_quit;
7689      return;      return;
7690      }      }
7691    
7692    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7693    
7694    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7695    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7696      {      {
7697      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7698      common->leave = save_leave;      common->quit = save_quit;
7699      return;      return;
7700      }      }
7701    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
# Line 6781  while (1) Line 7707  while (1)
7707    cc += GET(cc, 1);    cc += GET(cc, 1);
7708    }    }
7709  /* None of them matched. */  /* None of them matched. */
7710  if (common->leave != NULL)  if (common->quit != NULL)
7711    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
7712