/[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 991 by zherczeg, Sun Jul 8 16:44:39 2012 UTC revision 1084 by chpe, Tue Oct 16 15:55:28 2012 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 89  vertical (sub-expression) (See struct ba Line 92  vertical (sub-expression) (See struct ba
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
95  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
97  branches on the try path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Try path: match happens.     Matching path: match happens.
101     Backtrack path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Try path: no need to perform a match.     Matching path: no need to perform a match.
104     Backtrack path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A try path   A matching path
115   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B try path   B matching path
117   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D try path   D matching path
119   return with successful match   return with successful match
120    
121   D backtrack path   D backtrack path
122   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
123   B backtrack path   B backtrack path
124   C expected path   C expected path
125   jump to D try path   jump to D matching path
126   C backtrack path   C backtrack path
127   A backtrack path   A backtrack path
128    
# Line 127  The generated code will be the following Line 130  The generated code will be the following
130   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
131   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
132   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
133   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 188  typedef struct stub_list { Line 191  typedef struct stub_list {
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct backtrack_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
# Line 208  typedef struct assert_backtrack { Line 211  typedef struct assert_backtrack {
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *trypath;    struct sljit_label *matchingpath;
217  } assert_backtrack;  } assert_backtrack;
218    
219  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
220    backtrack_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 230  typedef struct bracket_backtrack { Line 233  typedef struct bracket_backtrack {
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_backtrack;  } bracket_backtrack;
238    
239  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
240    backtrack_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
# Line 245  typedef struct bracketpos_backtrack { Line 248  typedef struct bracketpos_backtrack {
248    
249  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
250    backtrack_common common;    backtrack_common common;
251    struct sljit_label *trypath;    struct sljit_label *matchingpath;
252  } braminzero_backtrack;  } braminzero_backtrack;
253    
254  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
255    backtrack_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *trypath;    struct sljit_label *matchingpath;
258  } iterator_backtrack;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 274  typedef struct compiler_common { Line 277  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    
280    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
281    int *localptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 337  typedef struct compiler_common { Line 343  typedef struct compiler_common {
343  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
344    BOOL use_ucp;    BOOL use_ucp;
345  #endif  #endif
346    #ifndef COMPILE_PCRE32
347    jump_list *utfreadchar;    jump_list *utfreadchar;
348    #endif
349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
350    jump_list *utfreadtype8;    jump_list *utfreadtype8;
351  #endif  #endif
# Line 357  typedef struct compare_context { Line 365  typedef struct compare_context {
365    union {    union {
366      sljit_i asint;      sljit_i asint;
367      sljit_uh asushort;      sljit_uh asushort;
368  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
369      sljit_ub asbyte;      sljit_ub asbyte;
370      sljit_ub asuchars[4];      sljit_ub asuchars[4];
371  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
372      sljit_uh asuchars[2];      sljit_uh asuchars[2];
373  #endif  #elif defined COMPILE_PCRE32
374        sljit_ui asuchars[1];
375  #endif  #endif
376    } c;    } c;
377    union {    union {
378      sljit_i asint;      sljit_i asint;
379      sljit_uh asushort;      sljit_uh asushort;
380  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
381      sljit_ub asbyte;      sljit_ub asbyte;
382      sljit_ub asuchars[4];      sljit_ub asuchars[4];
383  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
384      sljit_uh asuchars[2];      sljit_uh asuchars[2];
385  #endif  #elif defined COMPILE_PCRE32
386        sljit_ui asuchars[1];
387  #endif  #endif
388    } oc;    } oc;
389  #endif  #endif
# Line 404  enum { Line 412  enum {
412  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
413  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
414    
415  /* Locals layout. */  /* Local space layout. */
416  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
417  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
418  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 420  the start pointers when the end of the c Line 428  the start pointers when the end of the c
428  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
429  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
430  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
431  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
432    
433  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
434  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
435  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
436  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
437  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
438  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
439    #elif defined COMPILE_PCRE32
440    #define MOV_UCHAR  SLJIT_MOV_UI
441    #define MOVU_UCHAR SLJIT_MOVU_UI
442  #else  #else
443  #error Unsupported compiling mode  #error Unsupported compiling mode
444  #endif  #endif
 #endif  
445    
446  /* Shortcuts. */  /* Shortcuts. */
447  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 469  return cc; Line 478  return cc;
478    
479  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
480   next_opcode   next_opcode
481   get_localspace   get_private_data_length
482   set_localptrs   set_private_data_ptrs
483   get_framesize   get_framesize
484   init_frame   init_frame
485   get_localsize   get_private_data_length_for_copy
486   copy_locals   copy_private_data
487   compile_trypath   compile_matchingpath
488   compile_backtrackpath   compile_backtrackingpath
489  */  */
490    
491  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 582  switch(*cc) Line 591  switch(*cc)
591    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
592    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
593    cc += 2;    cc += 2;
594  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
595    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
596  #endif  #endif
597    return cc;    return cc;
# Line 604  switch(*cc) Line 613  switch(*cc)
613    case OP_NOTEXACTI:    case OP_NOTEXACTI:
614    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
615    cc += 2 + IMM2_SIZE;    cc += 2 + IMM2_SIZE;
616  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
617    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
618  #endif  #endif
619    return cc;    return cc;
# Line 675  switch(*cc) Line 684  switch(*cc)
684    }    }
685  }  }
686    
687  #define CASE_ITERATOR_LOCAL1 \  #define CASE_ITERATOR_PRIVATE_DATA_1 \
688      case OP_MINSTAR: \      case OP_MINSTAR: \
689      case OP_MINPLUS: \      case OP_MINPLUS: \
690      case OP_QUERY: \      case OP_QUERY: \
# Line 693  switch(*cc) Line 702  switch(*cc)
702      case OP_NOTQUERYI: \      case OP_NOTQUERYI: \
703      case OP_NOTMINQUERYI:      case OP_NOTMINQUERYI:
704    
705  #define CASE_ITERATOR_LOCAL2A \  #define CASE_ITERATOR_PRIVATE_DATA_2A \
706      case OP_STAR: \      case OP_STAR: \
707      case OP_PLUS: \      case OP_PLUS: \
708      case OP_STARI: \      case OP_STARI: \
# Line 703  switch(*cc) Line 712  switch(*cc)
712      case OP_NOTSTARI: \      case OP_NOTSTARI: \
713      case OP_NOTPLUSI:      case OP_NOTPLUSI:
714    
715  #define CASE_ITERATOR_LOCAL2B \  #define CASE_ITERATOR_PRIVATE_DATA_2B \
716      case OP_UPTO: \      case OP_UPTO: \
717      case OP_MINUPTO: \      case OP_MINUPTO: \
718      case OP_UPTOI: \      case OP_UPTOI: \
# Line 713  switch(*cc) Line 722  switch(*cc)
722      case OP_NOTUPTOI: \      case OP_NOTUPTOI: \
723      case OP_NOTMINUPTOI:      case OP_NOTMINUPTOI:
724    
725  #define CASE_ITERATOR_TYPE_LOCAL1 \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
726      case OP_TYPEMINSTAR: \      case OP_TYPEMINSTAR: \
727      case OP_TYPEMINPLUS: \      case OP_TYPEMINPLUS: \
728      case OP_TYPEQUERY: \      case OP_TYPEQUERY: \
729      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
730    
731  #define CASE_ITERATOR_TYPE_LOCAL2A \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
732      case OP_TYPESTAR: \      case OP_TYPESTAR: \
733      case OP_TYPEPLUS:      case OP_TYPEPLUS:
734    
735  #define CASE_ITERATOR_TYPE_LOCAL2B \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
736      case OP_TYPEUPTO: \      case OP_TYPEUPTO: \
737      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
738    
# Line 752  switch(*cc) Line 761  switch(*cc)
761    }    }
762  }  }
763    
764  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
765  {  {
766  int localspace = 0;  int private_data_length = 0;
767  pcre_uchar *alternative;  pcre_uchar *alternative;
768    pcre_uchar *name;
769  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
770  int space, size, bracketlen;  int space, size, bracketlen, i;
771    
772  /* 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. */
773  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 782  while (cc < ccend)
782      cc += 1;      cc += 1;
783      break;      break;
784    
785        case OP_REF:
786        case OP_REFI:
787        common->optimized_cbracket[GET2(cc, 1)] = 0;
788        cc += 1 + IMM2_SIZE;
789        break;
790    
791      case OP_ASSERT:      case OP_ASSERT:
792      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
793      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 781  while (cc < ccend) Line 797  while (cc < ccend)
797      case OP_BRAPOS:      case OP_BRAPOS:
798      case OP_SBRA:      case OP_SBRA:
799      case OP_SBRAPOS:      case OP_SBRAPOS:
800      case OP_SCOND:      private_data_length += sizeof(sljit_w);
     localspace += sizeof(sljit_w);  
801      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
802      break;      break;
803    
804      case OP_CBRAPOS:      case OP_CBRAPOS:
805      case OP_SCBRAPOS:      case OP_SCBRAPOS:
806      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
807        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
808      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
809      break;      break;
810    
811      case OP_COND:      case OP_COND:
812      /* Might be a hidden SCOND. */      case OP_SCOND:
813      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
814      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
815        localspace += sizeof(sljit_w);        {
816          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
817          common->optimized_cbracket[bracketlen] = 0;
818          }
819        else if (bracketlen == OP_NCREF)
820          {
821          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
822          name = (pcre_uchar *)common->name_table;
823          alternative = name;
824          for (i = 0; i < common->name_count; i++)
825            {
826            if (GET2(name, 0) == bracketlen) break;
827            name += common->name_entry_size;
828            }
829          SLJIT_ASSERT(i != common->name_count);
830    
831          for (i = 0; i < common->name_count; i++)
832            {
833            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
834              common->optimized_cbracket[GET2(alternative, 0)] = 0;
835            alternative += common->name_entry_size;
836            }
837          }
838    
839        if (*cc == OP_COND)
840          {
841          /* Might be a hidden SCOND. */
842          alternative = cc + GET(cc, 1);
843          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
844            private_data_length += sizeof(sljit_w);
845          }
846        else
847          private_data_length += sizeof(sljit_w);
848      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
849      break;      break;
850    
# Line 809  while (cc < ccend) Line 857  while (cc < ccend)
857      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
858      break;      break;
859    
860      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
861      space = 1;      space = 1;
862      size = -2;      size = -2;
863      break;      break;
864    
865      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
866      space = 2;      space = 2;
867      size = -2;      size = -2;
868      break;      break;
869    
870      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
871      space = 2;      space = 2;
872      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
873      break;      break;
874    
875      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
876      space = 1;      space = 1;
877      size = 1;      size = 1;
878      break;      break;
879    
880      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
881      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
882        space = 2;        space = 2;
883      size = 1;      size = 1;
884      break;      break;
885    
886      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
887      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
888        space = 2;        space = 2;
889      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 881  while (cc < ccend) Line 929  while (cc < ccend)
929      }      }
930    
931    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
932      localspace += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_w) * space;
933    
934    if (size != 0)    if (size != 0)
935      {      {
936      if (size < 0)      if (size < 0)
937        {        {
938        cc += -size;        cc += -size;
939  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
940        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
941  #endif  #endif
942        }        }
# Line 907  while (cc < ccend) Line 955  while (cc < ccend)
955      cc += bracketlen;      cc += bracketlen;
956      }      }
957    }    }
958  return localspace;  return private_data_length;
959  }  }
960    
961  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)
962  {  {
963  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
964  pcre_uchar *alternative;  pcre_uchar *alternative;
# Line 934  while (cc < ccend) Line 982  while (cc < ccend)
982      case OP_SBRA:      case OP_SBRA:
983      case OP_SBRAPOS:      case OP_SBRAPOS:
984      case OP_SCOND:      case OP_SCOND:
985      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
986      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
987      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
988      break;      break;
989    
990      case OP_CBRAPOS:      case OP_CBRAPOS:
991      case OP_SCBRAPOS:      case OP_SCBRAPOS:
992      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
993      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
994      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
995      break;      break;
996    
# Line 951  while (cc < ccend) Line 999  while (cc < ccend)
999      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1000      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1001        {        {
1002        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1003        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1004        }        }
1005      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1006      break;      break;
# Line 966  while (cc < ccend) Line 1014  while (cc < ccend)
1014      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1015      break;      break;
1016    
1017      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1018      space = 1;      space = 1;
1019      size = -2;      size = -2;
1020      break;      break;
1021    
1022      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1023      space = 2;      space = 2;
1024      size = -2;      size = -2;
1025      break;      break;
1026    
1027      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1028      space = 2;      space = 2;
1029      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
1030      break;      break;
1031    
1032      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1033      space = 1;      space = 1;
1034      size = 1;      size = 1;
1035      break;      break;
1036    
1037      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1038      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1039        space = 2;        space = 2;
1040      size = 1;      size = 1;
1041      break;      break;
1042    
1043      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1044      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1045        space = 2;        space = 2;
1046      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 1019  while (cc < ccend) Line 1067  while (cc < ccend)
1067    
1068    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1069      {      {
1070      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1071      localptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_w) * space;
1072      }      }
1073    
1074    if (size != 0)    if (size != 0)
# Line 1028  while (cc < ccend) Line 1076  while (cc < ccend)
1076      if (size < 0)      if (size < 0)
1077        {        {
1078        cc += -size;        cc += -size;
1079  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1080        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1081  #endif  #endif
1082        }        }
# Line 1222  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1270  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1270  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1271  }  }
1272    
1273  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)
1274  {  {
1275  int localsize = 2;  int private_data_length = 2;
1276  int size;  int size;
1277  pcre_uchar *alternative;  pcre_uchar *alternative;
1278  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1279  while (cc < ccend)  while (cc < ccend)
1280    {    {
1281    size = 0;    size = 0;
# Line 1243  while (cc < ccend) Line 1291  while (cc < ccend)
1291      case OP_SBRA:      case OP_SBRA:
1292      case OP_SBRAPOS:      case OP_SBRAPOS:
1293      case OP_SCOND:      case OP_SCOND:
1294      localsize++;      private_data_length++;
1295      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1296      break;      break;
1297    
1298      case OP_CBRA:      case OP_CBRA:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1301          private_data_length++;
1302      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1303      break;      break;
1304    
1305      case OP_CBRAPOS:      case OP_CBRAPOS:
1306      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1307      localsize += 2;      private_data_length += 2;
1308      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1309      break;      break;
1310    
# Line 1263  while (cc < ccend) Line 1312  while (cc < ccend)
1312      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1313      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1314      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1315        localsize++;        private_data_length++;
1316      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1317      break;      break;
1318    
1319      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1320      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1321        localsize++;        private_data_length++;
1322      cc += 2;      cc += 2;
1323  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1324      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1325  #endif  #endif
1326      break;      break;
1327    
1328      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1329      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1330        localsize += 2;        private_data_length += 2;
1331      cc += 2;      cc += 2;
1332  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1333      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1334  #endif  #endif
1335      break;      break;
1336    
1337      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1338      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1339        localsize += 2;        private_data_length += 2;
1340      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1341  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1342      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1343  #endif  #endif
1344      break;      break;
1345    
1346      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1347      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1348        localsize++;        private_data_length++;
1349      cc += 1;      cc += 1;
1350      break;      break;
1351    
1352      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1353      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1354        localsize += 2;        private_data_length += 2;
1355      cc += 1;      cc += 1;
1356      break;      break;
1357    
1358      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1359      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1360        localsize += 2;        private_data_length += 2;
1361      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
1362      break;      break;
1363    
# Line 1320  while (cc < ccend) Line 1369  while (cc < ccend)
1369  #else  #else
1370      size = 1 + 32 / (int)sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1371  #endif  #endif
1372      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1373        localsize += get_class_iterator_size(cc + size);        private_data_length += get_class_iterator_size(cc + size);
1374      cc += size;      cc += size;
1375      break;      break;
1376    
# Line 1332  while (cc < ccend) Line 1381  while (cc < ccend)
1381      }      }
1382    }    }
1383  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1384  return localsize;  return private_data_length;
1385  }  }
1386    
1387  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,
1388    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1389  {  {
1390  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1405  while (status != end) Line 1454  while (status != end)
1454        case OP_SBRAPOS:        case OP_SBRAPOS:
1455        case OP_SCOND:        case OP_SCOND:
1456        count = 1;        count = 1;
1457        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1458        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1459        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1460        break;        break;
1461    
1462        case OP_CBRA:        case OP_CBRA:
1463        case OP_SCBRA:        case OP_SCBRA:
1464        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1465        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1466            count = 1;
1467            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1468            }
1469        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1470        break;        break;
1471    
1472        case OP_CBRAPOS:        case OP_CBRAPOS:
1473        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1474        count = 2;        count = 2;
1475        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1476        srcw[1] = PRIV_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1477        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1478        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1479        break;        break;
1480    
# Line 1432  while (status != end) Line 1484  while (status != end)
1484        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1485          {          {
1486          count = 1;          count = 1;
1487          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1488          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1489          }          }
1490        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1491        break;        break;
1492    
1493        CASE_ITERATOR_LOCAL1        CASE_ITERATOR_PRIVATE_DATA_1
1494        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1495          {          {
1496          count = 1;          count = 1;
1497          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1498          }          }
1499        cc += 2;        cc += 2;
1500  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1501        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1502  #endif  #endif
1503        break;        break;
1504    
1505        CASE_ITERATOR_LOCAL2A        CASE_ITERATOR_PRIVATE_DATA_2A
1506        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1507          {          {
1508          count = 2;          count = 2;
1509          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1510          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1511          }          }
1512        cc += 2;        cc += 2;
1513  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1514        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1515  #endif  #endif
1516        break;        break;
1517    
1518        CASE_ITERATOR_LOCAL2B        CASE_ITERATOR_PRIVATE_DATA_2B
1519        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1520          {          {
1521          count = 2;          count = 2;
1522          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1523          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1524          }          }
1525        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1526  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1527        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1528  #endif  #endif
1529        break;        break;
1530    
1531        CASE_ITERATOR_TYPE_LOCAL1        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1532        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1533          {          {
1534          count = 1;          count = 1;
1535          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1536          }          }
1537        cc += 1;        cc += 1;
1538        break;        break;
1539    
1540        CASE_ITERATOR_TYPE_LOCAL2A        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1541        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1542          {          {
1543          count = 2;          count = 2;
1544          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1545          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1546          }          }
1547        cc += 1;        cc += 1;
1548        break;        break;
1549    
1550        CASE_ITERATOR_TYPE_LOCAL2B        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1551        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1552          {          {
1553          count = 2;          count = 2;
1554          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1555          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1556          }          }
1557        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
# Line 1513  while (status != end) Line 1565  while (status != end)
1565  #else  #else
1566        size = 1 + 32 / (int)sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1567  #endif  #endif
1568        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1569          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
1570            {            {
1571            case 1:            case 1:
1572            count = 1;            count = 1;
1573            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1574            break;            break;
1575    
1576            case 2:            case 2:
1577            count = 2;            count = 2;
1578            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1579            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_w);
1580            break;            break;
1581    
# Line 1636  if (save) Line 1688  if (save)
1688  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1689  }  }
1690    
1691  #undef CASE_ITERATOR_LOCAL1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1692  #undef CASE_ITERATOR_LOCAL2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1693  #undef CASE_ITERATOR_LOCAL2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
1694  #undef CASE_ITERATOR_TYPE_LOCAL1  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1695  #undef CASE_ITERATOR_TYPE_LOCAL2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1696  #undef CASE_ITERATOR_TYPE_LOCAL2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1697    
1698  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1699  {  {
1700  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1701  }  }
# Line 1653  static SLJIT_INLINE void set_jumps(jump_ Line 1705  static SLJIT_INLINE void set_jumps(jump_
1705  while (list)  while (list)
1706    {    {
1707    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1708    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1709    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1710    list = list->next;    list = list->next;
1711    }    }
# Line 1785  loop = LABEL(); Line 1837  loop = LABEL();
1837  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1838  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1839  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1840  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1841  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1842  #endif  #endif
1843  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1844  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
# Line 1827  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 1879  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
1879  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1880  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1881  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1882  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1883  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1884  #endif  #endif
1885  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1886    
1887  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1888  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1889  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1890  #endif  #endif
1891  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);
1892    
# Line 1949  if (c <= 127 && bit == 0x20) Line 2001  if (c <= 127 && bit == 0x20)
2001    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2002    
2003  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2004  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2005    return 0;    return 0;
2006    
2007  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2008    
2009  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2010  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1968  if (common->utf && c > 127) Line 2020  if (common->utf && c > 127)
2020  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2021  return (0 << 8) | bit;  return (0 << 8) | bit;
2022    
2023  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2024    
 #ifdef COMPILE_PCRE16  
2025  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2026  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2027    {    {
# Line 1981  if (common->utf && c > 65535) Line 2032  if (common->utf && c > 65535)
2032    }    }
2033  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2034  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2035    
2036  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2037  }  }
2038    
2039  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 2081  static void read_char(compiler_common *c Line 2131  static void read_char(compiler_common *c
2131  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2132  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2133  DEFINE_COMPILER;  DEFINE_COMPILER;
2134  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2135  struct sljit_jump *jump;  struct sljit_jump *jump;
2136  #endif  #endif
2137    
2138  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2139  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2140  if (common->utf)  if (common->utf)
2141    {    {
2142  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2143    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2144  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2146  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2147    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2148    JUMPHERE(jump);    JUMPHERE(jump);
2149    }    }
2150  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2151  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));
2152  }  }
2153    
# Line 2108  static void peek_char(compiler_common *c Line 2156  static void peek_char(compiler_common *c
2156  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2157  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2158  DEFINE_COMPILER;  DEFINE_COMPILER;
2159  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2160  struct sljit_jump *jump;  struct sljit_jump *jump;
2161  #endif  #endif
2162    
2163  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2164  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2165  if (common->utf)  if (common->utf)
2166    {    {
2167  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2168    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2169  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2171  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2172    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2173    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2174    JUMPHERE(jump);    JUMPHERE(jump);
2175    }    }
2176  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2177  }  }
2178    
2179  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2180  {  {
2181  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2182  DEFINE_COMPILER;  DEFINE_COMPILER;
2183  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2184  struct sljit_jump *jump;  struct sljit_jump *jump;
2185  #endif  #endif
2186    
# Line 2143  if (common->utf) Line 2189  if (common->utf)
2189    {    {
2190    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2191    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));
2192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2193    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2194    it is needed in most cases. */    it is needed in most cases. */
2195    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2196    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2197    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2198    JUMPHERE(jump);    JUMPHERE(jump);
2199  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2200    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2201    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2202    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 2162  if (common->utf) Line 2207  if (common->utf)
2207    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2208    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2209    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2210  #endif  #elif defined COMPILE_PCRE32
2211  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2212      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2213      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2214      JUMPHERE(jump);
2215    #endif /* COMPILE_PCRE[8|16|32] */
2216    return;    return;
2217    }    }
2218  #endif  #endif /* SUPPORT_UTF */
2219  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2220  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));
2221  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2222  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2223  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2224  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2225  #endif  #endif
2226  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2227  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2228  JUMPHERE(jump);  JUMPHERE(jump);
2229  #endif  #endif
2230  }  }
# Line 2184  static void skip_char_back(compiler_comm Line 2233  static void skip_char_back(compiler_comm
2233  {  {
2234  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2235  DEFINE_COMPILER;  DEFINE_COMPILER;
2236  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2237    #if defined COMPILE_PCRE8
2238  struct sljit_label *label;  struct sljit_label *label;
2239    
2240  if (common->utf)  if (common->utf)
# Line 2196  if (common->utf) Line 2246  if (common->utf)
2246    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2247    return;    return;
2248    }    }
2249  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2250  if (common->utf)  if (common->utf)
2251    {    {
2252    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 2210  if (common->utf) Line 2259  if (common->utf)
2259    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2260    return;    return;
2261    }    }
2262  #endif  #endif /* COMPILE_PCRE[8|16] */
2263    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2264  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2265  }  }
2266    
# Line 2241  else Line 2291  else
2291    
2292  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2293    
2294  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2295  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2296  {  {
2297  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 2335  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); Line 2385  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2385  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2386  }  }
2387    
2388  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2389    
 #ifdef COMPILE_PCRE16  
2390  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2391  {  {
2392  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 2362  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2411  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2411  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2412  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2413  }  }
 #endif /* COMPILE_PCRE16 */  
2414    
2415  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2416    
2417  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2418    
# Line 2419  if (firstline) Line 2467  if (firstline)
2467    {    {
2468    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2469    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2470    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);  
2471    
2472    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2473      {      {
# Line 2431  if (firstline) Line 2478  if (firstline)
2478      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2479      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);
2480      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);
2481        JUMPHERE(end);
2482      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));
2483      }      }
2484    else    else
# Line 2442  if (firstline) Line 2490  if (firstline)
2490      read_char(common);      read_char(common);
2491      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2492      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2493        JUMPHERE(end);
2494      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);
2495      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2496      }      }
2497    
2498    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2499    }    }
2500    
2501  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2460  if (newlinecheck) Line 2508  if (newlinecheck)
2508    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2509    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2510    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2511  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2512    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2513  #endif  #endif
2514    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2515    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2482  if (newlinecheck) Line 2530  if (newlinecheck)
2530    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2531    
2532  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));
2533  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2534    #if defined COMPILE_PCRE8
2535  if (common->utf)  if (common->utf)
2536    {    {
2537    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
# Line 2490  if (common->utf) Line 2539  if (common->utf)
2539    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2540    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2541    }    }
2542  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2543  if (common->utf)  if (common->utf)
2544    {    {
2545    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
# Line 2502  if (common->utf) Line 2550  if (common->utf)
2550    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2551    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2552    }    }
2553  #endif  #endif /* COMPILE_PCRE[8|16] */
2554    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2555  JUMPHERE(start);  JUMPHERE(start);
2556    
2557  if (newlinecheck)  if (newlinecheck)
# Line 2514  if (newlinecheck) Line 2563  if (newlinecheck)
2563  return mainloop;  return mainloop;
2564  }  }
2565    
2566  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2567    
2568    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2569  {  {
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571  struct sljit_label *start;  struct sljit_label *start;
2572  struct sljit_jump *quit;  struct sljit_jump *quit;
2573  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
 pcre_int32 chars[4];  
2574  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2575  int location = 0;  int location = 0;
2576  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2577  BOOL must_end;  int must_stop;
   
 #ifdef COMPILE_PCRE8  
 union {  
     sljit_uh ascombined;  
     sljit_ub asuchars[2];  
 } pair;  
 #else  
 union {  
     sljit_ui ascombined;  
     sljit_uh asuchars[2];  
 } pair;  
 #endif  
2578    
2579    /* We do not support alternatives now. */
2580  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2581    return FALSE;    return FALSE;
2582    
2583  while (TRUE)  while (TRUE)
2584    {    {
2585    caseless = 0;    caseless = 0;
2586    must_end = TRUE;    must_stop = 1;
2587    switch(*cc)    switch(*cc)
2588      {      {
2589      case OP_CHAR:      case OP_CHAR:
2590      must_end = FALSE;      must_stop = 0;
2591      cc++;      cc++;
2592      break;      break;
2593    
2594      case OP_CHARI:      case OP_CHARI:
2595      caseless = 1;      caseless = 1;
2596      must_end = FALSE;      must_stop = 0;
2597      cc++;      cc++;
2598      break;      break;
2599    
# Line 2596  while (TRUE) Line 2635  while (TRUE)
2635      break;      break;
2636    
2637      default:      default:
2638      return FALSE;      must_stop = 2;
2639        break;
2640      }      }
2641    
2642      if (must_stop == 2)
2643          break;
2644    
2645    len = 1;    len = 1;
2646  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2647    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2648  #endif  #endif
2649    
# Line 2621  while (TRUE) Line 2664  while (TRUE)
2664    else    else
2665      caseless = 0;      caseless = 0;
2666    
2667    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
2668      {      {
2669      c = *cc;      c = *cc;
2670      bit = 0;      bit = 0;
# Line 2639  while (TRUE) Line 2682  while (TRUE)
2682      cc++;      cc++;
2683      }      }
2684    
2685    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2686      break;      break;
   else if (must_end)  
     return FALSE;  
2687    }    }
2688    
2689    /* At least two characters are required. */
2690    if (location < 2 * 2)
2691        return FALSE;
2692    
2693  if (firstline)  if (firstline)
2694    {    {
2695    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2696    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2697      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2698    }    }
2699  else  else
2700    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2701    
2702  start = LABEL();  start = LABEL();
2703  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  
 #ifdef COMPILE_PCRE8  
 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #else /* COMPILE_PCRE8 */  
 OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #endif  
2704    
2705  #else /* SLJIT_UNALIGNED */  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
   
 #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 #else /* SLJIT_BIG_ENDIAN */  
2706  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2707  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2708  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
2709      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2710  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2711  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
2712  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2713  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
2714  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2715  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2716    if (location > 2 * 2)
2717  #endif    {
2718      if (chars[5] != 0)
2719  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2720    {    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
   pair.asuchars[0] = chars[1];  
   pair.asuchars[1] = chars[3];  
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);  
2721    }    }
2722    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2723    
 pair.asuchars[0] = chars[0];  
 pair.asuchars[1] = chars[2];  
 found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);  
   
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 JUMPTO(SLJIT_JUMP, start);  
 JUMPHERE(found);  
2724  JUMPHERE(quit);  JUMPHERE(quit);
2725    
2726  if (firstline)  if (firstline)
2727    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2728  OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);  else
2729      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2730  return TRUE;  return TRUE;
2731  }  }
2732    
2733    #undef MAX_N_CHARS
2734    
2735  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2736  {  {
2737  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2713  pcre_uchar oc, bit; Line 2742  pcre_uchar oc, bit;
2742    
2743  if (firstline)  if (firstline)
2744    {    {
2745    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2746      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2747    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);
2748    }    }
2749    
# Line 2735  if (first_char == oc) Line 2765  if (first_char == oc)
2765  else  else
2766    {    {
2767    bit = first_char ^ oc;    bit = first_char ^ oc;
2768    if (ispowerof2(bit))    if (is_powerof2(bit))
2769      {      {
2770      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2771      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2756  JUMPHERE(found); Line 2786  JUMPHERE(found);
2786  JUMPHERE(quit);  JUMPHERE(quit);
2787    
2788  if (firstline)  if (firstline)
2789    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2790  }  }
2791    
2792  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 2772  jump_list *newline = NULL; Line 2802  jump_list *newline = NULL;
2802    
2803  if (firstline)  if (firstline)
2804    {    {
2805    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2806      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2807    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);
2808    }    }
2809    
# Line 2787  if (common->nltype == NLTYPE_FIXED && co Line 2818  if (common->nltype == NLTYPE_FIXED && co
2818    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2819    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2820    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2821  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2822    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2823  #endif  #endif
2824    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2825    
# Line 2830  if (common->nltype == NLTYPE_ANY || comm Line 2861  if (common->nltype == NLTYPE_ANY || comm
2861    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2862    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2863    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2864  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2865    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2866  #endif  #endif
2867    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2868    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
# Line 2841  JUMPHERE(lastchar); Line 2872  JUMPHERE(lastchar);
2872  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2873    
2874  if (firstline)  if (firstline)
2875    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2876  }  }
2877    
2878  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)
# Line 2856  struct sljit_jump *jump; Line 2887  struct sljit_jump *jump;
2887    
2888  if (firstline)  if (firstline)
2889    {    {
2890    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2891      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2892    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2893    }    }
2894    
# Line 2884  if (common->utf) Line 2916  if (common->utf)
2916    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2917  #endif  #endif
2918  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));
2919  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2920    #if defined COMPILE_PCRE8
2921  if (common->utf)  if (common->utf)
2922    {    {
2923    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2924    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2925    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2926    }    }
2927  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2928  if (common->utf)  if (common->utf)
2929    {    {
2930    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2902  if (common->utf) Line 2934  if (common->utf)
2934    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2935    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2936    }    }
2937  #endif  #endif /* COMPILE_PCRE[8|16] */
2938    #endif /* SUPPORT_UTF */
2939  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2940  JUMPHERE(found);  JUMPHERE(found);
2941  JUMPHERE(quit);  JUMPHERE(quit);
2942    
2943  if (firstline)  if (firstline)
2944    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2945  }  }
2946    
2947  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 2920  struct sljit_jump *alreadyfound; Line 2953  struct sljit_jump *alreadyfound;
2953  struct sljit_jump *found;  struct sljit_jump *found;
2954  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2955  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2956  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2957    
2958  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2959  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2951  if (req_char == oc) Line 2984  if (req_char == oc)
2984  else  else
2985    {    {
2986    bit = req_char ^ oc;    bit = req_char ^ oc;
2987    if (ispowerof2(bit))    if (is_powerof2(bit))
2988      {      {
2989      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2990      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 3181  switch(ranges[0]) Line 3214  switch(ranges[0])
3214        }        }
3215      return TRUE;      return TRUE;
3216      }      }
3217      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3218        {
3219        if (readch)
3220          read_char(common);
3221        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3222        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3223        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3224        return TRUE;
3225        }
3226    return FALSE;    return FALSE;
3227    
3228    default:    default:
# Line 3194  int i, bit, length; Line 3236  int i, bit, length;
3236  const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;  const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3237    
3238  bit = ctypes[0] & flag;  bit = ctypes[0] & flag;
3239    ranges[0] = -1;
3240  ranges[1] = bit != 0 ? 1 : 0;  ranges[1] = bit != 0 ? 1 : 0;
3241  length = 0;  length = 0;
3242    
# Line 3201  for (i = 1; i < 256; i++) Line 3244  for (i = 1; i < 256; i++)
3244    if ((ctypes[i] & flag) != bit)    if ((ctypes[i] & flag) != bit)
3245      {      {
3246      if (length >= MAX_RANGE_SIZE)      if (length >= MAX_RANGE_SIZE)
       {  
       ranges[0] = -1;  
3247        return;        return;
       }  
3248      ranges[2 + length] = i;      ranges[2 + length] = i;
3249      length++;      length++;
3250      bit ^= flag;      bit ^= flag;
# Line 3213  for (i = 1; i < 256; i++) Line 3253  for (i = 1; i < 256; i++)
3253  if (bit != 0)  if (bit != 0)
3254    {    {
3255    if (length >= MAX_RANGE_SIZE)    if (length >= MAX_RANGE_SIZE)
     {  
     ranges[0] = -1;  
3256      return;      return;
     }  
3257    ranges[2 + length] = 256;    ranges[2 + length] = 256;
3258    length++;    length++;
3259    }    }
# Line 3278  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3315  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3315  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3316  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3317  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3318  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3319  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3320  if (common->utf)  if (common->utf)
3321    {    {
# Line 3289  if (common->utf) Line 3326  if (common->utf)
3326  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3327    }    }
3328  #endif  #endif
3329  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3330  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3331  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3332  }  }
# Line 3306  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 3343  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
3343  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3344  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3345  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3346  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3347  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3348  if (common->utf)  if (common->utf)
3349    {    {
# Line 3327  if (common->utf) Line 3364  if (common->utf)
3364  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3365    }    }
3366  #endif  #endif
3367  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3368  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3369    
3370  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3344  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3381  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3381  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3382  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3383  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3384  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3385  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3386  if (common->utf)  if (common->utf)
3387    {    {
# Line 3355  if (common->utf) Line 3392  if (common->utf)
3392  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3393    }    }
3394  #endif  #endif
3395  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3396  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3397    
3398  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3445  sljit_emit_fast_return(compiler, RETURN_ Line 3482  sljit_emit_fast_return(compiler, RETURN_
3482  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3483  {  {
3484  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3485  int c1, c2;  pcre_uint32 c1, c2;
3486  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3487  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3488    const ucd_record *ur;
3489    const pcre_uint32 *pp;
3490    
3491  while (src1 < end1)  while (src1 < end1)
3492    {    {
# Line 3455  while (src1 < end1) Line 3494  while (src1 < end1)
3494      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3495    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3496    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3497    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3498      if (c1 != c2 && c1 != c2 + ur->other_case)
3499        {
3500        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3501        for (;;)
3502          {
3503          if (c1 < *pp) return NULL;
3504          if (c1 == *pp++) break;
3505          }
3506        }
3507    }    }
3508  return src2;  return src2;
3509  }  }
# Line 3477  if (caseless && char_has_othercase(commo Line 3525  if (caseless && char_has_othercase(commo
3525    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3526    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3527    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3528  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3529    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3530    othercasebit &= 0xff;    othercasebit &= 0xff;
3531  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
 #ifdef COMPILE_PCRE16  
3532    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3533    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3534      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3535    else    else
3536      othercasebit &= 0xff;      othercasebit &= 0xff;
3537  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3538    }    }
3539    
3540  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3541    {    {
3542  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3543  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3544    if (context->length >= 4)    if (context->length >= 4)
3545      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 3502  if (context->sourcereg == -1) Line 3548  if (context->sourcereg == -1)
3548    else    else
3549  #endif  #endif
3550      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3551  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3552  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3553    if (context->length >= 4)    if (context->length >= 4)
3554      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3555    else    else
3556  #endif  #endif
3557      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3558  #endif  #elif defined COMPILE_PCRE32
3559  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3560    #endif /* COMPILE_PCRE[8|16|32] */
3561    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3562    }    }
3563    
3564  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3565  utflength = 1;  utflength = 1;
3566    #ifndef COMPILE_PCRE32
3567  if (common->utf && HAS_EXTRALEN(*cc))  if (common->utf && HAS_EXTRALEN(*cc))
3568    utflength += GET_EXTRALEN(*cc);    utflength += GET_EXTRALEN(*cc);
3569    #endif
3570    
3571  do  do
3572    {    {
# Line 3540  do Line 3588  do
3588      }      }
3589    context->ucharptr++;    context->ucharptr++;
3590    
3591  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3592    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3593  #else  #elif defined COMPILE_PCRE16
3594    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3595    #elif defined COMPILE_PCRE32
3596      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3597  #endif  #endif
3598      {      {
3599    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3600      if (context->length >= 4)      if (context->length >= 4)
3601        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3602  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3603      else if (context->length >= 2)      else if (context->length >= 2)
3604        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3605      else if (context->length >= 1)      else if (context->length >= 1)
3606        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3607  #else  #elif defined COMPILE_PCRE16
3608      else if (context->length >= 2)      else if (context->length >= 2)
3609        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3610  #endif  #endif /* COMPILE_PCRE[8|16] */
3611    #elif defined COMPILE_PCRE32
3612        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3613    #endif /* COMPILE_PCRE[8|16|32] */
3614      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3615    
3616      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3567  do Line 3621  do
3621        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3622        break;        break;
3623    
3624    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3625        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3626        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3627          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 3581  do Line 3636  do
3636        break;        break;
3637  #endif  #endif
3638    
3639    #endif /* COMPILE_PCRE[8|16] */
3640    
3641        default:        default:
3642        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3643        break;        break;
# Line 3591  do Line 3648  do
3648  #else  #else
3649    
3650    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
3651    if (context->length > 0)    if (context->length > 0)
3652      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3653  #else  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3654    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3655    
3656    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3642  return cc; Line 3695  return cc;
3695      } \      } \
3696    charoffset = (value);    charoffset = (value);
3697    
3698  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)
3699  {  {
3700  DEFINE_COMPILER;  DEFINE_COMPILER;
3701  jump_list *found = NULL;  jump_list *found = NULL;
3702  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3703  unsigned int c;  pcre_int32 c, charoffset;
3704  int compares;  const pcre_uint32 *other_cases;
3705  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3706  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3707    int compares, invertcmp, numberofcmps;
3708  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3709  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3710  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3711  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3712  unsigned int typeoffset;  pcre_int32 typeoffset;
3713  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3714    
3715  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3716     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3707  while (*cc != XCL_END) Line 3759  while (*cc != XCL_END)
3759    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3760      {      {
3761      cc += 2;      cc += 2;
3762  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3763      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3764  #endif  #endif
3765  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 3717  while (*cc != XCL_END) Line 3769  while (*cc != XCL_END)
3769    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3770      {      {
3771      cc += 2;      cc += 2;
3772  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3773      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3774  #endif  #endif
3775      cc++;      cc++;
3776  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3777      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3778  #endif  #endif
3779  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 3756  while (*cc != XCL_END) Line 3808  while (*cc != XCL_END)
3808        needschar = TRUE;        needschar = TRUE;
3809        break;        break;
3810    
3811          case PT_CLIST:
3812          needschar = TRUE;
3813          break;
3814    
3815        default:        default:
3816        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3817        break;        break;
# Line 3965  while (*cc != XCL_END) Line 4021  while (*cc != XCL_END)
4021        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4022        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4023        break;        break;
4024    
4025          case PT_CLIST:
4026          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4027    
4028          /* At least three characters are required.
4029             Otherwise this case would be handled by the normal code path. */
4030          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4031          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4032    
4033          /* Optimizing character pairs, if their difference is power of 2. */
4034          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4035            {
4036            if (charoffset == 0)
4037              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4038            else
4039              {
4040              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4041              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4042              }
4043            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4044            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4045            other_cases += 2;
4046            }
4047          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4048            {
4049            if (charoffset == 0)
4050              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4051            else
4052              {
4053              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4054              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4055              }
4056            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4057            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4058    
4059            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4060            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4061    
4062            other_cases += 3;
4063            }
4064          else
4065            {
4066            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4067            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4068            }
4069    
4070          while (*other_cases != NOTACHAR)
4071            {
4072            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4073            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4074            }
4075          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4076          break;
4077        }        }
4078      cc += 2;      cc += 2;
4079      }      }
# Line 3983  if (found != NULL) Line 4092  if (found != NULL)
4092    
4093  #endif  #endif
4094    
4095  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)
4096  {  {
4097  DEFINE_COMPILER;  DEFINE_COMPILER;
4098  int length;  int length;
# Line 4080  switch(type) Line 4189  switch(type)
4189      {      {
4190      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4191      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));
4192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4193    #if defined COMPILE_PCRE8
4194      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4195      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4196      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4197  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4198      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4199      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4200      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4201      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4202      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4203      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4204  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4205      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4206    #endif /* COMPILE_PCRE[8|16] */
4207      return cc;      return cc;
4208      }      }
4209  #endif  #endif
# Line 4115  switch(type) Line 4224  switch(type)
4224    propdata[2] = cc[0];    propdata[2] = cc[0];
4225    propdata[3] = cc[1];    propdata[3] = cc[1];
4226    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4227    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4228    return cc + 2;    return cc + 2;
4229  #endif  #endif
4230  #endif  #endif
# Line 4161  switch(type) Line 4270  switch(type)
4270    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4271    read_char(common);    read_char(common);
4272    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4273    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));
4274    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4275      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4276      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4277    
4278    label = LABEL();    label = LABEL();
4279    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);
4280    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4281    read_char(common);    read_char(common);
4282    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4283    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));
4284    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);
4285    
4286      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4287      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4288      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4289      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4290      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4291      JUMPTO(SLJIT_C_NOT_ZERO, label);
4292    
4293    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4294    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4295      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4296    
4297    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4298      {      {
4299      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 4299  switch(type) Line 4419  switch(type)
4419    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));
4420    
4421    if (!common->endonly)    if (!common->endonly)
4422      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4423    else    else
4424      {      {
4425      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 4347  switch(type) Line 4467  switch(type)
4467    case OP_CHAR:    case OP_CHAR:
4468    case OP_CHARI:    case OP_CHARI:
4469    length = 1;    length = 1;
4470  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4471    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
4472  #endif  #endif
4473    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
# Line 4379  switch(type) Line 4499  switch(type)
4499      }      }
4500    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4501    bit = c ^ oc;    bit = c ^ oc;
4502    if (ispowerof2(bit))    if (is_powerof2(bit))
4503      {      {
4504      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4505      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4387  switch(type) Line 4507  switch(type)
4507      }      }
4508    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);
4509    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4510    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);
4511    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4512    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4513    return cc + length;    return cc + length;
# Line 4440  switch(type) Line 4560  switch(type)
4560      {      {
4561      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4562      bit = c ^ oc;      bit = c ^ oc;
4563      if (ispowerof2(bit))      if (is_powerof2(bit))
4564        {        {
4565        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4566        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4488  switch(type) Line 4608  switch(type)
4608  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4609    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4610    
4611  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4612    case OP_XCLASS:    case OP_XCLASS:
4613    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4614    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4615  #endif  #endif
4616    
# Line 4524  SLJIT_ASSERT_STOP(); Line 4644  SLJIT_ASSERT_STOP();
4644  return cc;  return cc;
4645  }  }
4646    
4647  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)
4648  {  {
4649  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4650  /* 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 4542  do Line 4662  do
4662    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
4663      {      {
4664      size = 1;      size = 1;
4665  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4666      if (common->utf && HAS_EXTRALEN(cc[1]))      if (common->utf && HAS_EXTRALEN(cc[1]))
4667        size += GET_EXTRALEN(cc[1]);        size += GET_EXTRALEN(cc[1]);
4668  #endif  #endif
# Line 4555  do Line 4675  do
4675        {        {
4676        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
4677          size = 0;          size = 0;
4678    #ifndef COMPILE_PCRE32
4679        else if (HAS_EXTRALEN(cc[1]))        else if (HAS_EXTRALEN(cc[1]))
4680          size += GET_EXTRALEN(cc[1]);          size += GET_EXTRALEN(cc[1]);
4681    #endif
4682        }        }
4683      else      else
4684  #endif  #endif
# Line 4587  if (context.length > 0) Line 4709  if (context.length > 0)
4709    }    }
4710    
4711  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4712  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4713  }  }
4714    
4715  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 4613  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4735  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4735  }  }
4736    
4737  /* Forward definitions. */  /* Forward definitions. */
4738  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4739  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4740    
4741  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4742    do \    do \
# Line 4644  static void compile_backtrackpath(compil Line 4766  static void compile_backtrackpath(compil
4766    
4767  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4768    
4769  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)
4770  {  {
4771  DEFINE_COMPILER;  DEFINE_COMPILER;
4772  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 4726  if (jump != NULL) Line 4848  if (jump != NULL)
4848  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4849  }  }
4850    
4851  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)
4852  {  {
4853  DEFINE_COMPILER;  DEFINE_COMPILER;
4854  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4797  if (!minimize) Line 4919  if (!minimize)
4919      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4920    
4921    label = LABEL();    label = LABEL();
4922    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4923    
4924    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4925      {      {
# Line 4825  if (!minimize) Line 4947  if (!minimize)
4947      }      }
4948    
4949    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4950    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4951    
4952    decrease_call_count(common);    decrease_call_count(common);
4953    return cc;    return cc;
# Line 4845  if (min == 0) Line 4967  if (min == 0)
4967  else  else
4968    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4969    
4970  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4971  if (max > 0)  if (max > 0)
4972    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));
4973    
4974  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4975  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4976    
4977  if (min > 1)  if (min > 1)
# Line 4857  if (min > 1) Line 4979  if (min > 1)
4979    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4980    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4981    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4982    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);
4983    }    }
4984  else if (max > 0)  else if (max > 0)
4985    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 4870  decrease_call_count(common); Line 4992  decrease_call_count(common);
4992  return cc;  return cc;
4993  }  }
4994    
4995  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)
4996  {  {
4997  DEFINE_COMPILER;  DEFINE_COMPILER;
4998  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4927  add_jump(compiler, &backtrack->topbacktr Line 5049  add_jump(compiler, &backtrack->topbacktr
5049  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5050  }  }
5051    
5052  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)
5053  {  {
5054  DEFINE_COMPILER;  DEFINE_COMPILER;
5055  int framesize;  int framesize;
5056  int localptr;  int private_data_ptr;
5057  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5058  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5059  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4953  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5075  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5075    bra = *cc;    bra = *cc;
5076    cc++;    cc++;
5077    }    }
5078  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5079  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5080  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5081  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5082  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5083  opcode = *cc;  opcode = *cc;
5084  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5085  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4974  if (bra == OP_BRAMINZERO) Line 5096  if (bra == OP_BRAMINZERO)
5096    
5097  if (framesize < 0)  if (framesize < 0)
5098    {    {
5099    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);
5100    allocate_stack(common, 1);    allocate_stack(common, 1);
5101    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5102    }    }
5103  else  else
5104    {    {
5105    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5106    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5107    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));
5108    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5109    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5110    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5111    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
# Line 5003  while (1) Line 5125  while (1)
5125      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5126    
5127    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5128    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5129    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5130      {      {
5131      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5018  while (1) Line 5140  while (1)
5140    
5141    /* Reset stack. */    /* Reset stack. */
5142    if (framesize < 0)    if (framesize < 0)
5143      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);
5144    else {    else {
5145      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5146        {        {
5147        /* 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. */
5148        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));
5149        }        }
5150      else      else
5151        {        {
5152        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);
5153        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5154        }        }
5155    }    }
# Line 5045  while (1) Line 5167  while (1)
5167          {          {
5168          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));
5169          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));
5170          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5171          }          }
5172        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));
5173        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 5053  while (1) Line 5175  while (1)
5175      else if (framesize >= 0)      else if (framesize >= 0)
5176        {        {
5177        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5178        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));
5179        }        }
5180      }      }
5181    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5182    
5183    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5184    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5185      {      {
5186      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5104  if (opcode == OP_ASSERT || opcode == OP_ Line 5226  if (opcode == OP_ASSERT || opcode == OP_
5226        }        }
5227      else      else
5228        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5229      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5230      }      }
5231    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5232    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 5129  if (opcode == OP_ASSERT || opcode == OP_ Line 5251  if (opcode == OP_ASSERT || opcode == OP_
5251      {      {
5252      if (bra == OP_BRA)      if (bra == OP_BRA)
5253        {        {
5254        /* 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. */
5255        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));
5256        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5257        }        }
5258      else      else
5259        {        {
5260        /* 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. */
5261        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));
5262        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5263        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);
5264        }        }
# Line 5144  if (opcode == OP_ASSERT || opcode == OP_ Line 5266  if (opcode == OP_ASSERT || opcode == OP_
5266    
5267    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5268      {      {
5269      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5270      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5271      }      }
5272    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5273      {      {
5274      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5275      JUMPHERE(brajump);      JUMPHERE(brajump);
5276      if (framesize >= 0)      if (framesize >= 0)
5277        {        {
5278        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);
5279        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5280        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));
5281        }        }
5282      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5283      }      }
# Line 5183  else Line 5305  else
5305        }        }
5306      else      else
5307        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5308      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5309      }      }
5310    
5311    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5312      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5313    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5314      {      {
5315      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5316      JUMPHERE(brajump);      JUMPHERE(brajump);
5317      }      }
5318    
# Line 5373  return condition; Line 5495  return condition;
5495                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5496  */  */
5497    
5498  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)
5499  {  {
5500  DEFINE_COMPILER;  DEFINE_COMPILER;
5501  backtrack_common *backtrack;  backtrack_common *backtrack;
5502  pcre_uchar opcode;  pcre_uchar opcode;
5503  int localptr = 0;  int private_data_ptr = 0;
5504  int offset = 0;  int offset = 0;
5505  int stacksize;  int stacksize;
5506  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5507  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5508  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5509  pcre_uchar ket;  pcre_uchar ket;
5510  assert_backtrack *assert;  assert_backtrack *assert;
# Line 5403  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5525  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5525    
5526  opcode = *cc;  opcode = *cc;
5527  ccbegin = cc;  ccbegin = cc;
5528  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5529    
5530  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)
5531    {    {
# Line 5420  cc += GET(cc, 1); Line 5542  cc += GET(cc, 1);
5542  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5543  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5544    {    {
5545    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5546    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5547      {      {
5548      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5549      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5550        has_alternatives = FALSE;        has_alternatives = FALSE;
5551      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 5442  if (opcode == OP_CBRA || opcode == OP_SC Line 5564  if (opcode == OP_CBRA || opcode == OP_SC
5564    {    {
5565    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5566    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5567    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5568    offset <<= 1;      {
5569    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5570    trypath += IMM2_SIZE;      offset <<= 1;
5571        }
5572      else
5573        {
5574        offset <<= 1;
5575        private_data_ptr = OVECTOR(offset);
5576        }
5577      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5578      matchingpath += IMM2_SIZE;
5579    }    }
5580  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5581    {    {
5582    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5583    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5584    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5585    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5586    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5587      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5588    }    }
# Line 5498  if (bra == OP_BRAMINZERO) Line 5628  if (bra == OP_BRAMINZERO)
5628        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5629        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5630          {          {
5631          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5632          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);
5633          }          }
5634        else        else
5635          {          {
5636          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5637          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5638          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));
5639          }          }
5640        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5519  if (bra == OP_BRAMINZERO) Line 5649  if (bra == OP_BRAMINZERO)
5649    }    }
5650    
5651  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5652    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5653    
5654  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5655    {    {
5656    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5657    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5658      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5659    }    }
5660    
5661  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 5536  if (opcode == OP_ONCE) Line 5666  if (opcode == OP_ONCE)
5666      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5667      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5668        {        {
5669        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5670        allocate_stack(common, 2);        allocate_stack(common, 2);
5671        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5672        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5673        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));
5674        }        }
5675      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5676        {        {
5677        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);
5678        allocate_stack(common, 1);        allocate_stack(common, 1);
5679        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5680        }        }
5681      else      else
5682        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);
5683      }      }
5684    else    else
5685      {      {
5686      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5687        {        {
5688        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5689        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5690        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));
5691        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5692        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5693        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5694        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);
5695        }        }
5696      else      else
5697        {        {
5698        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5699        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5700        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));
5701        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5702        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5703        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5704        }        }
# Line 5577  if (opcode == OP_ONCE) Line 5707  if (opcode == OP_ONCE)
5707  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5708    {    {
5709    /* Saving the previous values. */    /* Saving the previous values. */
5710    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5711    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5712    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5713    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5714    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5715    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5716    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);
5717    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5718        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5719        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5720        }
5721      else
5722        {
5723        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5724        allocate_stack(common, 2);
5725        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5726        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5727        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5728        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5729        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5730        }
5731    }    }
5732  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5733    {    {
5734    /* Saving the previous value. */    /* Saving the previous value. */
5735    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5736    allocate_stack(common, 1);    allocate_stack(common, 1);
5737    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);
5738    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5739    }    }
5740  else if (has_alternatives)  else if (has_alternatives)
# Line 5604  else if (has_alternatives) Line 5747  else if (has_alternatives)
5747  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5748  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5749    {    {
5750    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5751      {      {
5752      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5753      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5754        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)));
5755      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5756      }      }
5757    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5758      {      {
5759      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5760      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5761      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));
5762    
5763      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 5628  if (opcode == OP_COND || opcode == OP_SC Line 5771  if (opcode == OP_COND || opcode == OP_SC
5771      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));
5772    
5773      JUMPHERE(jump);      JUMPHERE(jump);
5774      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5775      }      }
5776    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5777      {      {
5778      /* Never has other case. */      /* Never has other case. */
5779      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5780    
5781      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5782      if (common->currententry == NULL)      if (common->currententry == NULL)
5783        stacksize = 0;        stacksize = 0;
5784      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 5645  if (opcode == OP_COND || opcode == OP_SC Line 5788  if (opcode == OP_COND || opcode == OP_SC
5788      else      else
5789        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5790    
5791      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5792        {        {
5793        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5794        if (stacksize != 0)        if (stacksize != 0)
5795          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5796        else        else
5797          {          {
5798          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5799            {            {
5800            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5801            cc += GET(cc, 1);            cc += GET(cc, 1);
5802            }            }
5803          else          else
5804            trypath = cc;            matchingpath = cc;
5805          }          }
5806        }        }
5807      else      else
5808        {        {
5809        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5810    
5811        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5812        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5813        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);
5814        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 5676  if (opcode == OP_COND || opcode == OP_SC Line 5819  if (opcode == OP_COND || opcode == OP_SC
5819        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));
5820        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5821        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));
5822        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5823        }        }
5824      }      }
5825    else    else
5826      {      {
5827      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5828      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5829      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5830      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5831        return NULL;        return NULL;
5832      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5833      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5834      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5835      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5836      }      }
5837    }    }
5838    
5839  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5840  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5841    return NULL;    return NULL;
5842    
# Line 5701  if (opcode == OP_ONCE) Line 5844  if (opcode == OP_ONCE)
5844    {    {
5845    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5846      {      {
5847      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);
5848      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5849      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5850        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5851      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5852        {        {
5853        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5854        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);
5855        }        }
5856      }      }
5857    else    else
5858      {      {
5859      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5860      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));
5861      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5862        {        {
5863        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5749  if (has_alternatives) Line 5892  if (has_alternatives)
5892    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5893      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5894    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5895      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5896    }    }
5897    
5898  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5899  if (offset != 0)  if (offset != 0)
5900    {    {
5901    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5902    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);
5903    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);
5904    }    }
# Line 5765  if (ket == OP_KETRMAX) Line 5908  if (ket == OP_KETRMAX)
5908    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5909      {      {
5910      if (has_alternatives)      if (has_alternatives)
5911        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5912      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5913      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5914        {        {
5915        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5916        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5917        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5918          free_stack(common, 1);          free_stack(common, 1);
# Line 5780  if (ket == OP_KETRMAX) Line 5923  if (ket == OP_KETRMAX)
5923      }      }
5924    else    else
5925      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5926    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5927    }    }
5928    
5929  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5930    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5931    
5932  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5933    {    {
5934    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5935    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5936    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5937      {      {
5938      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5798  if (bra == OP_BRAMINZERO) Line 5941  if (bra == OP_BRAMINZERO)
5941      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5942      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5943        {        {
5944        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);
5945        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5946        }        }
5947      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5817  cc += 1 + LINK_SIZE; Line 5960  cc += 1 + LINK_SIZE;
5960  return cc;  return cc;
5961  }  }
5962    
5963  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)
5964  {  {
5965  DEFINE_COMPILER;  DEFINE_COMPILER;
5966  backtrack_common *backtrack;  backtrack_common *backtrack;
5967  pcre_uchar opcode;  pcre_uchar opcode;
5968  int localptr;  int private_data_ptr;
5969  int cbraprivptr = 0;  int cbraprivptr = 0;
5970  int framesize;  int framesize;
5971  int stacksize;  int stacksize;
# Line 5841  if (*cc == OP_BRAPOSZERO) Line 5984  if (*cc == OP_BRAPOSZERO)
5984    }    }
5985    
5986  opcode = *cc;  opcode = *cc;
5987  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5988  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5989  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5990  switch(opcode)  switch(opcode)
5991    {    {
5992    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5854  switch(opcode) Line 5997  switch(opcode)
5997    case OP_CBRAPOS:    case OP_CBRAPOS:
5998    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5999    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
6000      /* This case cannot be optimized in the same was as
6001      normal capturing brackets. */
6002      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
6003    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6004    offset <<= 1;    offset <<= 1;
6005    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5873  if (framesize < 0) Line 6019  if (framesize < 0)
6019      stacksize++;      stacksize++;
6020    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6021    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6022    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);
6023    
6024    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6025      {      {
# Line 5898  else Line 6044  else
6044    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6045    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6046    
6047    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6048    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));
6049    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6050    stack = 0;    stack = 0;
6051    if (!zero)    if (!zero)
6052      {      {
# Line 5926  while (*cc != OP_KETRPOS) Line 6072  while (*cc != OP_KETRPOS)
6072    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6073    cc += GET(cc, 1);    cc += GET(cc, 1);
6074    
6075    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6076    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6077      return NULL;      return NULL;
6078    
6079    if (framesize < 0)    if (framesize < 0)
6080      {      {
6081      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);
6082    
6083      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6084        {        {
# Line 5958  while (*cc != OP_KETRPOS) Line 6104  while (*cc != OP_KETRPOS)
6104      {      {
6105      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6106        {        {
6107        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));
6108        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6109        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);
6110        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 5966  while (*cc != OP_KETRPOS) Line 6112  while (*cc != OP_KETRPOS)
6112        }        }
6113      else      else
6114        {        {
6115        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6116        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));
6117        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6118          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 5987  while (*cc != OP_KETRPOS) Line 6133  while (*cc != OP_KETRPOS)
6133    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6134    flush_stubs(common);    flush_stubs(common);
6135    
6136    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6137    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6138      return NULL;      return NULL;
6139    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 6005  while (*cc != OP_KETRPOS) Line 6151  while (*cc != OP_KETRPOS)
6151        {        {
6152        /* Last alternative. */        /* Last alternative. */
6153        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6154          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6155        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6156        }        }
6157      else      else
6158        {        {
6159        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6160        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));
6161        }        }
6162      }      }
# Line 6025  if (!zero) Line 6171  if (!zero)
6171    {    {
6172    if (framesize < 0)    if (framesize < 0)
6173      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));
6174    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6175      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));
6176    }    }
6177    
# Line 6120  if (*type == 0) Line 6266  if (*type == 0)
6266  if (end != NULL)  if (end != NULL)
6267    {    {
6268    *end = cc + 1;    *end = cc + 1;
6269  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
6270    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
6271  #endif  #endif
6272    }    }
6273  return cc;  return cc;
6274  }  }
6275    
6276  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)
6277  {  {
6278  DEFINE_COMPILER;  DEFINE_COMPILER;
6279  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6138  pcre_uchar* end; Line 6284  pcre_uchar* end;
6284  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6285  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6286  struct sljit_label *label;  struct sljit_label *label;
6287  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6288  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6289  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6290  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6291  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6292    
6293  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6195  switch(opcode) Line 6341  switch(opcode)
6341    case OP_CRRANGE:    case OP_CRRANGE:
6342    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6343      {      {
6344      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6345      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6346        {        {
6347        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6212  switch(opcode) Line 6358  switch(opcode)
6358        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6359    
6360      label = LABEL();      label = LABEL();
6361      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6362      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6363        {        {
6364        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 6234  switch(opcode) Line 6380  switch(opcode)
6380    else    else
6381      {      {
6382      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6383        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6384      if (localptr == 0)      if (private_data_ptr == 0)
6385        allocate_stack(common, 2);        allocate_stack(common, 2);
6386      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6387      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6243  switch(opcode) Line 6389  switch(opcode)
6389      else      else
6390        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6391      label = LABEL();      label = LABEL();
6392      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6393      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6394      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
6395        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6264  switch(opcode) Line 6410  switch(opcode)
6410        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6411      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6412      }      }
6413    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6414    break;    break;
6415    
6416    case OP_MINSTAR:    case OP_MINSTAR:
6417    case OP_MINPLUS:    case OP_MINPLUS:
6418    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6419      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6420    if (localptr == 0)    if (private_data_ptr == 0)
6421      allocate_stack(common, 1);      allocate_stack(common, 1);
6422    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6423    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6424    break;    break;
6425    
6426    case OP_MINUPTO:    case OP_MINUPTO:
6427    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6428    if (localptr == 0)    if (private_data_ptr == 0)
6429      allocate_stack(common, 2);      allocate_stack(common, 2);
6430    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6431    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6432    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6433      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6434    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6435    break;    break;
6436    
6437    case OP_QUERY:    case OP_QUERY:
6438    case OP_MINQUERY:    case OP_MINQUERY:
6439    if (localptr == 0)    if (private_data_ptr == 0)
6440      allocate_stack(common, 1);      allocate_stack(common, 1);
6441    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6442    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6443      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6444    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6445    break;    break;
6446    
6447    case OP_EXACT:    case OP_EXACT:
6448    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6449    label = LABEL();    label = LABEL();
6450    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6451    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6452    JUMPTO(SLJIT_C_NOT_ZERO, label);    JUMPTO(SLJIT_C_NOT_ZERO, label);
6453    break;    break;
# Line 6310  switch(opcode) Line 6456  switch(opcode)
6456    case OP_POSPLUS:    case OP_POSPLUS:
6457    case OP_POSUPTO:    case OP_POSUPTO:
6458    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
6459      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6460    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
6461      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6462    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6463    label = LABEL();    label = LABEL();
6464    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6465    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6466    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
6467      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6330  switch(opcode) Line 6476  switch(opcode)
6476    
6477    case OP_POSQUERY:    case OP_POSQUERY:
6478    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6479    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6480    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6481    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6482    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
# Line 6345  decrease_call_count(common); Line 6491  decrease_call_count(common);
6491  return end;  return end;
6492  }  }
6493    
6494  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)
6495  {  {
6496  DEFINE_COMPILER;  DEFINE_COMPILER;
6497  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6389  add_jump(compiler, &backtrack->topbacktr Line 6535  add_jump(compiler, &backtrack->topbacktr
6535  return cc + 1;  return cc + 1;
6536  }  }
6537    
6538  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)
6539  {  {
6540  DEFINE_COMPILER;  DEFINE_COMPILER;
6541  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6542    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6543    
6544  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6545  if (common->currententry != NULL)  if (common->currententry != NULL)
6546    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6547    
6548  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6549      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6550  offset <<= 1;  offset <<= 1;
6551  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);
6552  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6553      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6554  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6555  }  }
6556    
6557  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)
6558  {  {
6559  DEFINE_COMPILER;  DEFINE_COMPILER;
6560  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6444  while (cc < ccend) Line 6593  while (cc < ccend)
6593      case OP_NOT:      case OP_NOT:
6594      case OP_NOTI:      case OP_NOTI:
6595      case OP_REVERSE:      case OP_REVERSE:
6596      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);
6597      break;      break;
6598    
6599      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6459  while (cc < ccend) Line 6608  while (cc < ccend)
6608      case OP_CHAR:      case OP_CHAR:
6609      case OP_CHARI:      case OP_CHARI:
6610      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6611        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);
6612      else      else
6613        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);
6614      break;      break;
6615    
6616      case OP_STAR:      case OP_STAR:
# Line 6529  while (cc < ccend) Line 6678  while (cc < ccend)
6678      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6679      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6680      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6681      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6682      break;      break;
6683    
6684      case OP_CLASS:      case OP_CLASS:
6685      case OP_NCLASS:      case OP_NCLASS:
6686      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)
6687        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6688      else      else
6689        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);
6690      break;      break;
6691    
6692  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
6693      case OP_XCLASS:      case OP_XCLASS:
6694      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)
6695        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6696      else      else
6697        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);
6698      break;      break;
6699  #endif  #endif
6700    
6701      case OP_REF:      case OP_REF:
6702      case OP_REFI:      case OP_REFI:
6703      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)
6704        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6705      else      else
6706        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);
6707      break;      break;
6708    
6709      case OP_RECURSE:      case OP_RECURSE:
6710      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6711      break;      break;
6712    
6713      case OP_ASSERT:      case OP_ASSERT:
# Line 6566  while (cc < ccend) Line 6715  while (cc < ccend)
6715      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6716      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6717      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6718      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6719      break;      break;
6720    
6721      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 6583  while (cc < ccend) Line 6732  while (cc < ccend)
6732        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6733        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6734        }        }
6735      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6736      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6737        decrease_call_count(common);        decrease_call_count(common);
6738      break;      break;
# Line 6596  while (cc < ccend) Line 6745  while (cc < ccend)
6745      case OP_SBRA:      case OP_SBRA:
6746      case OP_SCBRA:      case OP_SCBRA:
6747      case OP_SCOND:      case OP_SCOND:
6748      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6749      break;      break;
6750    
6751      case OP_BRAZERO:      case OP_BRAZERO:
6752      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6753        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6754      else      else
6755        {        {
6756        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6757        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6758        }        }
6759      break;      break;
6760    
# Line 6614  while (cc < ccend) Line 6763  while (cc < ccend)
6763      case OP_SBRAPOS:      case OP_SBRAPOS:
6764      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6765      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6766      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6767      break;      break;
6768    
6769      case OP_MARK:      case OP_MARK:
# Line 6638  while (cc < ccend) Line 6787  while (cc < ccend)
6787      case OP_FAIL:      case OP_FAIL:
6788      case OP_ACCEPT:      case OP_ACCEPT:
6789      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6790      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6791      break;      break;
6792    
6793      case OP_CLOSE:      case OP_CLOSE:
6794      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6795      break;      break;
6796    
6797      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 6663  SLJIT_ASSERT(cc == ccend); Line 6812  SLJIT_ASSERT(cc == ccend);
6812  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6813  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6814    
6815  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6816    do \    do \
6817      { \      { \
6818      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6819      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6820        return; \        return; \
6821      } \      } \
# Line 6674  SLJIT_ASSERT(cc == ccend); Line 6823  SLJIT_ASSERT(cc == ccend);
6823    
6824  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6825    
6826  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6827  {  {
6828  DEFINE_COMPILER;  DEFINE_COMPILER;
6829  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6684  int arg1 = -1, arg2 = -1; Line 6833  int arg1 = -1, arg2 = -1;
6833  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6834  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6835  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6836  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6837  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6838  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6839  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6840    
6841  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6842    
# Line 6699  switch(opcode) Line 6848  switch(opcode)
6848    case OP_CRRANGE:    case OP_CRRANGE:
6849    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6850      {      {
6851      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6852      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6853      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6854      free_stack(common, 1);      free_stack(common, 1);
6855      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);
6856      }      }
6857    else    else
6858      {      {
# Line 6723  switch(opcode) Line 6872  switch(opcode)
6872        }        }
6873      skip_char_back(common);      skip_char_back(common);
6874      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6875      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6876      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6877        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6878      JUMPHERE(jump);      JUMPHERE(jump);
6879      if (localptr == 0)      if (private_data_ptr == 0)
6880        free_stack(common, 2);        free_stack(common, 2);
6881      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6882        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6737  switch(opcode) Line 6886  switch(opcode)
6886    case OP_MINSTAR:    case OP_MINSTAR:
6887    case OP_MINPLUS:    case OP_MINPLUS:
6888    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6889    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6890    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6891    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6892    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6893    if (localptr == 0)    if (private_data_ptr == 0)
6894      free_stack(common, 1);      free_stack(common, 1);
6895    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6896      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6755  switch(opcode) Line 6904  switch(opcode)
6904      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6905      }      }
6906    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6907    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6908    
6909    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6910    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6766  switch(opcode) Line 6915  switch(opcode)
6915      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6916    
6917    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6918      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6919    else    else
6920      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);
6921    
6922    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6923    if (localptr == 0)    if (private_data_ptr == 0)
6924      free_stack(common, 2);      free_stack(common, 2);
6925    break;    break;
6926    
6927    case OP_QUERY:    case OP_QUERY:
6928    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6929    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6930    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);
6931    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6932    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6933    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6934    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6935    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6936    JUMPHERE(jump);    JUMPHERE(jump);
6937    if (localptr == 0)    if (private_data_ptr == 0)
6938      free_stack(common, 1);      free_stack(common, 1);
6939    break;    break;
6940    
# Line 6793  switch(opcode) Line 6942  switch(opcode)
6942    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6943    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6944    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6945    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6946    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6947    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6948    JUMPHERE(jump);    JUMPHERE(jump);
6949    if (localptr == 0)    if (private_data_ptr == 0)
6950      free_stack(common, 1);      free_stack(common, 1);
6951    break;    break;
6952    
# Line 6817  switch(opcode) Line 6966  switch(opcode)
6966    }    }
6967  }  }
6968    
6969  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)
6970  {  {
6971  DEFINE_COMPILER;  DEFINE_COMPILER;
6972  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6829  if ((type & 0x1) == 0) Line 6978  if ((type & 0x1) == 0)
6978    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6979    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6980    free_stack(common, 1);    free_stack(common, 1);
6981    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);
6982    return;    return;
6983    }    }
6984    
6985  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6986  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);
6987  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6988  free_stack(common, 2);  free_stack(common, 2);
6989  }  }
6990    
6991  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6992  {  {
6993  DEFINE_COMPILER;  DEFINE_COMPILER;
6994    
# Line 6861  else if (common->has_set_som || common-> Line 7010  else if (common->has_set_som || common->
7010    }    }
7011  }  }
7012    
7013  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7014  {  {
7015  DEFINE_COMPILER;  DEFINE_COMPILER;
7016  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6888  if (CURRENT_AS(assert_backtrack)->frames Line 7037  if (CURRENT_AS(assert_backtrack)->frames
7037    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7038      {      {
7039      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7040      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);
7041      free_stack(common, 1);      free_stack(common, 1);
7042      }      }
7043    return;    return;
# Line 6899  if (bra == OP_BRAZERO) Line 7048  if (bra == OP_BRAZERO)
7048    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
7049      {      {
7050      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7051      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);
7052      free_stack(common, 1);      free_stack(common, 1);
7053      return;      return;
7054      }      }
# Line 6909  if (bra == OP_BRAZERO) Line 7058  if (bra == OP_BRAZERO)
7058    
7059  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7060    {    {
7061    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);
7062    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7063    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));
7064    
7065    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7066    }    }
# Line 6923  if (bra == OP_BRAZERO) Line 7072  if (bra == OP_BRAZERO)
7072    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
7073    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));
7074    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7075    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
7076    JUMPHERE(brajump);    JUMPHERE(brajump);
7077    }    }
7078  }  }
7079    
7080  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7081  {  {
7082  DEFINE_COMPILER;  DEFINE_COMPILER;
7083  int opcode;  int opcode;
7084  int offset = 0;  int offset = 0;
7085  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7086  int stacksize;  int stacksize;
7087  int count;  int count;
7088  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6988  else if (ket == OP_KETRMIN) Line 7137  else if (ket == OP_KETRMIN)
7137        {        {
7138        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7139        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7140          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);
7141        else        else
7142          {          {
7143          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7144          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);
7145          }          }
7146        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7147          free_stack(common, 1);          free_stack(common, 1);
7148        }        }
7149      else      else
7150        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7151      }      }
7152    rminlabel = LABEL();    rminlabel = LABEL();
7153    }    }
# Line 7013  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7162  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7162    {    {
7163    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7164      {      {
7165      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);
7166      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7167      }      }
7168    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 7066  else if (*cc == OP_ALT) Line 7215  else if (*cc == OP_ALT)
7215    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7216    }    }
7217    
7218  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7219  if (current->topbacktracks)  if (current->topbacktracks)
7220    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7221    
# Line 7079  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7228  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7228      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7229      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))
7230        {        {
7231        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);
7232        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7233        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));
7234        }        }
7235      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7236      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
# Line 7110  if (has_alternatives) Line 7259  if (has_alternatives)
7259        cc += GET(cc, 1);        cc += GET(cc, 1);
7260        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7261          {          {
7262          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7263            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);
7264          else          else
7265            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7266          }          }
7267        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7268        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7269          return;          return;
7270        }        }
7271    
7272      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7273      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7274      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7275        {        {
7276        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7277          {          {
7278          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);
7279          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7280          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7281            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7282          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7283            {            {
7284            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7285            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);
7286            }            }
7287          }          }
7288        else        else
7289          {          {
7290          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));
7291          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7292            {            {
7293            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 7179  if (has_alternatives) Line 7328  if (has_alternatives)
7328    
7329      if (offset != 0)      if (offset != 0)
7330        {        {
7331        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7332        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);
7333        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);
7334        }        }
7335    
7336      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7337    
7338      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7339        {        {
# Line 7193  if (has_alternatives) Line 7342  if (has_alternatives)
7342        jumplist = jumplist->next;        jumplist = jumplist->next;
7343        }        }
7344    
7345      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7346      if (current->topbacktracks)      if (current->topbacktracks)
7347        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7348      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 7208  if (has_alternatives) Line 7357  if (has_alternatives)
7357      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)
7358    
7359        {        {
7360        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);
7361        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7362        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));
7363        }        }
7364      JUMPHERE(cond);      JUMPHERE(cond);
7365      }      }
7366    
7367    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7368    if (localptr == 0)    if (private_data_ptr == 0)
7369      free_stack(common, 1);      free_stack(common, 1);
7370    }    }
7371    
7372  if (offset != 0)  if (offset != 0)
7373    {    {
7374    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7375    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7376    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7377    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7378    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7379    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);
7380    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7381        free_stack(common, 3);
7382        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7383        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7384        }
7385      else
7386        {
7387        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7388        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7389        free_stack(common, 2);
7390        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7391        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7392        }
7393    }    }
7394  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7395    {    {
7396    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));
7397    free_stack(common, 1);    free_stack(common, 1);
7398    }    }
7399  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7251  else if (opcode == OP_ONCE) Line 7412  else if (opcode == OP_ONCE)
7412      }      }
7413    
7414    JUMPHERE(once);    JUMPHERE(once);
7415    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7416    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7417      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));
7418    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7419      {      {
7420      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7421      /* See the comment below. */      /* See the comment below. */
7422      free_stack(common, 2);      free_stack(common, 2);
7423      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7424      }      }
7425    }    }
7426    
# Line 7268  if (ket == OP_KETRMAX) Line 7429  if (ket == OP_KETRMAX)
7429    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7430    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7431      free_stack(common, 1);      free_stack(common, 1);
7432    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7433    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7434      {      {
7435      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7436      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7437      JUMPHERE(brazero);      JUMPHERE(brazero);
7438      free_stack(common, 1);      free_stack(common, 1);
7439      }      }
# Line 7295  else if (ket == OP_KETRMIN) Line 7456  else if (ket == OP_KETRMIN)
7456  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7457    {    {
7458    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7459    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7460    JUMPHERE(brazero);    JUMPHERE(brazero);
7461    }    }
7462  }  }
7463    
7464  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7465  {  {
7466  DEFINE_COMPILER;  DEFINE_COMPILER;
7467  int offset;  int offset;
# Line 7321  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7482  if (CURRENT_AS(bracketpos_backtrack)->fr
7482    return;    return;
7483    }    }
7484    
7485  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);
7486  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7487    
7488  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7332  if (current->topbacktracks) Line 7493  if (current->topbacktracks)
7493    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7494    JUMPHERE(jump);    JUMPHERE(jump);
7495    }    }
7496  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));
7497  }  }
7498    
7499  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7500  {  {
7501  assert_backtrack backtrack;  assert_backtrack backtrack;
7502    
# Line 7344  current->topbacktracks = NULL; Line 7505  current->topbacktracks = NULL;
7505  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7506  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7507    {    {
7508    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7509    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7510    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7511    }    }
7512  else  else
7513    {    {
7514    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7515    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7516    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7517    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7518    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7519    }    }
7520  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7521  }  }
7522    
7523  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7524  {  {
7525  DEFINE_COMPILER;  DEFINE_COMPILER;
7526    
# Line 7445  while (current) Line 7606  while (current)
7606  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8