/[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 995 by zherczeg, Wed Jul 11 11:05:30 2012 UTC revision 1187 by zherczeg, Mon Oct 29 11:30:45 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 167  typedef struct executable_functions { Line 170  typedef struct executable_functions {
170    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
171    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
172    void *userdata;    void *userdata;
173      pcre_uint32 top_bracket;
174    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
175  } executable_functions;  } executable_functions;
176    
# Line 188  typedef struct stub_list { Line 192  typedef struct stub_list {
192  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
193    
194  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
195  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
196  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
197  of its descendants. */  of its descendants. */
198  typedef struct backtrack_common {  typedef struct backtrack_common {
199    /* Concatenation stack. */    /* Concatenation stack. */
# Line 208  typedef struct assert_backtrack { Line 212  typedef struct assert_backtrack {
212    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
213    int framesize;    int framesize;
214    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
215    int localptr;    int private_data_ptr;
216    /* For iterators. */    /* For iterators. */
217    struct sljit_label *trypath;    struct sljit_label *matchingpath;
218  } assert_backtrack;  } assert_backtrack;
219    
220  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
221    backtrack_common common;    backtrack_common common;
222    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
223    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
224    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
225    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
226    /* For greedy ? operator. */    /* For greedy ? operator. */
227    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
228    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
229    union {    union {
230      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 230  typedef struct bracket_backtrack { Line 234  typedef struct bracket_backtrack {
234      int framesize;      int framesize;
235    } u;    } u;
236    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
237    int localptr;    int private_data_ptr;
238  } bracket_backtrack;  } bracket_backtrack;
239    
240  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
241    backtrack_common common;    backtrack_common common;
242    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
243    int localptr;    int private_data_ptr;
244    /* Reverting stack is needed. */    /* Reverting stack is needed. */
245    int framesize;    int framesize;
246    /* Allocated stack size. */    /* Allocated stack size. */
# Line 245  typedef struct bracketpos_backtrack { Line 249  typedef struct bracketpos_backtrack {
249    
250  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
251    backtrack_common common;    backtrack_common common;
252    struct sljit_label *trypath;    struct sljit_label *matchingpath;
253  } braminzero_backtrack;  } braminzero_backtrack;
254    
255  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
256    backtrack_common common;    backtrack_common common;
257    /* Next iteration. */    /* Next iteration. */
258    struct sljit_label *trypath;    struct sljit_label *matchingpath;
259  } iterator_backtrack;  } iterator_backtrack;
260    
261  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 274  typedef struct compiler_common { Line 278  typedef struct compiler_common {
278    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
279    pcre_uchar *start;    pcre_uchar *start;
280    
281    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
282    int *localptrs;    int *private_data_ptrs;
283      /* Tells whether the capturing bracket is optimized. */
284      pcre_uint8 *optimized_cbracket;
285      /* Starting offset of private data for capturing brackets. */
286    int cbraptr;    int cbraptr;
287    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
288    int ovector_start;    int ovector_start;
# Line 337  typedef struct compiler_common { Line 344  typedef struct compiler_common {
344  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
345    BOOL use_ucp;    BOOL use_ucp;
346  #endif  #endif
347    #ifndef COMPILE_PCRE32
348    jump_list *utfreadchar;    jump_list *utfreadchar;
349    #endif
350  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
351    jump_list *utfreadtype8;    jump_list *utfreadtype8;
352  #endif  #endif
# Line 357  typedef struct compare_context { Line 366  typedef struct compare_context {
366    union {    union {
367      sljit_i asint;      sljit_i asint;
368      sljit_uh asushort;      sljit_uh asushort;
369  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
370      sljit_ub asbyte;      sljit_ub asbyte;
371      sljit_ub asuchars[4];      sljit_ub asuchars[4];
372  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
373      sljit_uh asuchars[2];      sljit_uh asuchars[2];
374  #endif  #elif defined COMPILE_PCRE32
375        sljit_ui asuchars[1];
376  #endif  #endif
377    } c;    } c;
378    union {    union {
379      sljit_i asint;      sljit_i asint;
380      sljit_uh asushort;      sljit_uh asushort;
381  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
382      sljit_ub asbyte;      sljit_ub asbyte;
383      sljit_ub asuchars[4];      sljit_ub asuchars[4];
384  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
385      sljit_uh asuchars[2];      sljit_uh asuchars[2];
386  #endif  #elif defined COMPILE_PCRE32
387        sljit_ui asuchars[1];
388  #endif  #endif
389    } oc;    } oc;
390  #endif  #endif
# Line 404  enum { Line 413  enum {
413  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
414  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
415    
416  /* Locals layout. */  /* Local space layout. */
417  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
418  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
419  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 420  the start pointers when the end of the c Line 429  the start pointers when the end of the c
429  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
430  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
431  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
432  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
433    
434  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
435  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
436  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
437  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
438  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
439  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
440    #elif defined COMPILE_PCRE32
441    #define MOV_UCHAR  SLJIT_MOV_UI
442    #define MOVU_UCHAR SLJIT_MOVU_UI
443  #else  #else
444  #error Unsupported compiling mode  #error Unsupported compiling mode
445  #endif  #endif
 #endif  
446    
447  /* Shortcuts. */  /* Shortcuts. */
448  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 469  return cc; Line 479  return cc;
479    
480  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
481   next_opcode   next_opcode
482   get_localspace   get_private_data_length
483   set_localptrs   set_private_data_ptrs
484   get_framesize   get_framesize
485   init_frame   init_frame
486   get_localsize   get_private_data_length_for_copy
487   copy_locals   copy_private_data
488   compile_trypath   compile_matchingpath
489   compile_backtrackpath   compile_backtrackingpath
490  */  */
491    
492  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 675  switch(*cc) Line 685  switch(*cc)
685    }    }
686  }  }
687    
688  #define CASE_ITERATOR_LOCAL1 \  #define CASE_ITERATOR_PRIVATE_DATA_1 \
689      case OP_MINSTAR: \      case OP_MINSTAR: \
690      case OP_MINPLUS: \      case OP_MINPLUS: \
691      case OP_QUERY: \      case OP_QUERY: \
# Line 693  switch(*cc) Line 703  switch(*cc)
703      case OP_NOTQUERYI: \      case OP_NOTQUERYI: \
704      case OP_NOTMINQUERYI:      case OP_NOTMINQUERYI:
705    
706  #define CASE_ITERATOR_LOCAL2A \  #define CASE_ITERATOR_PRIVATE_DATA_2A \
707      case OP_STAR: \      case OP_STAR: \
708      case OP_PLUS: \      case OP_PLUS: \
709      case OP_STARI: \      case OP_STARI: \
# Line 703  switch(*cc) Line 713  switch(*cc)
713      case OP_NOTSTARI: \      case OP_NOTSTARI: \
714      case OP_NOTPLUSI:      case OP_NOTPLUSI:
715    
716  #define CASE_ITERATOR_LOCAL2B \  #define CASE_ITERATOR_PRIVATE_DATA_2B \
717      case OP_UPTO: \      case OP_UPTO: \
718      case OP_MINUPTO: \      case OP_MINUPTO: \
719      case OP_UPTOI: \      case OP_UPTOI: \
# Line 713  switch(*cc) Line 723  switch(*cc)
723      case OP_NOTUPTOI: \      case OP_NOTUPTOI: \
724      case OP_NOTMINUPTOI:      case OP_NOTMINUPTOI:
725    
726  #define CASE_ITERATOR_TYPE_LOCAL1 \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
727      case OP_TYPEMINSTAR: \      case OP_TYPEMINSTAR: \
728      case OP_TYPEMINPLUS: \      case OP_TYPEMINPLUS: \
729      case OP_TYPEQUERY: \      case OP_TYPEQUERY: \
730      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
731    
732  #define CASE_ITERATOR_TYPE_LOCAL2A \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
733      case OP_TYPESTAR: \      case OP_TYPESTAR: \
734      case OP_TYPEPLUS:      case OP_TYPEPLUS:
735    
736  #define CASE_ITERATOR_TYPE_LOCAL2B \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
737      case OP_TYPEUPTO: \      case OP_TYPEUPTO: \
738      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
739    
# Line 752  switch(*cc) Line 762  switch(*cc)
762    }    }
763  }  }
764    
765  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)
766  {  {
767  int localspace = 0;  int private_data_length = 0;
768  pcre_uchar *alternative;  pcre_uchar *alternative;
769    pcre_uchar *name;
770  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
771  int space, size, bracketlen;  int space, size, i;
772    pcre_uint32 bracketlen;
773    
774  /* 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. */
775  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 784  while (cc < ccend)
784      cc += 1;      cc += 1;
785      break;      break;
786    
787        case OP_REF:
788        case OP_REFI:
789        common->optimized_cbracket[GET2(cc, 1)] = 0;
790        cc += 1 + IMM2_SIZE;
791        break;
792    
793      case OP_ASSERT:      case OP_ASSERT:
794      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
795      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 781  while (cc < ccend) Line 799  while (cc < ccend)
799      case OP_BRAPOS:      case OP_BRAPOS:
800      case OP_SBRA:      case OP_SBRA:
801      case OP_SBRAPOS:      case OP_SBRAPOS:
802      case OP_SCOND:      private_data_length += sizeof(sljit_w);
     localspace += sizeof(sljit_w);  
803      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
804      break;      break;
805    
806      case OP_CBRAPOS:      case OP_CBRAPOS:
807      case OP_SCBRAPOS:      case OP_SCBRAPOS:
808      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
809        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
810      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
811      break;      break;
812    
813      case OP_COND:      case OP_COND:
814      /* Might be a hidden SCOND. */      case OP_SCOND:
815      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
816      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
817        localspace += sizeof(sljit_w);        {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          common->optimized_cbracket[bracketlen] = 0;
820          }
821        else if (bracketlen == OP_NCREF)
822          {
823          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
824          name = (pcre_uchar *)common->name_table;
825          alternative = name;
826          for (i = 0; i < common->name_count; i++)
827            {
828            if (GET2(name, 0) == bracketlen) break;
829            name += common->name_entry_size;
830            }
831          SLJIT_ASSERT(i != common->name_count);
832    
833          for (i = 0; i < common->name_count; i++)
834            {
835            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
836              common->optimized_cbracket[GET2(alternative, 0)] = 0;
837            alternative += common->name_entry_size;
838            }
839          }
840    
841        if (*cc == OP_COND)
842          {
843          /* Might be a hidden SCOND. */
844          alternative = cc + GET(cc, 1);
845          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
846            private_data_length += sizeof(sljit_w);
847          }
848        else
849          private_data_length += sizeof(sljit_w);
850      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
851      break;      break;
852    
# Line 809  while (cc < ccend) Line 859  while (cc < ccend)
859      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
860      break;      break;
861    
862      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
863      space = 1;      space = 1;
864      size = -2;      size = -2;
865      break;      break;
866    
867      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
868      space = 2;      space = 2;
869      size = -2;      size = -2;
870      break;      break;
871    
872      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
873      space = 2;      space = 2;
874      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
875      break;      break;
876    
877      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
878      space = 1;      space = 1;
879      size = 1;      size = 1;
880      break;      break;
881    
882      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
883      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
884        space = 2;        space = 2;
885      size = 1;      size = 1;
886      break;      break;
887    
888      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
889      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)
890        space = 2;        space = 2;
891      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 881  while (cc < ccend) Line 931  while (cc < ccend)
931      }      }
932    
933    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
934      localspace += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_w) * space;
935    
936    if (size != 0)    if (size != 0)
937      {      {
# Line 896  while (cc < ccend) Line 946  while (cc < ccend)
946        cc += size;        cc += size;
947      }      }
948    
949    if (bracketlen > 0)    if (bracketlen != 0)
950      {      {
951      if (cc >= end)      if (cc >= end)
952        {        {
# Line 907  while (cc < ccend) Line 957  while (cc < ccend)
957      cc += bracketlen;      cc += bracketlen;
958      }      }
959    }    }
960  return localspace;  return private_data_length;
961  }  }
962    
963  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)
964  {  {
965  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
966  pcre_uchar *alternative;  pcre_uchar *alternative;
# Line 934  while (cc < ccend) Line 984  while (cc < ccend)
984      case OP_SBRA:      case OP_SBRA:
985      case OP_SBRAPOS:      case OP_SBRAPOS:
986      case OP_SCOND:      case OP_SCOND:
987      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
988      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
989      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
990      break;      break;
991    
992      case OP_CBRAPOS:      case OP_CBRAPOS:
993      case OP_SCBRAPOS:      case OP_SCBRAPOS:
994      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
995      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
996      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
997      break;      break;
998    
# Line 951  while (cc < ccend) Line 1001  while (cc < ccend)
1001      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1002      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1003        {        {
1004        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1005        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1006        }        }
1007      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1008      break;      break;
# Line 966  while (cc < ccend) Line 1016  while (cc < ccend)
1016      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1017      break;      break;
1018    
1019      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1020      space = 1;      space = 1;
1021      size = -2;      size = -2;
1022      break;      break;
1023    
1024      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1025      space = 2;      space = 2;
1026      size = -2;      size = -2;
1027      break;      break;
1028    
1029      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1030      space = 2;      space = 2;
1031      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
1032      break;      break;
1033    
1034      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1035      space = 1;      space = 1;
1036      size = 1;      size = 1;
1037      break;      break;
1038    
1039      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1040      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1041        space = 2;        space = 2;
1042      size = 1;      size = 1;
1043      break;      break;
1044    
1045      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1046      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)
1047        space = 2;        space = 2;
1048      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 1019  while (cc < ccend) Line 1069  while (cc < ccend)
1069    
1070    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1071      {      {
1072      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1073      localptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_w) * space;
1074      }      }
1075    
1076    if (size != 0)    if (size != 0)
# Line 1222  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1272  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1272  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1273  }  }
1274    
1275  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)
1276  {  {
1277  int localsize = 2;  int private_data_length = 2;
1278  int size;  int size;
1279  pcre_uchar *alternative;  pcre_uchar *alternative;
1280  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1281  while (cc < ccend)  while (cc < ccend)
1282    {    {
1283    size = 0;    size = 0;
# Line 1243  while (cc < ccend) Line 1293  while (cc < ccend)
1293      case OP_SBRA:      case OP_SBRA:
1294      case OP_SBRAPOS:      case OP_SBRAPOS:
1295      case OP_SCOND:      case OP_SCOND:
1296      localsize++;      private_data_length++;
1297      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1298      break;      break;
1299    
1300      case OP_CBRA:      case OP_CBRA:
1301      case OP_SCBRA:      case OP_SCBRA:
1302      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1303          private_data_length++;
1304      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1305      break;      break;
1306    
1307      case OP_CBRAPOS:      case OP_CBRAPOS:
1308      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1309      localsize += 2;      private_data_length += 2;
1310      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1311      break;      break;
1312    
# Line 1263  while (cc < ccend) Line 1314  while (cc < ccend)
1314      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1315      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1316      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1317        localsize++;        private_data_length++;
1318      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1319      break;      break;
1320    
1321      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1322      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1323        localsize++;        private_data_length++;
1324      cc += 2;      cc += 2;
1325  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1326      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1327  #endif  #endif
1328      break;      break;
1329    
1330      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1331      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1332        localsize += 2;        private_data_length += 2;
1333      cc += 2;      cc += 2;
1334  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1335      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1336  #endif  #endif
1337      break;      break;
1338    
1339      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1340      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1341        localsize += 2;        private_data_length += 2;
1342      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1343  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1344      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1345  #endif  #endif
1346      break;      break;
1347    
1348      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1349      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1350        localsize++;        private_data_length++;
1351      cc += 1;      cc += 1;
1352      break;      break;
1353    
1354      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1355      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1356        localsize += 2;        private_data_length += 2;
1357      cc += 1;      cc += 1;
1358      break;      break;
1359    
1360      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1361      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1362        localsize += 2;        private_data_length += 2;
1363      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
1364      break;      break;
1365    
# Line 1320  while (cc < ccend) Line 1371  while (cc < ccend)
1371  #else  #else
1372      size = 1 + 32 / (int)sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1373  #endif  #endif
1374      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1375        localsize += get_class_iterator_size(cc + size);        private_data_length += get_class_iterator_size(cc + size);
1376      cc += size;      cc += size;
1377      break;      break;
1378    
# Line 1332  while (cc < ccend) Line 1383  while (cc < ccend)
1383      }      }
1384    }    }
1385  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1386  return localsize;  return private_data_length;
1387  }  }
1388    
1389  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,
1390    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1391  {  {
1392  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1405  while (status != end) Line 1456  while (status != end)
1456        case OP_SBRAPOS:        case OP_SBRAPOS:
1457        case OP_SCOND:        case OP_SCOND:
1458        count = 1;        count = 1;
1459        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1460        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1461        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1462        break;        break;
1463    
1464        case OP_CBRA:        case OP_CBRA:
1465        case OP_SCBRA:        case OP_SCBRA:
1466        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1467        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1468            count = 1;
1469            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1470            }
1471        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1472        break;        break;
1473    
1474        case OP_CBRAPOS:        case OP_CBRAPOS:
1475        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1476        count = 2;        count = 2;
1477        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1478        srcw[1] = PRIV_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1479        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1480        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1481        break;        break;
1482    
# Line 1432  while (status != end) Line 1486  while (status != end)
1486        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1487          {          {
1488          count = 1;          count = 1;
1489          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1490          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1491          }          }
1492        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1493        break;        break;
1494    
1495        CASE_ITERATOR_LOCAL1        CASE_ITERATOR_PRIVATE_DATA_1
1496        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1497          {          {
1498          count = 1;          count = 1;
1499          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1500          }          }
1501        cc += 2;        cc += 2;
1502  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1450  while (status != end) Line 1504  while (status != end)
1504  #endif  #endif
1505        break;        break;
1506    
1507        CASE_ITERATOR_LOCAL2A        CASE_ITERATOR_PRIVATE_DATA_2A
1508        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1509          {          {
1510          count = 2;          count = 2;
1511          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1512          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1513          }          }
1514        cc += 2;        cc += 2;
1515  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1463  while (status != end) Line 1517  while (status != end)
1517  #endif  #endif
1518        break;        break;
1519    
1520        CASE_ITERATOR_LOCAL2B        CASE_ITERATOR_PRIVATE_DATA_2B
1521        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1522          {          {
1523          count = 2;          count = 2;
1524          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1525          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1526          }          }
1527        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1528  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1476  while (status != end) Line 1530  while (status != end)
1530  #endif  #endif
1531        break;        break;
1532    
1533        CASE_ITERATOR_TYPE_LOCAL1        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1534        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1535          {          {
1536          count = 1;          count = 1;
1537          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1538          }          }
1539        cc += 1;        cc += 1;
1540        break;        break;
1541    
1542        CASE_ITERATOR_TYPE_LOCAL2A        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1543        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1544          {          {
1545          count = 2;          count = 2;
1546          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1547          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1548          }          }
1549        cc += 1;        cc += 1;
1550        break;        break;
1551    
1552        CASE_ITERATOR_TYPE_LOCAL2B        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1553        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1554          {          {
1555          count = 2;          count = 2;
1556          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1557          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1558          }          }
1559        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
# Line 1513  while (status != end) Line 1567  while (status != end)
1567  #else  #else
1568        size = 1 + 32 / (int)sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1569  #endif  #endif
1570        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1571          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
1572            {            {
1573            case 1:            case 1:
1574            count = 1;            count = 1;
1575            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1576            break;            break;
1577    
1578            case 2:            case 2:
1579            count = 2;            count = 2;
1580            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1581            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_w);
1582            break;            break;
1583    
# Line 1636  if (save) Line 1690  if (save)
1690  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1691  }  }
1692    
1693  #undef CASE_ITERATOR_LOCAL1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1694  #undef CASE_ITERATOR_LOCAL2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1695  #undef CASE_ITERATOR_LOCAL2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
1696  #undef CASE_ITERATOR_TYPE_LOCAL1  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1697  #undef CASE_ITERATOR_TYPE_LOCAL2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1698  #undef CASE_ITERATOR_TYPE_LOCAL2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1699    
1700  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1701  {  {
1702  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1703  }  }
# Line 1653  static SLJIT_INLINE void set_jumps(jump_ Line 1707  static SLJIT_INLINE void set_jumps(jump_
1707  while (list)  while (list)
1708    {    {
1709    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1710    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1711    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1712    list = list->next;    list = list->next;
1713    }    }
# Line 1785  loop = LABEL(); Line 1839  loop = LABEL();
1839  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);
1840  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));
1841  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1842  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1843  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);
1844  #endif  #endif
1845  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);
1846  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 1881  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
1881  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));
1882  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);
1883  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);
1884  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1885  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);
1886  #endif  #endif
1887  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);
1888    
1889  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);
1890  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1891  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);
1892  #endif  #endif
1893  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);
1894    
# Line 1949  if (c <= 127 && bit == 0x20) Line 2003  if (c <= 127 && bit == 0x20)
2003    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2004    
2005  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2006  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2007    return 0;    return 0;
2008    
2009  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2010    
2011  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2012  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1968  if (common->utf && c > 127) Line 2022  if (common->utf && c > 127)
2022  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2023  return (0 << 8) | bit;  return (0 << 8) | bit;
2024    
2025  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2026    
 #ifdef COMPILE_PCRE16  
2027  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2028  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2029    {    {
# Line 1981  if (common->utf && c > 65535) Line 2034  if (common->utf && c > 65535)
2034    }    }
2035  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2036  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2037    
2038  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2039  }  }
2040    
2041  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 2133  static void read_char(compiler_common *c
2133  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2134  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2135  DEFINE_COMPILER;  DEFINE_COMPILER;
2136  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2137  struct sljit_jump *jump;  struct sljit_jump *jump;
2138  #endif  #endif
2139    
2140  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2141  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2142  if (common->utf)  if (common->utf)
2143    {    {
2144  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2146  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2147    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2148  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2149    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2150    JUMPHERE(jump);    JUMPHERE(jump);
2151    }    }
2152  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2153  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));
2154  }  }
2155    
# Line 2108  static void peek_char(compiler_common *c Line 2158  static void peek_char(compiler_common *c
2158  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2159  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2160  DEFINE_COMPILER;  DEFINE_COMPILER;
2161  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2162  struct sljit_jump *jump;  struct sljit_jump *jump;
2163  #endif  #endif
2164    
2165  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2166  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2167  if (common->utf)  if (common->utf)
2168    {    {
2169  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2171  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2172    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2173  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2174    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2175    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2176    JUMPHERE(jump);    JUMPHERE(jump);
2177    }    }
2178  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2179  }  }
2180    
2181  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2182  {  {
2183  /* 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. */
2184  DEFINE_COMPILER;  DEFINE_COMPILER;
2185  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2186  struct sljit_jump *jump;  struct sljit_jump *jump;
2187  #endif  #endif
2188    
# Line 2143  if (common->utf) Line 2191  if (common->utf)
2191    {    {
2192    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2193    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));
2194  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2195    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2196    it is needed in most cases. */    it is needed in most cases. */
2197    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2198    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2199    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2200    JUMPHERE(jump);    JUMPHERE(jump);
2201  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2202    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2203    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2204    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 2209  if (common->utf)
2209    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2210    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2211    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2212  #endif  #elif defined COMPILE_PCRE32
2213  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2214      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2215      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2216      JUMPHERE(jump);
2217    #endif /* COMPILE_PCRE[8|16|32] */
2218    return;    return;
2219    }    }
2220  #endif  #endif /* SUPPORT_UTF */
2221  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2222  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));
2223  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2224  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2225  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2226  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2227  #endif  #endif
2228  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2229  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2230  JUMPHERE(jump);  JUMPHERE(jump);
2231  #endif  #endif
2232  }  }
# Line 2184  static void skip_char_back(compiler_comm Line 2235  static void skip_char_back(compiler_comm
2235  {  {
2236  /* 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. */
2237  DEFINE_COMPILER;  DEFINE_COMPILER;
2238  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2239    #if defined COMPILE_PCRE8
2240  struct sljit_label *label;  struct sljit_label *label;
2241    
2242  if (common->utf)  if (common->utf)
# Line 2196  if (common->utf) Line 2248  if (common->utf)
2248    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2249    return;    return;
2250    }    }
2251  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2252  if (common->utf)  if (common->utf)
2253    {    {
2254    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 2261  if (common->utf)
2261    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2262    return;    return;
2263    }    }
2264  #endif  #endif /* COMPILE_PCRE[8|16] */
2265    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2266  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));
2267  }  }
2268    
# Line 2241  else Line 2293  else
2293    
2294  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2295    
2296  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2297  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2298  {  {
2299  /* 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 2387  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2387  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2388  }  }
2389    
2390  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2391    
 #ifdef COMPILE_PCRE16  
2392  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2393  {  {
2394  /* 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 2413  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2413  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2414  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2415  }  }
 #endif /* COMPILE_PCRE16 */  
2416    
2417  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2418    
2419  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2420    
# Line 2404  struct sljit_label *newlinelabel = NULL; Line 2454  struct sljit_label *newlinelabel = NULL;
2454  struct sljit_jump *start;  struct sljit_jump *start;
2455  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2456  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2457  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2458  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2459  #endif  #endif
2460  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 2460  if (newlinecheck) Line 2510  if (newlinecheck)
2510    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2511    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);
2512    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2513  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2514    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2515  #endif  #endif
2516    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2517    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2482  if (newlinecheck) Line 2532  if (newlinecheck)
2532    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);
2533    
2534  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));
2535  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2536    #if defined COMPILE_PCRE8
2537  if (common->utf)  if (common->utf)
2538    {    {
2539    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 2541  if (common->utf)
2541    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2542    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2543    }    }
2544  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2545  if (common->utf)  if (common->utf)
2546    {    {
2547    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 2552  if (common->utf)
2552    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2553    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2554    }    }
2555  #endif  #endif /* COMPILE_PCRE[8|16] */
2556    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2557  JUMPHERE(start);  JUMPHERE(start);
2558    
2559  if (newlinecheck)  if (newlinecheck)
# Line 2514  if (newlinecheck) Line 2565  if (newlinecheck)
2565  return mainloop;  return mainloop;
2566  }  }
2567    
2568  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2569    
2570    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2571  {  {
2572  DEFINE_COMPILER;  DEFINE_COMPILER;
2573  struct sljit_label *start;  struct sljit_label *start;
2574  struct sljit_jump *quit;  struct sljit_jump *quit;
2575  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
 pcre_int32 chars[4];  
2576  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2577  int location = 0;  int location = 0;
2578  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2579  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  
2580    
2581    /* We do not support alternatives now. */
2582  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2583    return FALSE;    return FALSE;
2584    
2585  while (TRUE)  while (TRUE)
2586    {    {
2587    caseless = 0;    caseless = 0;
2588    must_end = TRUE;    must_stop = 1;
2589    switch(*cc)    switch(*cc)
2590      {      {
2591      case OP_CHAR:      case OP_CHAR:
2592      must_end = FALSE;      must_stop = 0;
2593      cc++;      cc++;
2594      break;      break;
2595    
2596      case OP_CHARI:      case OP_CHARI:
2597      caseless = 1;      caseless = 1;
2598      must_end = FALSE;      must_stop = 0;
2599      cc++;      cc++;
2600      break;      break;
2601    
# Line 2596  while (TRUE) Line 2637  while (TRUE)
2637      break;      break;
2638    
2639      default:      default:
2640      return FALSE;      must_stop = 2;
2641        break;
2642      }      }
2643    
2644      if (must_stop == 2)
2645          break;
2646    
2647    len = 1;    len = 1;
2648  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2649    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
# Line 2621  while (TRUE) Line 2666  while (TRUE)
2666    else    else
2667      caseless = 0;      caseless = 0;
2668    
2669    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
2670      {      {
2671      c = *cc;      c = *cc;
2672      bit = 0;      bit = 0;
# Line 2639  while (TRUE) Line 2684  while (TRUE)
2684      cc++;      cc++;
2685      }      }
2686    
2687    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2688      break;      break;
   else if (must_end)  
     return FALSE;  
2689    }    }
2690    
2691    /* At least two characters are required. */
2692    if (location < 2 * 2)
2693        return FALSE;
2694    
2695  if (firstline)  if (firstline)
2696    {    {
2697    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2698    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2699    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2700    }    }
2701  else  else
2702    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);
2703    
2704  start = LABEL();  start = LABEL();
2705  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  
2706    
2707  #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 */  
2708  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2709  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2710  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
2711      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2712  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2713  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
2714  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2715  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
2716  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2717  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2718    if (location > 2 * 2)
2719  #endif    {
2720      if (chars[5] != 0)
2721  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2722    {    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);  
2723    }    }
2724    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2725    
 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);  
2726  JUMPHERE(quit);  JUMPHERE(quit);
2727    
2728  if (firstline)  if (firstline)
2729    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2730  else  else
2731    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2732  return TRUE;  return TRUE;
2733  }  }
2734    
2735    #undef MAX_N_CHARS
2736    
2737  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)
2738  {  {
2739  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2738  if (first_char == oc) Line 2767  if (first_char == oc)
2767  else  else
2768    {    {
2769    bit = first_char ^ oc;    bit = first_char ^ oc;
2770    if (ispowerof2(bit))    if (is_powerof2(bit))
2771      {      {
2772      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2773      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 2791  if (common->nltype == NLTYPE_FIXED && co Line 2820  if (common->nltype == NLTYPE_FIXED && co
2820    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2821    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);
2822    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2823  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2824    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2825  #endif  #endif
2826    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2827    
# Line 2834  if (common->nltype == NLTYPE_ANY || comm Line 2863  if (common->nltype == NLTYPE_ANY || comm
2863    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2864    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);
2865    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2866  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2867    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2868  #endif  #endif
2869    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2870    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
# Line 2889  if (common->utf) Line 2918  if (common->utf)
2918    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2919  #endif  #endif
2920  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));
2921  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2922    #if defined COMPILE_PCRE8
2923  if (common->utf)  if (common->utf)
2924    {    {
2925    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2926    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);
2927    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2928    }    }
2929  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2930  if (common->utf)  if (common->utf)
2931    {    {
2932    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2907  if (common->utf) Line 2936  if (common->utf)
2936    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2937    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2938    }    }
2939  #endif  #endif /* COMPILE_PCRE[8|16] */
2940    #endif /* SUPPORT_UTF */
2941  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2942  JUMPHERE(found);  JUMPHERE(found);
2943  JUMPHERE(quit);  JUMPHERE(quit);
# Line 2925  struct sljit_jump *alreadyfound; Line 2955  struct sljit_jump *alreadyfound;
2955  struct sljit_jump *found;  struct sljit_jump *found;
2956  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2957  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2958  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2959    
2960  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2961  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 2956  if (req_char == oc) Line 2986  if (req_char == oc)
2986  else  else
2987    {    {
2988    bit = req_char ^ oc;    bit = req_char ^ oc;
2989    if (ispowerof2(bit))    if (is_powerof2(bit))
2990      {      {
2991      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2992      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 3186  switch(ranges[0]) Line 3216  switch(ranges[0])
3216        }        }
3217      return TRUE;      return TRUE;
3218      }      }
3219    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3220      {      {
3221      if (readch)      if (readch)
3222        read_char(common);        read_char(common);
# Line 3287  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3317  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3317  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);
3318  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3319  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);
3320  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3321  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3322  if (common->utf)  if (common->utf)
3323    {    {
# Line 3298  if (common->utf) Line 3328  if (common->utf)
3328  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3329    }    }
3330  #endif  #endif
3331  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3332  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3333  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3334  }  }
# Line 3315  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 3345  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
3345  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);
3346  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3347  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);
3348  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3350  if (common->utf)  if (common->utf)
3351    {    {
# Line 3336  if (common->utf) Line 3366  if (common->utf)
3366  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3367    }    }
3368  #endif  #endif
3369  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3370  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3371    
3372  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3353  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3383  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3383  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);
3384  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3385  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);
3386  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3387  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3388  if (common->utf)  if (common->utf)
3389    {    {
# Line 3364  if (common->utf) Line 3394  if (common->utf)
3394  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3395    }    }
3396  #endif  #endif
3397  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3398  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3399    
3400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3454  sljit_emit_fast_return(compiler, RETURN_ Line 3484  sljit_emit_fast_return(compiler, RETURN_
3484  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)
3485  {  {
3486  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3487  int c1, c2;  pcre_uint32 c1, c2;
3488  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3489  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3490    const ucd_record *ur;
3491    const pcre_uint32 *pp;
3492    
3493  while (src1 < end1)  while (src1 < end1)
3494    {    {
# Line 3464  while (src1 < end1) Line 3496  while (src1 < end1)
3496      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3497    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3498    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3499    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3500      if (c1 != c2 && c1 != c2 + ur->other_case)
3501        {
3502        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3503        for (;;)
3504          {
3505          if (c1 < *pp) return NULL;
3506          if (c1 == *pp++) break;
3507          }
3508        }
3509    }    }
3510  return src2;  return src2;
3511  }  }
# Line 3486  if (caseless && char_has_othercase(commo Line 3527  if (caseless && char_has_othercase(commo
3527    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3528    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3529    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3530  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3531    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3532    othercasebit &= 0xff;    othercasebit &= 0xff;
3533  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3534  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3535      ever are characters outside the BMP whose othercase differs in only one
3536      bit from itself (there currently are none), this code will need to be
3537      revised for COMPILE_PCRE32. */
3538    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3539    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3540      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3541    else    else
3542      othercasebit &= 0xff;      othercasebit &= 0xff;
3543  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3544    }    }
3545    
3546  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3547    {    {
3548  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3549  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3550    if (context->length >= 4)    if (context->length >= 4)
3551      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 3511  if (context->sourcereg == -1) Line 3554  if (context->sourcereg == -1)
3554    else    else
3555  #endif  #endif
3556      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3557  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3558  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3559    if (context->length >= 4)    if (context->length >= 4)
3560      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3561    else    else
3562  #endif  #endif
3563      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3564  #endif  #elif defined COMPILE_PCRE32
3565  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3566    #endif /* COMPILE_PCRE[8|16|32] */
3567    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3568    }    }
3569    
# Line 3549  do Line 3592  do
3592      }      }
3593    context->ucharptr++;    context->ucharptr++;
3594    
3595  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3596    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))
3597  #else  #elif defined COMPILE_PCRE16
3598    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3599    #elif defined COMPILE_PCRE32
3600      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3601  #endif  #endif
3602      {      {
3603    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3604      if (context->length >= 4)      if (context->length >= 4)
3605        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);
3606  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3607      else if (context->length >= 2)      else if (context->length >= 2)
3608        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);
3609      else if (context->length >= 1)      else if (context->length >= 1)
3610        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);
3611  #else  #elif defined COMPILE_PCRE16
3612      else if (context->length >= 2)      else if (context->length >= 2)
3613        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);
3614  #endif  #endif /* COMPILE_PCRE[8|16] */
3615    #elif defined COMPILE_PCRE32
3616        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3617    #endif /* COMPILE_PCRE[8|16|32] */
3618      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3619    
3620      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3576  do Line 3625  do
3625        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));
3626        break;        break;
3627    
3628    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3629        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3630        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3631          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 3590  do Line 3640  do
3640        break;        break;
3641  #endif  #endif
3642    
3643    #endif /* COMPILE_PCRE[8|16] */
3644    
3645        default:        default:
3646        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3647        break;        break;
# Line 3600  do Line 3652  do
3652  #else  #else
3653    
3654    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #else  
3655    if (context->length > 0)    if (context->length > 0)
3656      OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3657  #endif  
3658    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3659    
3660    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3651  return cc; Line 3699  return cc;
3699      } \      } \
3700    charoffset = (value);    charoffset = (value);
3701    
3702  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)
3703  {  {
3704  DEFINE_COMPILER;  DEFINE_COMPILER;
3705  jump_list *found = NULL;  jump_list *found = NULL;
3706  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3707  unsigned int c;  pcre_int32 c, charoffset;
3708  int compares;  const pcre_uint32 *other_cases;
3709  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3710  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3711    int compares, invertcmp, numberofcmps;
3712  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3713  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3714  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3715  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3716  unsigned int typeoffset;  pcre_int32 typeoffset;
3717  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3718    
3719  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3720     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3765  while (*cc != XCL_END) Line 3812  while (*cc != XCL_END)
3812        needschar = TRUE;        needschar = TRUE;
3813        break;        break;
3814    
3815          case PT_CLIST:
3816          needschar = TRUE;
3817          break;
3818    
3819        default:        default:
3820        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3821        break;        break;
# Line 3974  while (*cc != XCL_END) Line 4025  while (*cc != XCL_END)
4025        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);
4026        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4027        break;        break;
4028    
4029          case PT_CLIST:
4030          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4031    
4032          /* At least three characters are required.
4033             Otherwise this case would be handled by the normal code path. */
4034          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4035          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4036    
4037          /* Optimizing character pairs, if their difference is power of 2. */
4038          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4039            {
4040            if (charoffset == 0)
4041              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4042            else
4043              {
4044              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4045              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4046              }
4047            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4048            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4049            other_cases += 2;
4050            }
4051          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4052            {
4053            if (charoffset == 0)
4054              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4055            else
4056              {
4057              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4058              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4059              }
4060            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4061            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4062    
4063            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4064            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4065    
4066            other_cases += 3;
4067            }
4068          else
4069            {
4070            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4071            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4072            }
4073    
4074          while (*other_cases != NOTACHAR)
4075            {
4076            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4077            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4078            }
4079          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4080          break;
4081        }        }
4082      cc += 2;      cc += 2;
4083      }      }
# Line 3992  if (found != NULL) Line 4096  if (found != NULL)
4096    
4097  #endif  #endif
4098    
4099  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)
4100  {  {
4101  DEFINE_COMPILER;  DEFINE_COMPILER;
4102  int length;  int length;
# Line 4089  switch(type) Line 4193  switch(type)
4193      {      {
4194      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4195      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));
4196  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4197    #if defined COMPILE_PCRE8
4198      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4199      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);
4200      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4201  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4202      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4203      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4204      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);
4205      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4206      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4207      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4208  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4209      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4210    #endif /* COMPILE_PCRE[8|16] */
4211      return cc;      return cc;
4212      }      }
4213  #endif  #endif
# Line 4124  switch(type) Line 4228  switch(type)
4228    propdata[2] = cc[0];    propdata[2] = cc[0];
4229    propdata[3] = cc[1];    propdata[3] = cc[1];
4230    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4231    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4232    return cc + 2;    return cc + 2;
4233  #endif  #endif
4234  #endif  #endif
# Line 4170  switch(type) Line 4274  switch(type)
4274    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4275    read_char(common);    read_char(common);
4276    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4277    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));
4278    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4279      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4280      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4281    
4282    label = LABEL();    label = LABEL();
4283    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);
4284    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4285    read_char(common);    read_char(common);
4286    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4287    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));
4288    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);
4289    
4290      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4291      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4292      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4293      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4294      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4295      JUMPTO(SLJIT_C_NOT_ZERO, label);
4296    
4297    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4298    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4299      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4300    
4301    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4302      {      {
4303      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 4308  switch(type) Line 4423  switch(type)
4423    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));
4424    
4425    if (!common->endonly)    if (!common->endonly)
4426      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4427    else    else
4428      {      {
4429      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 4388  switch(type) Line 4503  switch(type)
4503      }      }
4504    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4505    bit = c ^ oc;    bit = c ^ oc;
4506    if (ispowerof2(bit))    if (is_powerof2(bit))
4507      {      {
4508      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4509      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 4449  switch(type) Line 4564  switch(type)
4564      {      {
4565      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4566      bit = c ^ oc;      bit = c ^ oc;
4567      if (ispowerof2(bit))      if (is_powerof2(bit))
4568        {        {
4569        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4570        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 4497  switch(type) Line 4612  switch(type)
4612  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4613    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4614    
4615  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4616    case OP_XCLASS:    case OP_XCLASS:
4617    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4618    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4619  #endif  #endif
4620    
# Line 4533  SLJIT_ASSERT_STOP(); Line 4648  SLJIT_ASSERT_STOP();
4648  return cc;  return cc;
4649  }  }
4650    
4651  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)
4652  {  {
4653  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4654  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 4596  if (context.length > 0) Line 4711  if (context.length > 0)
4711    }    }
4712    
4713  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4714  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4715  }  }
4716    
4717  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 4622  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4737  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4737  }  }
4738    
4739  /* Forward definitions. */  /* Forward definitions. */
4740  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4741  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4742    
4743  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4744    do \    do \
# Line 4653  static void compile_backtrackpath(compil Line 4768  static void compile_backtrackpath(compil
4768    
4769  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4770    
4771  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)
4772  {  {
4773  DEFINE_COMPILER;  DEFINE_COMPILER;
4774  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 4735  if (jump != NULL) Line 4850  if (jump != NULL)
4850  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4851  }  }
4852    
4853  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)
4854  {  {
4855  DEFINE_COMPILER;  DEFINE_COMPILER;
4856  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4806  if (!minimize) Line 4921  if (!minimize)
4921      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4922    
4923    label = LABEL();    label = LABEL();
4924    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4925    
4926    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4927      {      {
# Line 4834  if (!minimize) Line 4949  if (!minimize)
4949      }      }
4950    
4951    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4952    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4953    
4954    decrease_call_count(common);    decrease_call_count(common);
4955    return cc;    return cc;
# Line 4854  if (min == 0) Line 4969  if (min == 0)
4969  else  else
4970    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4971    
4972  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4973  if (max > 0)  if (max > 0)
4974    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));
4975    
4976  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4977  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4978    
4979  if (min > 1)  if (min > 1)
# Line 4866  if (min > 1) Line 4981  if (min > 1)
4981    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4982    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4983    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4984    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);
4985    }    }
4986  else if (max > 0)  else if (max > 0)
4987    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4879  decrease_call_count(common); Line 4994  decrease_call_count(common);
4994  return cc;  return cc;
4995  }  }
4996    
4997  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)
4998  {  {
4999  DEFINE_COMPILER;  DEFINE_COMPILER;
5000  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4936  add_jump(compiler, &backtrack->topbacktr Line 5051  add_jump(compiler, &backtrack->topbacktr
5051  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5052  }  }
5053    
5054  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)
5055  {  {
5056  DEFINE_COMPILER;  DEFINE_COMPILER;
5057  int framesize;  int framesize;
5058  int localptr;  int private_data_ptr;
5059  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5060  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5061  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4962  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5077  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5077    bra = *cc;    bra = *cc;
5078    cc++;    cc++;
5079    }    }
5080  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5081  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5082  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5083  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5084  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5085  opcode = *cc;  opcode = *cc;
5086  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5087  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4983  if (bra == OP_BRAMINZERO) Line 5098  if (bra == OP_BRAMINZERO)
5098    
5099  if (framesize < 0)  if (framesize < 0)
5100    {    {
5101    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);
5102    allocate_stack(common, 1);    allocate_stack(common, 1);
5103    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5104    }    }
5105  else  else
5106    {    {
5107    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5108    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5109    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));
5110    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5111    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5112    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5113    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
# Line 5012  while (1) Line 5127  while (1)
5127      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5128    
5129    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5130    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5131    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5132      {      {
5133      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5027  while (1) Line 5142  while (1)
5142    
5143    /* Reset stack. */    /* Reset stack. */
5144    if (framesize < 0)    if (framesize < 0)
5145      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);
5146    else {    else {
5147      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5148        {        {
5149        /* 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. */
5150        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));
5151        }        }
5152      else      else
5153        {        {
5154        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);
5155        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5156        }        }
5157    }    }
# Line 5054  while (1) Line 5169  while (1)
5169          {          {
5170          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));
5171          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));
5172          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5173          }          }
5174        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));
5175        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 5062  while (1) Line 5177  while (1)
5177      else if (framesize >= 0)      else if (framesize >= 0)
5178        {        {
5179        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5180        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));
5181        }        }
5182      }      }
5183    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5184    
5185    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5186    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5187      {      {
5188      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5113  if (opcode == OP_ASSERT || opcode == OP_ Line 5228  if (opcode == OP_ASSERT || opcode == OP_
5228        }        }
5229      else      else
5230        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5231      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5232      }      }
5233    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5234    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 5138  if (opcode == OP_ASSERT || opcode == OP_ Line 5253  if (opcode == OP_ASSERT || opcode == OP_
5253      {      {
5254      if (bra == OP_BRA)      if (bra == OP_BRA)
5255        {        {
5256        /* 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. */
5257        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));
5258        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5259        }        }
5260      else      else
5261        {        {
5262        /* 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. */
5263        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));
5264        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5265        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);
5266        }        }
# Line 5153  if (opcode == OP_ASSERT || opcode == OP_ Line 5268  if (opcode == OP_ASSERT || opcode == OP_
5268    
5269    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5270      {      {
5271      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5272      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5273      }      }
5274    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5275      {      {
5276      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5277      JUMPHERE(brajump);      JUMPHERE(brajump);
5278      if (framesize >= 0)      if (framesize >= 0)
5279        {        {
5280        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);
5281        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5282        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));
5283        }        }
5284      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5285      }      }
# Line 5192  else Line 5307  else
5307        }        }
5308      else      else
5309        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5310      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5311      }      }
5312    
5313    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5314      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5315    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5316      {      {
5317      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5318      JUMPHERE(brajump);      JUMPHERE(brajump);
5319      }      }
5320    
# Line 5218  common->accept = save_accept; Line 5333  common->accept = save_accept;
5333  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5334  }  }
5335    
5336  static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)  static sljit_w SLJIT_CALL do_searchovector(sljit_uw refno, sljit_w* locals, pcre_uchar *name_table)
5337  {  {
5338  int condition = FALSE;  int condition = FALSE;
5339  pcre_uchar *slotA = name_table;  pcre_uchar *slotA = name_table;
# Line 5275  if (i < name_count) Line 5390  if (i < name_count)
5390  return condition;  return condition;
5391  }  }
5392    
5393  static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)  static sljit_w SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table)
5394  {  {
5395  int condition = FALSE;  int condition = FALSE;
5396  pcre_uchar *slotA = name_table;  pcre_uchar *slotA = name_table;
5397  pcre_uchar *slotB;  pcre_uchar *slotB;
5398  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_w)];
5399  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
5400  sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];  sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
5401  int i;  sljit_uw i;
5402    
5403  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
5404    {    {
# Line 5382  return condition; Line 5497  return condition;
5497                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5498  */  */
5499    
5500  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)
5501  {  {
5502  DEFINE_COMPILER;  DEFINE_COMPILER;
5503  backtrack_common *backtrack;  backtrack_common *backtrack;
5504  pcre_uchar opcode;  pcre_uchar opcode;
5505  int localptr = 0;  int private_data_ptr = 0;
5506  int offset = 0;  int offset = 0;
5507  int stacksize;  int stacksize;
5508  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5509  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5510  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5511  pcre_uchar ket;  pcre_uchar ket;
5512  assert_backtrack *assert;  assert_backtrack *assert;
# Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5527  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5527    
5528  opcode = *cc;  opcode = *cc;
5529  ccbegin = cc;  ccbegin = cc;
5530  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5531    
5532  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)
5533    {    {
# Line 5429  cc += GET(cc, 1); Line 5544  cc += GET(cc, 1);
5544  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5545  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5546    {    {
5547    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5548    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5549      {      {
5550      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5551      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5552        has_alternatives = FALSE;        has_alternatives = FALSE;
5553      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
5554        has_alternatives = stacksize != 0;        has_alternatives = stacksize != 0;
5555      else      else
5556        has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        has_alternatives = stacksize != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5557      }      }
5558    }    }
5559    
# Line 5451  if (opcode == OP_CBRA || opcode == OP_SC Line 5566  if (opcode == OP_CBRA || opcode == OP_SC
5566    {    {
5567    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5568    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5569    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5570    offset <<= 1;      {
5571    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5572    trypath += IMM2_SIZE;      offset <<= 1;
5573        }
5574      else
5575        {
5576        offset <<= 1;
5577        private_data_ptr = OVECTOR(offset);
5578        }
5579      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5580      matchingpath += IMM2_SIZE;
5581    }    }
5582  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5583    {    {
5584    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5585    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5586    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5587    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5588    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5589      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5590    }    }
# Line 5507  if (bra == OP_BRAMINZERO) Line 5630  if (bra == OP_BRAMINZERO)
5630        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5631        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5632          {          {
5633          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5634          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);
5635          }          }
5636        else        else
5637          {          {
5638          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5639          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5640          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));
5641          }          }
5642        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5528  if (bra == OP_BRAMINZERO) Line 5651  if (bra == OP_BRAMINZERO)
5651    }    }
5652    
5653  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5654    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5655    
5656  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5657    {    {
5658    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5659    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5660      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5661    }    }
5662    
5663  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 5545  if (opcode == OP_ONCE) Line 5668  if (opcode == OP_ONCE)
5668      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5669      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5670        {        {
5671        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5672        allocate_stack(common, 2);        allocate_stack(common, 2);
5673        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5674        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5675        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));
5676        }        }
5677      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5678        {        {
5679        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);
5680        allocate_stack(common, 1);        allocate_stack(common, 1);
5681        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5682        }        }
5683      else      else
5684        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);
5685      }      }
5686    else    else
5687      {      {
5688      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5689        {        {
5690        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5691        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5692        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));
5693        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5694        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5695        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5696        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);
5697        }        }
5698      else      else
5699        {        {
5700        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5701        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5702        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));
5703        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5704        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5705        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5706        }        }
# Line 5586  if (opcode == OP_ONCE) Line 5709  if (opcode == OP_ONCE)
5709  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5710    {    {
5711    /* Saving the previous values. */    /* Saving the previous values. */
5712    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5713    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5714    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5715    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5716    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5717    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5718    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);
5719    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5720        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5721        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5722        }
5723      else
5724        {
5725        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5726        allocate_stack(common, 2);
5727        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5728        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5729        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5730        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5731        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5732        }
5733    }    }
5734  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5735    {    {
5736    /* Saving the previous value. */    /* Saving the previous value. */
5737    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5738    allocate_stack(common, 1);    allocate_stack(common, 1);
5739    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);
5740    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5741    }    }
5742  else if (has_alternatives)  else if (has_alternatives)
# Line 5613  else if (has_alternatives) Line 5749  else if (has_alternatives)
5749  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5750  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5751    {    {
5752    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5753      {      {
5754      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5755      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5756        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)));
5757      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5758      }      }
5759    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5760      {      {
5761      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5762      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5763      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));
5764    
5765      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 5637  if (opcode == OP_COND || opcode == OP_SC Line 5773  if (opcode == OP_COND || opcode == OP_SC
5773      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));
5774    
5775      JUMPHERE(jump);      JUMPHERE(jump);
5776      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5777      }      }
5778    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5779      {      {
5780      /* Never has other case. */      /* Never has other case. */
5781      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5782    
5783      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5784      if (common->currententry == NULL)      if (common->currententry == NULL)
5785        stacksize = 0;        stacksize = 0;
5786      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 5652  if (opcode == OP_COND || opcode == OP_SC Line 5788  if (opcode == OP_COND || opcode == OP_SC
5788      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
5789        stacksize = stacksize == 0;        stacksize = stacksize == 0;
5790      else      else
5791        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5792    
5793      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5794        {        {
5795        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5796        if (stacksize != 0)        if (stacksize != 0)
5797          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5798        else        else
5799          {          {
5800          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5801            {            {
5802            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5803            cc += GET(cc, 1);            cc += GET(cc, 1);
5804            }            }
5805          else          else
5806            trypath = cc;            matchingpath = cc;
5807          }          }
5808        }        }
5809      else      else
5810        {        {
5811        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5812    
5813        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5814        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5815        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);
5816        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 5685  if (opcode == OP_COND || opcode == OP_SC Line 5821  if (opcode == OP_COND || opcode == OP_SC
5821        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));
5822        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5823        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));
5824        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5825        }        }
5826      }      }
5827    else    else
5828      {      {
5829      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5830      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5831      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5832      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5833        return NULL;        return NULL;
5834      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5835      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5836      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5837      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5838      }      }
5839    }    }
5840    
5841  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5842  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5843    return NULL;    return NULL;
5844    
# Line 5710  if (opcode == OP_ONCE) Line 5846  if (opcode == OP_ONCE)
5846    {    {
5847    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5848      {      {
5849      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);
5850      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5851      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5852        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5853      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5854        {        {
5855        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5856        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);
5857        }        }
5858      }      }
5859    else    else
5860      {      {
5861      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5862      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));
5863      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5864        {        {
5865        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5758  if (has_alternatives) Line 5894  if (has_alternatives)
5894    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5895      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5896    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5897      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5898    }    }
5899    
5900  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5901  if (offset != 0)  if (offset != 0)
5902    {    {
5903    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5904    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);
5905    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);
5906    }    }
# Line 5774  if (ket == OP_KETRMAX) Line 5910  if (ket == OP_KETRMAX)
5910    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5911      {      {
5912      if (has_alternatives)      if (has_alternatives)
5913        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5914      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5915      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5916        {        {
5917        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);
5918        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5919        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5920          free_stack(common, 1);          free_stack(common, 1);
# Line 5789  if (ket == OP_KETRMAX) Line 5925  if (ket == OP_KETRMAX)
5925      }      }
5926    else    else
5927      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5928    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5929    }    }
5930    
5931  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5932    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5933    
5934  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5935    {    {
5936    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5937    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5938    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5939      {      {
5940      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5807  if (bra == OP_BRAMINZERO) Line 5943  if (bra == OP_BRAMINZERO)
5943      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5944      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5945        {        {
5946        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);
5947        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5948        }        }
5949      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5826  cc += 1 + LINK_SIZE; Line 5962  cc += 1 + LINK_SIZE;
5962  return cc;  return cc;
5963  }  }
5964    
5965  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)
5966  {  {
5967  DEFINE_COMPILER;  DEFINE_COMPILER;
5968  backtrack_common *backtrack;  backtrack_common *backtrack;
5969  pcre_uchar opcode;  pcre_uchar opcode;
5970  int localptr;  int private_data_ptr;
5971  int cbraprivptr = 0;  int cbraprivptr = 0;
5972  int framesize;  int framesize;
5973  int stacksize;  int stacksize;
# Line 5850  if (*cc == OP_BRAPOSZERO) Line 5986  if (*cc == OP_BRAPOSZERO)
5986    }    }
5987    
5988  opcode = *cc;  opcode = *cc;
5989  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5990  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5991  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5992  switch(opcode)  switch(opcode)
5993    {    {
5994    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5863  switch(opcode) Line 5999  switch(opcode)
5999    case OP_CBRAPOS:    case OP_CBRAPOS:
6000    case OP_SCBRAPOS:    case OP_SCBRAPOS:
6001    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
6002      /* This case cannot be optimized in the same was as
6003      normal capturing brackets. */
6004      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
6005    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6006    offset <<= 1;    offset <<= 1;
6007    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5882  if (framesize < 0) Line 6021  if (framesize < 0)
6021      stacksize++;      stacksize++;
6022    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6023    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6024    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);
6025    
6026    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6027      {      {
# Line 5907  else Line 6046  else
6046    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6047    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6048    
6049    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6050    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));
6051    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6052    stack = 0;    stack = 0;
6053    if (!zero)    if (!zero)
6054      {      {
# Line 5935  while (*cc != OP_KETRPOS) Line 6074  while (*cc != OP_KETRPOS)
6074    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6075    cc += GET(cc, 1);    cc += GET(cc, 1);
6076    
6077    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6078    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6079      return NULL;      return NULL;
6080    
6081    if (framesize < 0)    if (framesize < 0)
6082      {      {
6083      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);
6084    
6085      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6086        {        {
# Line 5967  while (*cc != OP_KETRPOS) Line 6106  while (*cc != OP_KETRPOS)
6106      {      {
6107      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6108        {        {
6109        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));
6110        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6111        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);
6112        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5975  while (*cc != OP_KETRPOS) Line 6114  while (*cc != OP_KETRPOS)
6114        }        }
6115      else      else
6116        {        {
6117        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6118        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));
6119        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6120          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
# Line 5996  while (*cc != OP_KETRPOS) Line 6135  while (*cc != OP_KETRPOS)
6135    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6136    flush_stubs(common);    flush_stubs(common);
6137    
6138    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6139    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6140      return NULL;      return NULL;
6141    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 6014  while (*cc != OP_KETRPOS) Line 6153  while (*cc != OP_KETRPOS)
6153        {        {
6154        /* Last alternative. */        /* Last alternative. */
6155        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6156          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6157        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6158        }        }
6159      else      else
6160        {        {
6161        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6162        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));
6163        }        }
6164      }      }
# Line 6034  if (!zero) Line 6173  if (!zero)
6173    {    {
6174    if (framesize < 0)    if (framesize < 0)
6175      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));
6176    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6177      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));
6178    }    }
6179    
# Line 6136  if (end != NULL) Line 6275  if (end != NULL)
6275  return cc;  return cc;
6276  }  }
6277    
6278  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)
6279  {  {
6280  DEFINE_COMPILER;  DEFINE_COMPILER;
6281  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6147  pcre_uchar* end; Line 6286  pcre_uchar* end;
6286  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6287  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6288  struct sljit_label *label;  struct sljit_label *label;
6289  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6290  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);
6291  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6292  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);
6293  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6294    
6295  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6204  switch(opcode) Line 6343  switch(opcode)
6343    case OP_CRRANGE:    case OP_CRRANGE:
6344    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6345      {      {
6346      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6347      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6348        {        {
6349        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6221  switch(opcode) Line 6360  switch(opcode)
6360        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6361    
6362      label = LABEL();      label = LABEL();
6363      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6364      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6365        {        {
6366        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 6243  switch(opcode) Line 6382  switch(opcode)
6382    else    else
6383      {      {
6384      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6385        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6386      if (localptr == 0)      if (private_data_ptr == 0)
6387        allocate_stack(common, 2);        allocate_stack(common, 2);
6388      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6389      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6252  switch(opcode) Line 6391  switch(opcode)
6391      else      else
6392        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6393      label = LABEL();      label = LABEL();
6394      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6395      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6396      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
6397        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6273  switch(opcode) Line 6412  switch(opcode)
6412        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));
6413      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6414      }      }
6415    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6416    break;    break;
6417    
6418    case OP_MINSTAR:    case OP_MINSTAR:
6419    case OP_MINPLUS:    case OP_MINPLUS:
6420    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6421      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6422    if (localptr == 0)    if (private_data_ptr == 0)
6423      allocate_stack(common, 1);      allocate_stack(common, 1);
6424    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6425    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6426    break;    break;
6427    
6428    case OP_MINUPTO:    case OP_MINUPTO:
6429    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6430    if (localptr == 0)    if (private_data_ptr == 0)
6431      allocate_stack(common, 2);      allocate_stack(common, 2);
6432    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6433    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6434    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6435      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6436    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6437    break;    break;
6438    
6439    case OP_QUERY:    case OP_QUERY:
6440    case OP_MINQUERY:    case OP_MINQUERY:
6441    if (localptr == 0)    if (private_data_ptr == 0)
6442      allocate_stack(common, 1);      allocate_stack(common, 1);
6443    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6444    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6445      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6446    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6447    break;    break;
6448    
6449    case OP_EXACT:    case OP_EXACT:
6450    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6451    label = LABEL();    label = LABEL();
6452    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6453    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);
6454    JUMPTO(SLJIT_C_NOT_ZERO, label);    JUMPTO(SLJIT_C_NOT_ZERO, label);
6455    break;    break;
# Line 6319  switch(opcode) Line 6458  switch(opcode)
6458    case OP_POSPLUS:    case OP_POSPLUS:
6459    case OP_POSUPTO:    case OP_POSUPTO:
6460    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
6461      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6462    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
6463      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6464    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6465    label = LABEL();    label = LABEL();
6466    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6467    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6468    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
6469      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6339  switch(opcode) Line 6478  switch(opcode)
6478    
6479    case OP_POSQUERY:    case OP_POSQUERY:
6480    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6481    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6482    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6483    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6484    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
# Line 6354  decrease_call_count(common); Line 6493  decrease_call_count(common);
6493  return end;  return end;
6494  }  }
6495    
6496  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)
6497  {  {
6498  DEFINE_COMPILER;  DEFINE_COMPILER;
6499  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6398  add_jump(compiler, &backtrack->topbacktr Line 6537  add_jump(compiler, &backtrack->topbacktr
6537  return cc + 1;  return cc + 1;
6538  }  }
6539    
6540  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)
6541  {  {
6542  DEFINE_COMPILER;  DEFINE_COMPILER;
6543  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6544    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6545    
6546  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6547  if (common->currententry != NULL)  if (common->currententry != NULL)
6548    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6549    
6550  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6551      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6552  offset <<= 1;  offset <<= 1;
6553  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);
6554  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6555      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6556  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6557  }  }
6558    
6559  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)
6560  {  {
6561  DEFINE_COMPILER;  DEFINE_COMPILER;
6562  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6453  while (cc < ccend) Line 6595  while (cc < ccend)
6595      case OP_NOT:      case OP_NOT:
6596      case OP_NOTI:      case OP_NOTI:
6597      case OP_REVERSE:      case OP_REVERSE:
6598      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);
6599      break;      break;
6600    
6601      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6468  while (cc < ccend) Line 6610  while (cc < ccend)
6610      case OP_CHAR:      case OP_CHAR:
6611      case OP_CHARI:      case OP_CHARI:
6612      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6613        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);
6614      else      else
6615        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);
6616      break;      break;
6617    
6618      case OP_STAR:      case OP_STAR:
# Line 6538  while (cc < ccend) Line 6680  while (cc < ccend)
6680      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6681      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6682      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6683      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6684      break;      break;
6685    
6686      case OP_CLASS:      case OP_CLASS:
6687      case OP_NCLASS:      case OP_NCLASS:
6688      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)
6689        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6690      else      else
6691        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);
6692      break;      break;
6693    
6694  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
6695      case OP_XCLASS:      case OP_XCLASS:
6696      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)
6697        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6698      else      else
6699        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);
6700      break;      break;
6701  #endif  #endif
6702    
6703      case OP_REF:      case OP_REF:
6704      case OP_REFI:      case OP_REFI:
6705      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)
6706        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6707      else      else
6708        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);
6709      break;      break;
6710    
6711      case OP_RECURSE:      case OP_RECURSE:
6712      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6713      break;      break;
6714    
6715      case OP_ASSERT:      case OP_ASSERT:
# Line 6575  while (cc < ccend) Line 6717  while (cc < ccend)
6717      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6718      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6719      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6720      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6721      break;      break;
6722    
6723      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 6592  while (cc < ccend) Line 6734  while (cc < ccend)
6734        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6735        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6736        }        }
6737      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6738      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6739        decrease_call_count(common);        decrease_call_count(common);
6740      break;      break;
# Line 6605  while (cc < ccend) Line 6747  while (cc < ccend)
6747      case OP_SBRA:      case OP_SBRA:
6748      case OP_SCBRA:      case OP_SCBRA:
6749      case OP_SCOND:      case OP_SCOND:
6750      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6751      break;      break;
6752    
6753      case OP_BRAZERO:      case OP_BRAZERO:
6754      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6755        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6756      else      else
6757        {        {
6758        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6759        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6760        }        }
6761      break;      break;
6762    
# Line 6623  while (cc < ccend) Line 6765  while (cc < ccend)
6765      case OP_SBRAPOS:      case OP_SBRAPOS:
6766      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6767      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6768      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6769      break;      break;
6770    
6771      case OP_MARK:      case OP_MARK:
# Line 6647  while (cc < ccend) Line 6789  while (cc < ccend)
6789      case OP_FAIL:      case OP_FAIL:
6790      case OP_ACCEPT:      case OP_ACCEPT:
6791      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6792      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6793      break;      break;
6794    
6795      case OP_CLOSE:      case OP_CLOSE:
6796      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6797      break;      break;
6798    
6799      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 6672  SLJIT_ASSERT(cc == ccend); Line 6814  SLJIT_ASSERT(cc == ccend);
6814  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6815  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6816    
6817  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6818    do \    do \
6819      { \      { \
6820      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6821      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6822        return; \        return; \
6823      } \      } \
# Line 6683  SLJIT_ASSERT(cc == ccend); Line 6825  SLJIT_ASSERT(cc == ccend);
6825    
6826  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6827    
6828  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6829  {  {
6830  DEFINE_COMPILER;  DEFINE_COMPILER;
6831  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6693  int arg1 = -1, arg2 = -1; Line 6835  int arg1 = -1, arg2 = -1;
6835  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6836  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6837  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6838  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6839  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);
6840  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6841  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);
6842    
6843  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6844    
# Line 6708  switch(opcode) Line 6850  switch(opcode)
6850    case OP_CRRANGE:    case OP_CRRANGE:
6851    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6852      {      {
6853      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6854      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6855      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6856      free_stack(common, 1);      free_stack(common, 1);
6857      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);
6858      }      }
6859    else    else
6860      {      {
# Line 6732  switch(opcode) Line 6874  switch(opcode)
6874        }        }
6875      skip_char_back(common);      skip_char_back(common);
6876      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6877      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6878      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6879        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6880      JUMPHERE(jump);      JUMPHERE(jump);
6881      if (localptr == 0)      if (private_data_ptr == 0)
6882        free_stack(common, 2);        free_stack(common, 2);
6883      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6884        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6746  switch(opcode) Line 6888  switch(opcode)
6888    case OP_MINSTAR:    case OP_MINSTAR:
6889    case OP_MINPLUS:    case OP_MINPLUS:
6890    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6891    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6892    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6893    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6894    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6895    if (localptr == 0)    if (private_data_ptr == 0)
6896      free_stack(common, 1);      free_stack(common, 1);
6897    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6898      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6764  switch(opcode) Line 6906  switch(opcode)
6906      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6907      }      }
6908    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6909    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6910    
6911    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6912    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6775  switch(opcode) Line 6917  switch(opcode)
6917      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6918    
6919    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6920      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6921    else    else
6922      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);
6923    
6924    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6925    if (localptr == 0)    if (private_data_ptr == 0)
6926      free_stack(common, 2);      free_stack(common, 2);
6927    break;    break;
6928    
6929    case OP_QUERY:    case OP_QUERY:
6930    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6931    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6932    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);
6933    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6934    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6935    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6936    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6937    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6938    JUMPHERE(jump);    JUMPHERE(jump);
6939    if (localptr == 0)    if (private_data_ptr == 0)
6940      free_stack(common, 1);      free_stack(common, 1);
6941    break;    break;
6942    
# Line 6802  switch(opcode) Line 6944  switch(opcode)
6944    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6945    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6946    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6947    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6948    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6949    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6950    JUMPHERE(jump);    JUMPHERE(jump);
6951    if (localptr == 0)    if (private_data_ptr == 0)
6952      free_stack(common, 1);      free_stack(common, 1);
6953    break;    break;
6954    
# Line 6826  switch(opcode) Line 6968  switch(opcode)
6968    }    }
6969  }  }
6970    
6971  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)
6972  {  {
6973  DEFINE_COMPILER;  DEFINE_COMPILER;
6974  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6838  if ((type & 0x1) == 0) Line 6980  if ((type & 0x1) == 0)
6980    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6981    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6982    free_stack(common, 1);    free_stack(common, 1);
6983    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);
6984    return;    return;
6985    }    }
6986    
6987  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6988  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);
6989  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6990  free_stack(common, 2);  free_stack(common, 2);
6991  }  }
6992    
6993  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6994  {  {
6995  DEFINE_COMPILER;  DEFINE_COMPILER;
6996    
# Line 6870  else if (common->has_set_som || common-> Line 7012  else if (common->has_set_som || common->
7012    }    }
7013  }  }
7014    
7015  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7016  {  {
7017  DEFINE_COMPILER;  DEFINE_COMPILER;
7018  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6897  if (CURRENT_AS(assert_backtrack)->frames Line 7039  if (CURRENT_AS(assert_backtrack)->frames
7039    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7040      {      {
7041      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7042      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);
7043      free_stack(common, 1);      free_stack(common, 1);
7044      }      }
7045    return;    return;
# Line 6908  if (bra == OP_BRAZERO) Line 7050  if (bra == OP_BRAZERO)
7050    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
7051      {      {
7052      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7053      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);
7054      free_stack(common, 1);      free_stack(common, 1);
7055      return;      return;
7056      }      }
# Line 6918  if (bra == OP_BRAZERO) Line 7060  if (bra == OP_BRAZERO)
7060    
7061  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7062    {    {
7063    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);
7064    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7065    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));
7066    
7067    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7068    }    }
# Line 6932  if (bra == OP_BRAZERO) Line 7074  if (bra == OP_BRAZERO)
7074    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
7075    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));
7076    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7077    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
7078    JUMPHERE(brajump);    JUMPHERE(brajump);
7079    }    }
7080  }  }
7081    
7082  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7083  {  {
7084  DEFINE_COMPILER;  DEFINE_COMPILER;
7085  int opcode;  int opcode;
7086  int offset = 0;  int offset = 0;
7087  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7088  int stacksize;  int stacksize;
7089  int count;  int count;
7090  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6997  else if (ket == OP_KETRMIN) Line 7139  else if (ket == OP_KETRMIN)
7139        {        {
7140        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7141        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7142          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);
7143        else        else
7144          {          {
7145          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7146          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);
7147          }          }
7148        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7149          free_stack(common, 1);          free_stack(common, 1);
7150        }        }
7151      else      else
7152        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7153      }      }
7154    rminlabel = LABEL();    rminlabel = LABEL();
7155    }    }
# Line 7022  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7164  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7164    {    {
7165    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7166      {      {
7167      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);
7168      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7169      }      }
7170    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 7075  else if (*cc == OP_ALT) Line 7217  else if (*cc == OP_ALT)
7217    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7218    }    }
7219    
7220  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7221  if (current->topbacktracks)  if (current->topbacktracks)
7222    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7223    
# Line 7088  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7230  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7230      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7231      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))
7232        {        {
7233        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);
7234        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7235        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));
7236        }        }
7237      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7238      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
# Line 7119  if (has_alternatives) Line 7261  if (has_alternatives)
7261        cc += GET(cc, 1);        cc += GET(cc, 1);
7262        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7263          {          {
7264          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7265            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);
7266          else          else
7267            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7268          }          }
7269        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7270        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7271          return;          return;
7272        }        }
7273    
7274      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7275      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7276      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7277        {        {
7278        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7279          {          {
7280          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);
7281          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7282          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7283            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7284          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7285            {            {
7286            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7287            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);
7288            }            }
7289          }          }
7290        else        else
7291          {          {
7292          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));
7293          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7294            {            {
7295            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 7188  if (has_alternatives) Line 7330  if (has_alternatives)
7330    
7331      if (offset != 0)      if (offset != 0)
7332        {        {
7333        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7334        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);
7335        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);
7336        }        }
7337    
7338      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7339    
7340      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7341        {        {
# Line 7202  if (has_alternatives) Line 7344  if (has_alternatives)
7344        jumplist = jumplist->next;        jumplist = jumplist->next;
7345        }        }
7346    
7347      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7348      if (current->topbacktracks)      if (current->topbacktracks)
7349        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7350      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 7217  if (has_alternatives) Line 7359  if (has_alternatives)
7359      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)
7360    
7361        {        {
7362        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);
7363        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7364        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));
7365        }        }
7366      JUMPHERE(cond);      JUMPHERE(cond);
7367      }      }
7368    
7369    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7370    if (localptr == 0)    if (private_data_ptr == 0)
7371      free_stack(common, 1);      free_stack(common, 1);
7372    }    }
7373    
7374  if (offset != 0)  if (offset != 0)
7375    {    {
7376    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7377    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7378    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7379    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7380    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7381    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);
7382    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7383        free_stack(common, 3);
7384        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7385        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7386        }
7387      else
7388        {
7389        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7390        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7391        free_stack(common, 2);
7392        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7393        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7394        }
7395    }    }
7396  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7397    {    {
7398    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));
7399    free_stack(common, 1);    free_stack(common, 1);
7400    }    }
7401  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7260  else if (opcode == OP_ONCE) Line 7414  else if (opcode == OP_ONCE)
7414      }      }
7415    
7416    JUMPHERE(once);    JUMPHERE(once);
7417    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7418    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7419      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));
7420    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7421      {      {
7422      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7423      /* See the comment below. */      /* See the comment below. */
7424      free_stack(common, 2);      free_stack(common, 2);
7425      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7426      }      }
7427    }    }
7428    
# Line 7277  if (ket == OP_KETRMAX) Line 7431  if (ket == OP_KETRMAX)
7431    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7432    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7433      free_stack(common, 1);      free_stack(common, 1);
7434    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);
7435    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7436      {      {
7437      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7438      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7439      JUMPHERE(brazero);      JUMPHERE(brazero);
7440      free_stack(common, 1);      free_stack(common, 1);
7441      }      }
# Line 7304  else if (ket == OP_KETRMIN) Line 7458  else if (ket == OP_KETRMIN)
7458  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7459    {    {
7460    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7461    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7462    JUMPHERE(brazero);    JUMPHERE(brazero);
7463    }    }
7464  }  }
7465    
7466  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7467  {  {
7468  DEFINE_COMPILER;  DEFINE_COMPILER;
7469  int offset;  int offset;
# Line 7330  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7484  if (CURRENT_AS(bracketpos_backtrack)->fr
7484    return;    return;
7485    }    }
7486    
7487  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);
7488  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7489    
7490  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7341  if (current->topbacktracks) Line 7495  if (current->topbacktracks)
7495    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7496    JUMPHERE(jump);    JUMPHERE(jump);
7497    }    }
7498  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));
7499  }  }
7500    
7501  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7502  {  {
7503  assert_backtrack backtrack;  assert_backtrack backtrack;
7504    
# Line 7353  current->topbacktracks = NULL; Line 7507  current->topbacktracks = NULL;
7507  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7508  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7509    {    {
7510    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7511    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7512    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7513    }    }
7514  else  else
7515    {    {
7516    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7517    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7518    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7519    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7520    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7521    }    }
7522  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7523  }  }
7524    
7525  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7526  {  {
7527  DEFINE_COMPILER;  DEFINE_COMPILER;
7528    
# Line 7454  while (current) Line 7608  while (current)
7608  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7609      case OP_XCLASS:      case OP_XCLASS:
7610  #endif  #endif
7611      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7612      break;      break;
7613    
7614      case OP_REF:      case OP_REF:
7615      case OP_REFI:      case OP_REFI:
7616      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7617      break;      break;
7618    
7619      case OP_RECURSE:      case OP_RECURSE:
7620      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7621      break;      break;
7622    
7623      case OP_ASSERT:      case OP_ASSERT:
7624      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7625      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7626      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7627      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7628      break;      break;
7629    
7630      case OP_ONCE:      case OP_ONCE:
# Line 7481  while (current) Line 7635  while (current)
7635      case OP_SBRA:      case OP_SBRA:
7636      case OP_SCBRA:      case OP_SCBRA:
7637      case OP_SCOND:      case OP_SCOND:
7638      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7639      break;      break;
7640    
7641      case OP_BRAZERO:      case OP_BRAZERO:
7642      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7643        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7644      else      else
7645        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7646      break;      break;
7647    
7648      case OP_BRAPOS:      case OP_BRAPOS:
# Line 7496  while (current) Line 7650  while (current)
7650      case OP_SBRAPOS:      case OP_SBRAPOS:
7651      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7652      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7653      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7654      break;      break;
7655    
7656      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7657      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7658      break;      break;
7659    
7660      case OP_MARK:      case OP_MARK:
# Line 7537  DEFINE_COMPILER; Line 7691  DEFINE_COMPILER;
7691  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7692  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
7693  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7694  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7695  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7696  int alternativesize;  int alternativesize;
7697  BOOL needsframe;  BOOL needsframe;
# Line 7557  common->currententry->entry = LABEL(); Line 7711  common->currententry->entry = LABEL();
7711  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7712    
7713  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7714  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7715  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
7716  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7717  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
7718  if (needsframe)  if (needsframe)
7719    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 7582  while (1) Line 7736  while (1)
7736    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7737      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7738    
7739    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7740    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7741      {      {
7742      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7592  while (1) Line 7746  while (1)
7746    
7747    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7748    
7749    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7750    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7751      {      {
7752      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7625  if (needsframe) Line 7779  if (needsframe)
7779  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
7780    
7781  JUMPHERE(jump);  JUMPHERE(jump);
7782  copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7783  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7784  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
7785  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7786  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
# Line 7636  common->quitlabel = save_quitlabel; Line 7790  common->quitlabel = save_quitlabel;
7790  common->quit = save_quit;  common->quit = save_quit;
7791  }  }
7792    
7793  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKINGPATH
7794  #undef CURRENT_AS  #undef CURRENT_AS
7795    
7796  void  void
# Line 7648  compiler_common common_data; Line 7802  compiler_common common_data;
7802  compiler_common *common = &common_data;  compiler_common *common = &common_data;
7803  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
7804  pcre_study_data *study;  pcre_study_data *study;
7805  int localsize;  int private_data_size;
7806  pcre_uchar *ccend;  pcre_uchar *ccend;
7807  executable_functions *functions;  executable_functions *functions;
7808  void *executable_func;  void *executable_func;
# Line 7714  common->name_count = re->name_count; Line 7868  common->name_count = re->name_count;
7868  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
7869  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
7870  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
7871  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
7872  common->utf = (re->options & PCRE_UTF8) != 0;  common->utf = (re->options & PCRE_UTF8) != 0;
7873  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
7874  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
# Line 7724  ccend = bracketend(rootbacktrack.cc); Line 7878  ccend = bracketend(rootbacktrack.cc);
7878    
7879  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7880  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7881    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7882    if (!common->optimized_cbracket)
7883      return;
7884    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7885    
7886  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7887  localsize = get_localspace(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7888  if (localsize < 0)  if (private_data_size < 0)
7889      {
7890      SLJIT_FREE(common->optimized_cbracket);
7891    return;    return;
7892      }
7893    
7894  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7895  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
# Line 7758  if ((common->ovector_start & sizeof(slji Line 7919  if ((common->ovector_start & sizeof(slji
7919    
7920  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
7921  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7922  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7923  if (localsize > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7924      {
7925      SLJIT_FREE(common->optimized_cbracket);
7926    return;    return;
7927  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));    }
7928  if (!common->localptrs)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7929    if (!common->private_data_ptrs)
7930      {
7931      SLJIT_FREE(common->optimized_cbracket);
7932    return;    return;
7933  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));    }
7934  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7935    set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);