/[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 977 by zherczeg, Sun Jun 17 06:20:52 2012 UTC revision 1120 by chpe, Tue Oct 16 15:57:38 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 181  typedef struct stub_list { Line 184  typedef struct stub_list {
184    enum stub_types type;    enum stub_types type;
185    int data;    int data;
186    struct sljit_jump *start;    struct sljit_jump *start;
187    struct sljit_label *leave;    struct sljit_label *quit;
188    struct stub_list *next;    struct stub_list *next;
189  } stub_list;  } stub_list;
190    
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct backtrack_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
# Line 208  typedef struct assert_backtrack { Line 211  typedef struct assert_backtrack {
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *trypath;    struct sljit_label *matchingpath;
217  } assert_backtrack;  } assert_backtrack;
218    
219  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
220    backtrack_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 230  typedef struct bracket_backtrack { Line 233  typedef struct bracket_backtrack {
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_backtrack;  } bracket_backtrack;
238    
239  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
240    backtrack_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
# Line 245  typedef struct bracketpos_backtrack { Line 248  typedef struct bracketpos_backtrack {
248    
249  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
250    backtrack_common common;    backtrack_common common;
251    struct sljit_label *trypath;    struct sljit_label *matchingpath;
252  } braminzero_backtrack;  } braminzero_backtrack;
253    
254  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
255    backtrack_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *trypath;    struct sljit_label *matchingpath;
258  } iterator_backtrack;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 268  typedef struct recurse_backtrack { Line 271  typedef struct recurse_backtrack {
271    backtrack_common common;    backtrack_common common;
272  } recurse_backtrack;  } recurse_backtrack;
273    
274    #define MAX_RANGE_SIZE 6
275    
276  typedef struct compiler_common {  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    
280    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
281    int *localptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 290  typedef struct compiler_common { Line 298  typedef struct compiler_common {
298    /* Points to the marked string. */    /* Points to the marked string. */
299    int mark_ptr;    int mark_ptr;
300    
301    /* Other  */    /* Flipped and lower case tables. */
302    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
303    sljit_w lcc;    sljit_w lcc;
304      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
305    int mode;    int mode;
306      /* Newline control. */
307    int nltype;    int nltype;
308    int newline;    int newline;
309    int bsr_nltype;    int bsr_nltype;
310      /* Dollar endonly. */
311    int endonly;    int endonly;
312    BOOL has_set_som;    BOOL has_set_som;
313      /* Tables. */
314    sljit_w ctypes;    sljit_w ctypes;
315      int digits[2 + MAX_RANGE_SIZE];
316      /* Named capturing brackets. */
317    sljit_uw name_table;    sljit_uw name_table;
318    sljit_w name_count;    sljit_w name_count;
319    sljit_w name_entry_size;    sljit_w name_entry_size;
320    
321    /* Labels and jump lists. */    /* Labels and jump lists. */
322    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
323    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
324    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
325    stub_list *stubs;    stub_list *stubs;
326    recurse_entry *entries;    recurse_entry *entries;
327    recurse_entry *currententry;    recurse_entry *currententry;
328    jump_list *partialmatch;    jump_list *partialmatch;
329    jump_list *leave;    jump_list *quit;
330    jump_list *accept;    jump_list *accept;
331    jump_list *calllimit;    jump_list *calllimit;
332    jump_list *stackalloc;    jump_list *stackalloc;
# Line 329  typedef struct compiler_common { Line 343  typedef struct compiler_common {
343  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
344    BOOL use_ucp;    BOOL use_ucp;
345  #endif  #endif
346    #ifndef COMPILE_PCRE32
347    jump_list *utfreadchar;    jump_list *utfreadchar;
348    #endif
349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
350    jump_list *utfreadtype8;    jump_list *utfreadtype8;
351  #endif  #endif
# Line 349  typedef struct compare_context { Line 365  typedef struct compare_context {
365    union {    union {
366      sljit_i asint;      sljit_i asint;
367      sljit_uh asushort;      sljit_uh asushort;
368  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
369      sljit_ub asbyte;      sljit_ub asbyte;
370      sljit_ub asuchars[4];      sljit_ub asuchars[4];
371  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
372      sljit_uh asuchars[2];      sljit_uh asuchars[2];
373  #endif  #elif defined COMPILE_PCRE32
374        sljit_ui asuchars[1];
375  #endif  #endif
376    } c;    } c;
377    union {    union {
378      sljit_i asint;      sljit_i asint;
379      sljit_uh asushort;      sljit_uh asushort;
380  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
381      sljit_ub asbyte;      sljit_ub asbyte;
382      sljit_ub asuchars[4];      sljit_ub asuchars[4];
383  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
384      sljit_uh asuchars[2];      sljit_uh asuchars[2];
385  #endif  #elif defined COMPILE_PCRE32
386        sljit_ui asuchars[1];
387  #endif  #endif
388    } oc;    } oc;
389  #endif  #endif
# Line 396  enum { Line 412  enum {
412  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
413  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
414    
415  /* Locals layout. */  /* Local space layout. */
416  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
417  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
418  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 412  the start pointers when the end of the c Line 428  the start pointers when the end of the c
428  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
429  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
430  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
431  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
432    
433  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
434  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
435  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
436  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
437  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
438  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
439    #elif defined COMPILE_PCRE32
440    #define MOV_UCHAR  SLJIT_MOV_UI
441    #define MOVU_UCHAR SLJIT_MOVU_UI
442  #else  #else
443  #error Unsupported compiling mode  #error Unsupported compiling mode
444  #endif  #endif
 #endif  
445    
446  /* Shortcuts. */  /* Shortcuts. */
447  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 461  return cc; Line 478  return cc;
478    
479  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
480   next_opcode   next_opcode
481   get_localspace   get_private_data_length
482   set_localptrs   set_private_data_ptrs
483   get_framesize   get_framesize
484   init_frame   init_frame
485   get_localsize   get_private_data_length_for_copy
486   copy_locals   copy_private_data
487   compile_trypath   compile_matchingpath
488   compile_backtrackpath   compile_backtrackingpath
489  */  */
490    
491  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 667  switch(*cc) Line 684  switch(*cc)
684    }    }
685  }  }
686    
687  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
688        case OP_MINSTAR: \
689        case OP_MINPLUS: \
690        case OP_QUERY: \
691        case OP_MINQUERY: \
692        case OP_MINSTARI: \
693        case OP_MINPLUSI: \
694        case OP_QUERYI: \
695        case OP_MINQUERYI: \
696        case OP_NOTMINSTAR: \
697        case OP_NOTMINPLUS: \
698        case OP_NOTQUERY: \
699        case OP_NOTMINQUERY: \
700        case OP_NOTMINSTARI: \
701        case OP_NOTMINPLUSI: \
702        case OP_NOTQUERYI: \
703        case OP_NOTMINQUERYI:
704    
705    #define CASE_ITERATOR_PRIVATE_DATA_2A \
706        case OP_STAR: \
707        case OP_PLUS: \
708        case OP_STARI: \
709        case OP_PLUSI: \
710        case OP_NOTSTAR: \
711        case OP_NOTPLUS: \
712        case OP_NOTSTARI: \
713        case OP_NOTPLUSI:
714    
715    #define CASE_ITERATOR_PRIVATE_DATA_2B \
716        case OP_UPTO: \
717        case OP_MINUPTO: \
718        case OP_UPTOI: \
719        case OP_MINUPTOI: \
720        case OP_NOTUPTO: \
721        case OP_NOTMINUPTO: \
722        case OP_NOTUPTOI: \
723        case OP_NOTMINUPTOI:
724    
725    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
726        case OP_TYPEMINSTAR: \
727        case OP_TYPEMINPLUS: \
728        case OP_TYPEQUERY: \
729        case OP_TYPEMINQUERY:
730    
731    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
732        case OP_TYPESTAR: \
733        case OP_TYPEPLUS:
734    
735    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
736        case OP_TYPEUPTO: \
737        case OP_TYPEMINUPTO:
738    
739    static int get_class_iterator_size(pcre_uchar *cc)
740  {  {
741  int localspace = 0;  switch(*cc)
742      {
743      case OP_CRSTAR:
744      case OP_CRPLUS:
745      return 2;
746    
747      case OP_CRMINSTAR:
748      case OP_CRMINPLUS:
749      case OP_CRQUERY:
750      case OP_CRMINQUERY:
751      return 1;
752    
753      case OP_CRRANGE:
754      case OP_CRMINRANGE:
755      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
756        return 0;
757      return 2;
758    
759      default:
760      return 0;
761      }
762    }
763    
764    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
765    {
766    int private_data_length = 0;
767  pcre_uchar *alternative;  pcre_uchar *alternative;
768    pcre_uchar *name;
769    pcre_uchar *end = NULL;
770    int space, size, bracketlen, i;
771    
772  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
773  while (cc < ccend)  while (cc < ccend)
774    {    {
775      space = 0;
776      size = 0;
777      bracketlen = 0;
778    switch(*cc)    switch(*cc)
779      {      {
780      case OP_SET_SOM:      case OP_SET_SOM:
# Line 681  while (cc < ccend) Line 782  while (cc < ccend)
782      cc += 1;      cc += 1;
783      break;      break;
784    
785        case OP_REF:
786        case OP_REFI:
787        common->optimized_cbracket[GET2(cc, 1)] = 0;
788        cc += 1 + IMM2_SIZE;
789        break;
790    
791      case OP_ASSERT:      case OP_ASSERT:
792      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
793      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 690  while (cc < ccend) Line 797  while (cc < ccend)
797      case OP_BRAPOS:      case OP_BRAPOS:
798      case OP_SBRA:      case OP_SBRA:
799      case OP_SBRAPOS:      case OP_SBRAPOS:
800      case OP_SCOND:      private_data_length += sizeof(sljit_w);
801      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
802      break;      break;
803    
804      case OP_CBRAPOS:      case OP_CBRAPOS:
805      case OP_SCBRAPOS:      case OP_SCBRAPOS:
806      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
807      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
808        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
809      break;      break;
810    
811      case OP_COND:      case OP_COND:
812      /* Might be a hidden SCOND. */      case OP_SCOND:
813      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
814      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
815        localspace += sizeof(sljit_w);        {
816      cc += 1 + LINK_SIZE;        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
817          common->optimized_cbracket[bracketlen] = 0;
818          }
819        else if (bracketlen == OP_NCREF)
820          {
821          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
822          name = (pcre_uchar *)common->name_table;
823          alternative = name;
824          for (i = 0; i < common->name_count; i++)
825            {
826            if (GET2(name, 0) == bracketlen) break;
827            name += common->name_entry_size;
828            }
829          SLJIT_ASSERT(i != common->name_count);
830    
831          for (i = 0; i < common->name_count; i++)
832            {
833            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
834              common->optimized_cbracket[GET2(alternative, 0)] = 0;
835            alternative += common->name_entry_size;
836            }
837          }
838    
839        if (*cc == OP_COND)
840          {
841          /* Might be a hidden SCOND. */
842          alternative = cc + GET(cc, 1);
843          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
844            private_data_length += sizeof(sljit_w);
845          }
846        else
847          private_data_length += sizeof(sljit_w);
848        bracketlen = 1 + LINK_SIZE;
849        break;
850    
851        case OP_BRA:
852        bracketlen = 1 + LINK_SIZE;
853        break;
854    
855        case OP_CBRA:
856        case OP_SCBRA:
857        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
858        break;
859    
860        CASE_ITERATOR_PRIVATE_DATA_1
861        space = 1;
862        size = -2;
863        break;
864    
865        CASE_ITERATOR_PRIVATE_DATA_2A
866        space = 2;
867        size = -2;
868        break;
869    
870        CASE_ITERATOR_PRIVATE_DATA_2B
871        space = 2;
872        size = -(2 + IMM2_SIZE);
873        break;
874    
875        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
876        space = 1;
877        size = 1;
878        break;
879    
880        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
881        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
882          space = 2;
883        size = 1;
884        break;
885    
886        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
887        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
888          space = 2;
889        size = 1 + IMM2_SIZE;
890        break;
891    
892        case OP_CLASS:
893        case OP_NCLASS:
894        size += 1 + 32 / sizeof(pcre_uchar);
895        space = get_class_iterator_size(cc + size);
896      break;      break;
897    
898    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
899        case OP_XCLASS:
900        size = GET(cc, 1);
901        space = get_class_iterator_size(cc + size);
902        break;
903    #endif
904    
905      case OP_RECURSE:      case OP_RECURSE:
906      /* Set its value only once. */      /* Set its value only once. */
907      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 734  while (cc < ccend) Line 927  while (cc < ccend)
927        return -1;        return -1;
928      break;      break;
929      }      }
930    
931      if (space > 0 && cc >= end)
932        private_data_length += sizeof(sljit_w) * space;
933    
934      if (size != 0)
935        {
936        if (size < 0)
937          {
938          cc += -size;
939    #ifdef SUPPORT_UTF
940          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
941    #endif
942          }
943        else
944          cc += size;
945        }
946    
947      if (bracketlen > 0)
948        {
949        if (cc >= end)
950          {
951          end = bracketend(cc);
952          if (end[-1 - LINK_SIZE] == OP_KET)
953            end = NULL;
954          }
955        cc += bracketlen;
956        }
957    }    }
958  return localspace;  return private_data_length;
959  }  }
960    
961  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
962  {  {
963  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
964  pcre_uchar *alternative;  pcre_uchar *alternative;
965    pcre_uchar *end = NULL;
966    int space, size, bracketlen;
967    
968  while (cc < ccend)  while (cc < ccend)
969    {    {
970      space = 0;
971      size = 0;
972      bracketlen = 0;
973    switch(*cc)    switch(*cc)
974      {      {
975      case OP_ASSERT:      case OP_ASSERT:
# Line 756  while (cc < ccend) Line 982  while (cc < ccend)
982      case OP_SBRA:      case OP_SBRA:
983      case OP_SBRAPOS:      case OP_SBRAPOS:
984      case OP_SCOND:      case OP_SCOND:
985      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
986      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
987      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
988      break;      break;
989    
990      case OP_CBRAPOS:      case OP_CBRAPOS:
991      case OP_SCBRAPOS:      case OP_SCBRAPOS:
992      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
993      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
994      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
995      break;      break;
996    
997      case OP_COND:      case OP_COND:
# Line 773  while (cc < ccend) Line 999  while (cc < ccend)
999      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1000      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1001        {        {
1002        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1003        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1004        }        }
1005      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1006        break;
1007    
1008        case OP_BRA:
1009        bracketlen = 1 + LINK_SIZE;
1010        break;
1011    
1012        case OP_CBRA:
1013        case OP_SCBRA:
1014        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1015        break;
1016    
1017        CASE_ITERATOR_PRIVATE_DATA_1
1018        space = 1;
1019        size = -2;
1020        break;
1021    
1022        CASE_ITERATOR_PRIVATE_DATA_2A
1023        space = 2;
1024        size = -2;
1025        break;
1026    
1027        CASE_ITERATOR_PRIVATE_DATA_2B
1028        space = 2;
1029        size = -(2 + IMM2_SIZE);
1030        break;
1031    
1032        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1033        space = 1;
1034        size = 1;
1035      break;      break;
1036    
1037        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1038        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1039          space = 2;
1040        size = 1;
1041        break;
1042    
1043        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1044        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1045          space = 2;
1046        size = 1 + IMM2_SIZE;
1047        break;
1048    
1049        case OP_CLASS:
1050        case OP_NCLASS:
1051        size += 1 + 32 / sizeof(pcre_uchar);
1052        space = get_class_iterator_size(cc + size);
1053        break;
1054    
1055    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1056        case OP_XCLASS:
1057        size = GET(cc, 1);
1058        space = get_class_iterator_size(cc + size);
1059        break;
1060    #endif
1061    
1062      default:      default:
1063      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1064      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1065      break;      break;
1066      }      }
1067    
1068      if (space > 0 && cc >= end)
1069        {
1070        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1071        private_data_ptr += sizeof(sljit_w) * space;
1072        }
1073    
1074      if (size != 0)
1075        {
1076        if (size < 0)
1077          {
1078          cc += -size;
1079    #ifdef SUPPORT_UTF
1080          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1081    #endif
1082          }
1083        else
1084          cc += size;
1085        }
1086    
1087      if (bracketlen > 0)
1088        {
1089        if (cc >= end)
1090          {
1091          end = bracketend(cc);
1092          if (end[-1 - LINK_SIZE] == OP_KET)
1093            end = NULL;
1094          }
1095        cc += bracketlen;
1096        }
1097    }    }
1098  }  }
1099    
# Line 960  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1270  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1270  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1271  }  }
1272    
1273  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1274  {  {
1275  int localsize = 2;  int private_data_length = 2;
1276    int size;
1277  pcre_uchar *alternative;  pcre_uchar *alternative;
1278  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1279  while (cc < ccend)  while (cc < ccend)
1280    {    {
1281      size = 0;
1282    switch(*cc)    switch(*cc)
1283      {      {
1284      case OP_ASSERT:      case OP_ASSERT:
# Line 979  while (cc < ccend) Line 1291  while (cc < ccend)
1291      case OP_SBRA:      case OP_SBRA:
1292      case OP_SBRAPOS:      case OP_SBRAPOS:
1293      case OP_SCOND:      case OP_SCOND:
1294      localsize++;      private_data_length++;
1295      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1296      break;      break;
1297    
1298      case OP_CBRA:      case OP_CBRA:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1301          private_data_length++;
1302      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1303      break;      break;
1304    
1305      case OP_CBRAPOS:      case OP_CBRAPOS:
1306      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1307      localsize += 2;      private_data_length += 2;
1308      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1309      break;      break;
1310    
# Line 999  while (cc < ccend) Line 1312  while (cc < ccend)
1312      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1313      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1314      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1315        localsize++;        private_data_length++;
1316      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1317      break;      break;
1318    
1319        CASE_ITERATOR_PRIVATE_DATA_1
1320        if (PRIVATE_DATA(cc))
1321          private_data_length++;
1322        cc += 2;
1323    #ifdef SUPPORT_UTF
1324        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1325    #endif
1326        break;
1327    
1328        CASE_ITERATOR_PRIVATE_DATA_2A
1329        if (PRIVATE_DATA(cc))
1330          private_data_length += 2;
1331        cc += 2;
1332    #ifdef SUPPORT_UTF
1333        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1334    #endif
1335        break;
1336    
1337        CASE_ITERATOR_PRIVATE_DATA_2B
1338        if (PRIVATE_DATA(cc))
1339          private_data_length += 2;
1340        cc += 2 + IMM2_SIZE;
1341    #ifdef SUPPORT_UTF
1342        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1343    #endif
1344        break;
1345    
1346        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1347        if (PRIVATE_DATA(cc))
1348          private_data_length++;
1349        cc += 1;
1350        break;
1351    
1352        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1353        if (PRIVATE_DATA(cc))
1354          private_data_length += 2;
1355        cc += 1;
1356        break;
1357    
1358        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1359        if (PRIVATE_DATA(cc))
1360          private_data_length += 2;
1361        cc += 1 + IMM2_SIZE;
1362        break;
1363    
1364        case OP_CLASS:
1365        case OP_NCLASS:
1366    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1367        case OP_XCLASS:
1368        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1369    #else
1370        size = 1 + 32 / (int)sizeof(pcre_uchar);
1371    #endif
1372        if (PRIVATE_DATA(cc))
1373          private_data_length += get_class_iterator_size(cc + size);
1374        cc += size;
1375        break;
1376    
1377      default:      default:
1378      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1379      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1010  while (cc < ccend) Line 1381  while (cc < ccend)
1381      }      }
1382    }    }
1383  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1384  return localsize;  return private_data_length;
1385  }  }
1386    
1387  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1388    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1389  {  {
1390  DEFINE_COMPILER;  DEFINE_COMPILER;
1391  int srcw[2];  int srcw[2];
1392  int count;  int count, size;
1393  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1394  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1395  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1083  while (status != end) Line 1454  while (status != end)
1454        case OP_SBRAPOS:        case OP_SBRAPOS:
1455        case OP_SCOND:        case OP_SCOND:
1456        count = 1;        count = 1;
1457        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1458        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1459        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1460        break;        break;
1461    
1462        case OP_CBRA:        case OP_CBRA:
1463        case OP_SCBRA:        case OP_SCBRA:
1464        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1465        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1466            count = 1;
1467            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1468            }
1469        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1470        break;        break;
1471    
1472        case OP_CBRAPOS:        case OP_CBRAPOS:
1473        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1474        count = 2;        count = 2;
1475          srcw[0] = PRIVATE_DATA(cc);
1476        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1477        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1478        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1479        break;        break;
1480    
# Line 1110  while (status != end) Line 1484  while (status != end)
1484        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1485          {          {
1486          count = 1;          count = 1;
1487          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1488          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1489          }          }
1490        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1491        break;        break;
1492    
1493          CASE_ITERATOR_PRIVATE_DATA_1
1494          if (PRIVATE_DATA(cc))
1495            {
1496            count = 1;
1497            srcw[0] = PRIVATE_DATA(cc);
1498            }
1499          cc += 2;
1500    #ifdef SUPPORT_UTF
1501          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1502    #endif
1503          break;
1504    
1505          CASE_ITERATOR_PRIVATE_DATA_2A
1506          if (PRIVATE_DATA(cc))
1507            {
1508            count = 2;
1509            srcw[0] = PRIVATE_DATA(cc);
1510            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1511            }
1512          cc += 2;
1513    #ifdef SUPPORT_UTF
1514          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1515    #endif
1516          break;
1517    
1518          CASE_ITERATOR_PRIVATE_DATA_2B
1519          if (PRIVATE_DATA(cc))
1520            {
1521            count = 2;
1522            srcw[0] = PRIVATE_DATA(cc);
1523            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1524            }
1525          cc += 2 + IMM2_SIZE;
1526    #ifdef SUPPORT_UTF
1527          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1528    #endif
1529          break;
1530    
1531          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1532          if (PRIVATE_DATA(cc))
1533            {
1534            count = 1;
1535            srcw[0] = PRIVATE_DATA(cc);
1536            }
1537          cc += 1;
1538          break;
1539    
1540          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1541          if (PRIVATE_DATA(cc))
1542            {
1543            count = 2;
1544            srcw[0] = PRIVATE_DATA(cc);
1545            srcw[1] = srcw[0] + sizeof(sljit_w);
1546            }
1547          cc += 1;
1548          break;
1549    
1550          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1551          if (PRIVATE_DATA(cc))
1552            {
1553            count = 2;
1554            srcw[0] = PRIVATE_DATA(cc);
1555            srcw[1] = srcw[0] + sizeof(sljit_w);
1556            }
1557          cc += 1 + IMM2_SIZE;
1558          break;
1559    
1560          case OP_CLASS:
1561          case OP_NCLASS:
1562    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1563          case OP_XCLASS:
1564          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1565    #else
1566          size = 1 + 32 / (int)sizeof(pcre_uchar);
1567    #endif
1568          if (PRIVATE_DATA(cc))
1569            switch(get_class_iterator_size(cc + size))
1570              {
1571              case 1:
1572              count = 1;
1573              srcw[0] = PRIVATE_DATA(cc);
1574              break;
1575    
1576              case 2:
1577              count = 2;
1578              srcw[0] = PRIVATE_DATA(cc);
1579              srcw[1] = srcw[0] + sizeof(sljit_w);
1580              break;
1581    
1582              default:
1583              SLJIT_ASSERT_STOP();
1584              break;
1585              }
1586          cc += size;
1587          break;
1588    
1589        default:        default:
1590        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1591        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1218  if (save) Line 1688  if (save)
1688  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1689  }  }
1690    
1691  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1692    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1693    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1694    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1695    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1696    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1697    
1698    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1699  {  {
1700  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1701  }  }
# Line 1228  static SLJIT_INLINE void set_jumps(jump_ Line 1705  static SLJIT_INLINE void set_jumps(jump_
1705  while (list)  while (list)
1706    {    {
1707    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1708    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1709    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1710    list = list->next;    list = list->next;
1711    }    }
# Line 1255  if (list_item) Line 1732  if (list_item)
1732    list_item->type = type;    list_item->type = type;
1733    list_item->data = data;    list_item->data = data;
1734    list_item->start = start;    list_item->start = start;
1735    list_item->leave = LABEL();    list_item->quit = LABEL();
1736    list_item->next = common->stubs;    list_item->next = common->stubs;
1737    common->stubs = list_item;    common->stubs = list_item;
1738    }    }
# Line 1275  while (list_item) Line 1752  while (list_item)
1752      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1753      break;      break;
1754      }      }
1755    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1756    list_item = list_item->next;    list_item = list_item->next;
1757    }    }
1758  common->stubs = NULL;  common->stubs = NULL;
# Line 1360  loop = LABEL(); Line 1837  loop = LABEL();
1837  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1838  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1839  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1840  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1841  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1842  #endif  #endif
1843  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1844  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
# Line 1385  else Line 1862  else
1862    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1863  }  }
1864    
1865  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1866  {  {
1867  DEFINE_COMPILER;  DEFINE_COMPILER;
1868    
# Line 1395  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1872  SLJIT_ASSERT(common->start_used_ptr != 0
1872  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1873  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1874  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1875  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1876    
1877  /* Store match begin and end. */  /* Store match begin and end. */
1878  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1879  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1880  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1881  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1882  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1883  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1884  #endif  #endif
1885  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1886    
1887  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1888  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1889  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1890  #endif  #endif
1891  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1892    
1893  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1894  }  }
1895    
1896  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1524  if (c <= 127 && bit == 0x20) Line 2001  if (c <= 127 && bit == 0x20)
2001    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2002    
2003  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2004  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2005    return 0;    return 0;
2006    
2007  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2008    
2009  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2010  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1543  if (common->utf && c > 127) Line 2020  if (common->utf && c > 127)
2020  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2021  return (0 << 8) | bit;  return (0 << 8) | bit;
2022    
2023  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2024    
 #ifdef COMPILE_PCRE16  
2025  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2026  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2027    {    {
# Line 1556  if (common->utf && c > 65535) Line 2032  if (common->utf && c > 65535)
2032    }    }
2033  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2034  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2035    
2036  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2037  }  }
2038    
2039  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 1656  static void read_char(compiler_common *c Line 2131  static void read_char(compiler_common *c
2131  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2132  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2133  DEFINE_COMPILER;  DEFINE_COMPILER;
2134  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2135  struct sljit_jump *jump;  struct sljit_jump *jump;
2136  #endif  #endif
2137    
2138  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2139  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2140  if (common->utf)  if (common->utf)
2141    {    {
2142  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2143    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2144  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2146  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2147    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2148    JUMPHERE(jump);    JUMPHERE(jump);
2149    }    }
2150  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2151  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2152  }  }
2153    
# Line 1683  static void peek_char(compiler_common *c Line 2156  static void peek_char(compiler_common *c
2156  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2157  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2158  DEFINE_COMPILER;  DEFINE_COMPILER;
2159  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2160  struct sljit_jump *jump;  struct sljit_jump *jump;
2161  #endif  #endif
2162    
2163  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2164  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2165  if (common->utf)  if (common->utf)
2166    {    {
2167  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2168    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2169  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2171  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2172    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2173    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2174    JUMPHERE(jump);    JUMPHERE(jump);
2175    }    }
2176  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2177  }  }
2178    
2179  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2180  {  {
2181  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2182  DEFINE_COMPILER;  DEFINE_COMPILER;
2183  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2184  struct sljit_jump *jump;  struct sljit_jump *jump;
2185  #endif  #endif
2186    
# Line 1718  if (common->utf) Line 2189  if (common->utf)
2189    {    {
2190    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2191    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2193    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2194    it is needed in most cases. */    it is needed in most cases. */
2195    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2196    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2197    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2198    JUMPHERE(jump);    JUMPHERE(jump);
2199  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2200    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2201    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2202    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 1737  if (common->utf) Line 2207  if (common->utf)
2207    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2208    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2209    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2210  #endif  #elif defined COMPILE_PCRE32
2211  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2212      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2213      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2214      JUMPHERE(jump);
2215    #endif /* COMPILE_PCRE[8|16|32] */
2216    return;    return;
2217    }    }
2218  #endif  #endif /* SUPPORT_UTF */
2219  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2220  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2221  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2222  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2223  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2224  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2225  #endif  #endif
2226  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2227  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2228  JUMPHERE(jump);  JUMPHERE(jump);
2229  #endif  #endif
2230  }  }
# Line 1759  static void skip_char_back(compiler_comm Line 2233  static void skip_char_back(compiler_comm
2233  {  {
2234  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2235  DEFINE_COMPILER;  DEFINE_COMPILER;
2236  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2237    #if defined COMPILE_PCRE8
2238  struct sljit_label *label;  struct sljit_label *label;
2239    
2240  if (common->utf)  if (common->utf)
# Line 1771  if (common->utf) Line 2246  if (common->utf)
2246    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2247    return;    return;
2248    }    }
2249  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2250  if (common->utf)  if (common->utf)
2251    {    {
2252    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 1785  if (common->utf) Line 2259  if (common->utf)
2259    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2260    return;    return;
2261    }    }
2262  #endif  #endif /* COMPILE_PCRE[8|16] */
2263    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2264  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2265  }  }
2266    
# Line 1816  else Line 2291  else
2291    
2292  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2293    
2294  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2295  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2296  {  {
2297  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 1910  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); Line 2385  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2385  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2386  }  }
2387    
2388  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2389    
 #ifdef COMPILE_PCRE16  
2390  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2391  {  {
2392  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 1937  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2411  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2411  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2412  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2413  }  }
 #endif /* COMPILE_PCRE16 */  
2414    
2415  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2416    
2417  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2418    
# Line 1979  struct sljit_label *newlinelabel = NULL; Line 2452  struct sljit_label *newlinelabel = NULL;
2452  struct sljit_jump *start;  struct sljit_jump *start;
2453  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2454  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2455  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2456  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2457  #endif  #endif
2458  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 1994  if (firstline) Line 2467  if (firstline)
2467    {    {
2468    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2469    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2470    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2471    
2472    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2473      {      {
# Line 2006  if (firstline) Line 2478  if (firstline)
2478      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2479      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2480      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2481        JUMPHERE(end);
2482      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2483      }      }
2484    else    else
# Line 2017  if (firstline) Line 2490  if (firstline)
2490      read_char(common);      read_char(common);
2491      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2492      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2493        JUMPHERE(end);
2494      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2495      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2496      }      }
2497    
2498    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2499    }    }
2500    
2501  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2035  if (newlinecheck) Line 2508  if (newlinecheck)
2508    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2509    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2510    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2511  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2512    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2513  #endif  #endif
2514    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2515    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2057  if (newlinecheck) Line 2530  if (newlinecheck)
2530    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2531    
2532  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2533  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2534    #if defined COMPILE_PCRE8
2535  if (common->utf)  if (common->utf)
2536    {    {
2537    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
# Line 2065  if (common->utf) Line 2539  if (common->utf)
2539    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2540    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2541    }    }
2542  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2543  if (common->utf)  if (common->utf)
2544    {    {
2545    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
# Line 2077  if (common->utf) Line 2550  if (common->utf)
2550    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2551    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2552    }    }
2553  #endif  #endif /* COMPILE_PCRE[8|16] */
2554    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2555  JUMPHERE(start);  JUMPHERE(start);
2556    
2557  if (newlinecheck)  if (newlinecheck)
# Line 2089  if (newlinecheck) Line 2563  if (newlinecheck)
2563  return mainloop;  return mainloop;
2564  }  }
2565    
2566    #define MAX_N_CHARS 3
2567    
2568    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2569    {
2570    DEFINE_COMPILER;
2571    struct sljit_label *start;
2572    struct sljit_jump *quit;
2573    pcre_uint32 chars[MAX_N_CHARS * 2];
2574    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2575    int location = 0;
2576    pcre_int32 len, c, bit, caseless;
2577    int must_stop;
2578    
2579    /* We do not support alternatives now. */
2580    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2581      return FALSE;
2582    
2583    while (TRUE)
2584      {
2585      caseless = 0;
2586      must_stop = 1;
2587      switch(*cc)
2588        {
2589        case OP_CHAR:
2590        must_stop = 0;
2591        cc++;
2592        break;
2593    
2594        case OP_CHARI:
2595        caseless = 1;
2596        must_stop = 0;
2597        cc++;
2598        break;
2599    
2600        case OP_SOD:
2601        case OP_SOM:
2602        case OP_SET_SOM:
2603        case OP_NOT_WORD_BOUNDARY:
2604        case OP_WORD_BOUNDARY:
2605        case OP_EODN:
2606        case OP_EOD:
2607        case OP_CIRC:
2608        case OP_CIRCM:
2609        case OP_DOLL:
2610        case OP_DOLLM:
2611        /* Zero width assertions. */
2612        cc++;
2613        continue;
2614    
2615        case OP_PLUS:
2616        case OP_MINPLUS:
2617        case OP_POSPLUS:
2618        cc++;
2619        break;
2620    
2621        case OP_EXACT:
2622        cc += 1 + IMM2_SIZE;
2623        break;
2624    
2625        case OP_PLUSI:
2626        case OP_MINPLUSI:
2627        case OP_POSPLUSI:
2628        caseless = 1;
2629        cc++;
2630        break;
2631    
2632        case OP_EXACTI:
2633        caseless = 1;
2634        cc += 1 + IMM2_SIZE;
2635        break;
2636    
2637        default:
2638        must_stop = 2;
2639        break;
2640        }
2641    
2642      if (must_stop == 2)
2643          break;
2644    
2645      len = 1;
2646    #ifdef SUPPORT_UTF
2647      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2648    #endif
2649    
2650      if (caseless && char_has_othercase(common, cc))
2651        {
2652        caseless = char_get_othercase_bit(common, cc);
2653        if (caseless == 0)
2654          return FALSE;
2655    #ifdef COMPILE_PCRE8
2656        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2657    #else
2658        if ((caseless & 0x100) != 0)
2659          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2660        else
2661          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2662    #endif
2663        }
2664      else
2665        caseless = 0;
2666    
2667      while (len > 0 && location < MAX_N_CHARS * 2)
2668        {
2669        c = *cc;
2670        bit = 0;
2671        if (len == (caseless & 0xff))
2672          {
2673          bit = caseless >> 8;
2674          c |= bit;
2675          }
2676    
2677        chars[location] = c;
2678        chars[location + 1] = bit;
2679    
2680        len--;
2681        location += 2;
2682        cc++;
2683        }
2684    
2685      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2686        break;
2687      }
2688    
2689    /* At least two characters are required. */
2690    if (location < 2 * 2)
2691        return FALSE;
2692    
2693    if (firstline)
2694      {
2695      SLJIT_ASSERT(common->first_line_end != 0);
2696      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2697      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2698      }
2699    else
2700      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2701    
2702    start = LABEL();
2703    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2704    
2705    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2706    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2707    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2708    if (chars[1] != 0)
2709      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2710    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2711    if (location > 2 * 2)
2712      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2713    if (chars[3] != 0)
2714      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2715    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2716    if (location > 2 * 2)
2717      {
2718      if (chars[5] != 0)
2719        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2720      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2721      }
2722    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2723    
2724    JUMPHERE(quit);
2725    
2726    if (firstline)
2727      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2728    else
2729      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2730    return TRUE;
2731    }
2732    
2733    #undef MAX_N_CHARS
2734    
2735  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2736  {  {
2737  DEFINE_COMPILER;  DEFINE_COMPILER;
2738  struct sljit_label *start;  struct sljit_label *start;
2739  struct sljit_jump *leave;  struct sljit_jump *quit;
2740  struct sljit_jump *found;  struct sljit_jump *found;
2741  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2742    
2743  if (firstline)  if (firstline)
2744    {    {
2745    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2746      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2747    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2748    }    }
2749    
2750  start = LABEL();  start = LABEL();
2751  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2752  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2753    
2754  oc = first_char;  oc = first_char;
# Line 2121  if (first_char == oc) Line 2765  if (first_char == oc)
2765  else  else
2766    {    {
2767    bit = first_char ^ oc;    bit = first_char ^ oc;
2768    if (ispowerof2(bit))    if (is_powerof2(bit))
2769      {      {
2770      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2771      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2137  else Line 2781  else
2781    }    }
2782    
2783  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2784  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2785  JUMPHERE(found);  JUMPHERE(found);
2786  JUMPHERE(leave);  JUMPHERE(quit);
2787    
2788  if (firstline)  if (firstline)
2789    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2790  }  }
2791    
2792  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2170  DEFINE_COMPILER; Line 2795  DEFINE_COMPILER;
2795  struct sljit_label *loop;  struct sljit_label *loop;
2796  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2797  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2798  struct sljit_jump *leave;  struct sljit_jump *quit;
2799  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2800  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2801  jump_list *newline = NULL;  jump_list *newline = NULL;
2802    
2803  if (firstline)  if (firstline)
2804    {    {
2805    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2806      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2807    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2808    }    }
2809    
# Line 2192  if (common->nltype == NLTYPE_FIXED && co Line 2818  if (common->nltype == NLTYPE_FIXED && co
2818    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2819    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2820    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2821  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2822    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2823  #endif  #endif
2824    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2825    
2826    loop = LABEL();    loop = LABEL();
2827    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));
2828    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2829    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2830    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2831    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2832    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2833    
2834    JUMPHERE(leave);    JUMPHERE(quit);
2835    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2836    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2837    
# Line 2229  set_jumps(newline, loop); Line 2855  set_jumps(newline, loop);
2855    
2856  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2857    {    {
2858    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2859    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2860    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2861    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2862    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2863    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2864  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2865    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2866  #endif  #endif
2867    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2868    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2869    JUMPHERE(leave);    JUMPHERE(quit);
2870    }    }
2871  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2872  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2873    
2874  if (firstline)  if (firstline)
2875    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2876  }  }
2877    
2878  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2879  {  {
2880  DEFINE_COMPILER;  DEFINE_COMPILER;
2881  struct sljit_label *start;  struct sljit_label *start;
2882  struct sljit_jump *leave;  struct sljit_jump *quit;
2883  struct sljit_jump *found;  struct sljit_jump *found;
2884  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2885  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2261  struct sljit_jump *jump; Line 2887  struct sljit_jump *jump;
2887    
2888  if (firstline)  if (firstline)
2889    {    {
2890    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2891      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2892    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2893    }    }
2894    
2895  start = LABEL();  start = LABEL();
2896  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2897  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2898  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2899  if (common->utf)  if (common->utf)
# Line 2289  if (common->utf) Line 2916  if (common->utf)
2916    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2917  #endif  #endif
2918  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2919  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2920    #if defined COMPILE_PCRE8
2921  if (common->utf)  if (common->utf)
2922    {    {
2923    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2924    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2925    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2926    }    }
2927  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2928  if (common->utf)  if (common->utf)
2929    {    {
2930    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2307  if (common->utf) Line 2934  if (common->utf)
2934    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2935    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2936    }    }
2937  #endif  #endif /* COMPILE_PCRE[8|16] */
2938    #endif /* SUPPORT_UTF */
2939  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2940  JUMPHERE(found);  JUMPHERE(found);
2941  JUMPHERE(leave);  JUMPHERE(quit);
2942    
2943  if (firstline)  if (firstline)
2944    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2945  }  }
2946    
2947  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2325  struct sljit_jump *alreadyfound; Line 2953  struct sljit_jump *alreadyfound;
2953  struct sljit_jump *found;  struct sljit_jump *found;
2954  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2955  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2956  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2957    
2958  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2959  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2356  if (req_char == oc) Line 2984  if (req_char == oc)
2984  else  else
2985    {    {
2986    bit = req_char ^ oc;    bit = req_char ^ oc;
2987    if (ispowerof2(bit))    if (is_powerof2(bit))
2988      {      {
2989      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2990      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 2508  if (common->use_ucp) Line 3136  if (common->use_ucp)
3136    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
3137    JUMPHERE(jump);    JUMPHERE(jump);
3138    }    }
3139  else  else
3140  #endif  #endif
3141      {
3142    #ifndef COMPILE_PCRE8
3143      /* TMP2 may be destroyed by peek_char. */
3144      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3145      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3146    #elif defined SUPPORT_UTF
3147      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3148      jump = NULL;
3149      if (common->utf)
3150        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3151    #endif
3152      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3153      OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3154      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3155    #ifndef COMPILE_PCRE8
3156      JUMPHERE(jump);
3157    #elif defined SUPPORT_UTF
3158      if (jump != NULL)
3159        JUMPHERE(jump);
3160    #endif /* COMPILE_PCRE8 */
3161      }
3162    JUMPHERE(skipread);
3163    
3164    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3165    sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3166    }
3167    
3168    /*
3169      range format:
3170    
3171      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3172      ranges[1] = first bit (0 or 1)
3173      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3174    */
3175    
3176    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3177    {
3178    DEFINE_COMPILER;
3179    struct sljit_jump *jump;
3180    
3181    if (ranges[0] < 0)
3182      return FALSE;
3183    
3184    switch(ranges[0])
3185      {
3186      case 1:
3187      if (readch)
3188        read_char(common);
3189      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3190      return TRUE;
3191    
3192      case 2:
3193      if (readch)
3194        read_char(common);
3195      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3196      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3197      return TRUE;
3198    
3199      case 4:
3200      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3201        {
3202        if (readch)
3203          read_char(common);
3204        if (ranges[1] != 0)
3205          {
3206          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3207          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3208          }
3209        else
3210          {
3211          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3212          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3213          JUMPHERE(jump);
3214          }
3215        return TRUE;
3216        }
3217      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3218        {
3219        if (readch)
3220          read_char(common);
3221        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3222        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3223        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3224        return TRUE;
3225        }
3226      return FALSE;
3227    
3228      default:
3229      return FALSE;
3230      }
3231    }
3232    
3233    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3234    {
3235    int i, bit, length;
3236    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3237    
3238    bit = ctypes[0] & flag;
3239    ranges[0] = -1;
3240    ranges[1] = bit != 0 ? 1 : 0;
3241    length = 0;
3242    
3243    for (i = 1; i < 256; i++)
3244      if ((ctypes[i] & flag) != bit)
3245        {
3246        if (length >= MAX_RANGE_SIZE)
3247          return;
3248        ranges[2 + length] = i;
3249        length++;
3250        bit ^= flag;
3251        }
3252    
3253    if (bit != 0)
3254      {
3255      if (length >= MAX_RANGE_SIZE)
3256        return;
3257      ranges[2 + length] = 256;
3258      length++;
3259      }
3260    ranges[0] = length;
3261    }
3262    
3263    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3264    {
3265    int ranges[2 + MAX_RANGE_SIZE];
3266    pcre_uint8 bit, cbit, all;
3267    int i, byte, length = 0;
3268    
3269    bit = bits[0] & 0x1;
3270    ranges[1] = bit;
3271    /* Can be 0 or 255. */
3272    all = -bit;
3273    
3274    for (i = 0; i < 256; )
3275      {
3276      byte = i >> 3;
3277      if ((i & 0x7) == 0 && bits[byte] == all)
3278        i += 8;
3279      else
3280        {
3281        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3282        if (cbit != bit)
3283          {
3284          if (length >= MAX_RANGE_SIZE)
3285            return FALSE;
3286          ranges[2 + length] = i;
3287          length++;
3288          bit = cbit;
3289          all = -cbit;
3290          }
3291        i++;
3292        }
3293      }
3294    
3295    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3296    {    {
3297  #ifndef COMPILE_PCRE8    if (length >= MAX_RANGE_SIZE)
3298    /* TMP2 may be destroyed by peek_char. */      return FALSE;
3299    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    ranges[2 + length] = 256;
3300    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    length++;
 #elif defined SUPPORT_UTF  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
   jump = NULL;  
   if (common->utf)  
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #endif  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);  
   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);  
   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (jump != NULL)  
     JUMPHERE(jump);  
 #endif /* COMPILE_PCRE8 */  
3301    }    }
3302  JUMPHERE(skipread);  ranges[0] = length;
3303    
3304  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  return check_ranges(common, ranges, backtracks, FALSE);
 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
3305  }  }
3306    
3307  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 2548  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3315  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3315  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3316  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3317  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3318  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3319  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3320  if (common->utf)  if (common->utf)
3321    {    {
# Line 2559  if (common->utf) Line 3326  if (common->utf)
3326  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3327    }    }
3328  #endif  #endif
3329  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3330  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3331  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3332  }  }
# Line 2576  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 3343  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
3343  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3344  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3345  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3346  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3347  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3348  if (common->utf)  if (common->utf)
3349    {    {
# Line 2597  if (common->utf) Line 3364  if (common->utf)
3364  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3365    }    }
3366  #endif  #endif
3367  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3368  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3369    
3370  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2614  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3381  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3381  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3382  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3383  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3384  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3385  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3386  if (common->utf)  if (common->utf)
3387    {    {
# Line 2625  if (common->utf) Line 3392  if (common->utf)
3392  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3393    }    }
3394  #endif  #endif
3395  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3396  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3397    
3398  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2715  sljit_emit_fast_return(compiler, RETURN_ Line 3482  sljit_emit_fast_return(compiler, RETURN_
3482  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3483  {  {
3484  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3485  int c1, c2;  pcre_uint32 c1, c2;
3486  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3487  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3488    const ucd_record *ur;
3489    const pcre_uint32 *pp;
3490    
3491  while (src1 < end1)  while (src1 < end1)
3492    {    {
# Line 2725  while (src1 < end1) Line 3494  while (src1 < end1)
3494      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3495    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3496    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3497    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3498      if (c1 != c2 && c1 != c2 + ur->other_case)
3499        {
3500        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3501        for (;;)
3502          {
3503          if (c1 < *pp) return NULL;
3504          if (c1 == *pp++) break;
3505          }
3506        }
3507    }    }
3508  return src2;  return src2;
3509  }  }
# Line 2747  if (caseless && char_has_othercase(commo Line 3525  if (caseless && char_has_othercase(commo
3525    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3526    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3527    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3528  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3529    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3530    othercasebit &= 0xff;    othercasebit &= 0xff;
3531  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
 #ifdef COMPILE_PCRE16  
3532    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3533    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3534      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3535    else    else
3536      othercasebit &= 0xff;      othercasebit &= 0xff;
3537  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3538    }    }
3539    
3540  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3541    {    {
3542  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3543  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3544    if (context->length >= 4)    if (context->length >= 4)
3545      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 2772  if (context->sourcereg == -1) Line 3548  if (context->sourcereg == -1)
3548    else    else
3549  #endif  #endif
3550      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3551  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3552  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3553    if (context->length >= 4)    if (context->length >= 4)
3554      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3555    else    else
3556  #endif  #endif
3557      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3558  #endif  #elif defined COMPILE_PCRE32
3559  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3560    #endif /* COMPILE_PCRE[8|16|32] */
3561    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3562    }    }
3563    
# Line 2810  do Line 3586  do
3586      }      }
3587    context->ucharptr++;    context->ucharptr++;
3588    
3589  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3590    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))
3591  #else  #elif defined COMPILE_PCRE16
3592    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3593    #elif defined COMPILE_PCRE32
3594      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3595  #endif  #endif
3596      {      {
3597    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3598      if (context->length >= 4)      if (context->length >= 4)
3599        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);
3600  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3601      else if (context->length >= 2)      else if (context->length >= 2)
3602        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);
3603      else if (context->length >= 1)      else if (context->length >= 1)
3604        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);
3605  #else  #elif defined COMPILE_PCRE16
3606      else if (context->length >= 2)      else if (context->length >= 2)
3607        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);
3608  #endif  #endif /* COMPILE_PCRE[8|16] */
3609    #elif defined COMPILE_PCRE32
3610        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3611    #endif /* COMPILE_PCRE[8|16|32] */
3612      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3613    
3614      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2837  do Line 3619  do
3619        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));
3620        break;        break;
3621    
3622    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3623        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3624        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3625          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 2851  do Line 3634  do
3634        break;        break;
3635  #endif  #endif
3636    
3637    #endif /* COMPILE_PCRE[8|16] */
3638    
3639        default:        default:
3640        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3641        break;        break;
# Line 2861  do Line 3646  do
3646  #else  #else
3647    
3648    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
3649    if (context->length > 0)    if (context->length > 0)
3650      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3651  #else  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3652    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3653    
3654    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 2912  return cc; Line 3693  return cc;
3693      } \      } \
3694    charoffset = (value);    charoffset = (value);
3695    
3696  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)
3697  {  {
3698  DEFINE_COMPILER;  DEFINE_COMPILER;
3699  jump_list *found = NULL;  jump_list *found = NULL;
3700  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3701  unsigned int c;  pcre_int32 c, charoffset;
3702  int compares;  const pcre_uint32 *other_cases;
3703  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3704  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3705    int compares, invertcmp, numberofcmps;
3706  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3707  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3708  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3709  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3710  unsigned int typeoffset;  pcre_int32 typeoffset;
3711  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3712    
3713  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3714       not necessary in utf mode even in 8 bit mode. */
3715  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3716  read_char(common);  read_char(common);
3717    
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3725  if ((*cc++ & XCL_MAP) != 0)
3725      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3726  #endif  #endif
3727    
3728    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3729    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3730    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3731    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3732    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3733    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3734        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3735        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3736        }
3737    
3738  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3739    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3022  while (*cc != XCL_END) Line 3806  while (*cc != XCL_END)
3806        needschar = TRUE;        needschar = TRUE;
3807        break;        break;
3808    
3809          case PT_CLIST:
3810          needschar = TRUE;
3811          break;
3812    
3813        default:        default:
3814        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3815        break;        break;
# Line 3231  while (*cc != XCL_END) Line 4019  while (*cc != XCL_END)
4019        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);
4020        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4021        break;        break;
4022    
4023          case PT_CLIST:
4024          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4025    
4026          /* At least three characters are required.
4027             Otherwise this case would be handled by the normal code path. */
4028          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4029          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4030    
4031          /* Optimizing character pairs, if their difference is power of 2. */
4032          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4033            {
4034            if (charoffset == 0)
4035              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4036            else
4037              {
4038              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4039              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4040              }
4041            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4042            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4043            other_cases += 2;
4044            }
4045          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4046            {
4047            if (charoffset == 0)
4048              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4049            else
4050              {
4051              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4052              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4053              }
4054            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4055            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4056    
4057            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4058            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4059    
4060            other_cases += 3;
4061            }
4062          else
4063            {
4064            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4065            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4066            }
4067    
4068          while (*other_cases != NOTACHAR)
4069            {
4070            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4071            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4072            }
4073          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4074          break;
4075        }        }
4076      cc += 2;      cc += 2;
4077      }      }
# Line 3249  if (found != NULL) Line 4090  if (found != NULL)
4090    
4091  #endif  #endif
4092    
4093  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)
4094  {  {
4095  DEFINE_COMPILER;  DEFINE_COMPILER;
4096  int length;  int length;
# Line 3285  switch(type) Line 4126  switch(type)
4126    
4127    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4128    case OP_DIGIT:    case OP_DIGIT:
4129      /* Digits are usually 0-9, so it is worth to optimize them. */
4130      if (common->digits[0] == -2)
4131        get_ctype_ranges(common, ctype_digit, common->digits);
4132    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4133    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4134    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4135    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4136      if (!check_ranges(common, common->digits, backtracks, TRUE))
4137        {
4138        read_char8_type(common);
4139        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4140        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4141        }
4142      if (type == OP_NOT_DIGIT)
4143        common->digits[1] ^= 1;
4144    return cc;    return cc;
4145    
4146    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3335  switch(type) Line 4187  switch(type)
4187      {      {
4188      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4189      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));
4190  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4191    #if defined COMPILE_PCRE8
4192      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4193      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);
4194      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4195  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4196      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4197      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4198      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);
4199      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4200      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4201      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4202  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4203      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4204    #endif /* COMPILE_PCRE[8|16] */
4205      return cc;      return cc;
4206      }      }
4207  #endif  #endif
# Line 3370  switch(type) Line 4222  switch(type)
4222    propdata[2] = cc[0];    propdata[2] = cc[0];
4223    propdata[3] = cc[1];    propdata[3] = cc[1];
4224    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4225    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4226    return cc + 2;    return cc + 2;
4227  #endif  #endif
4228  #endif  #endif
# Line 3416  switch(type) Line 4268  switch(type)
4268    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4269    read_char(common);    read_char(common);
4270    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4271    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));
4272    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4273      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4274      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4275    
4276    label = LABEL();    label = LABEL();
4277    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);
4278    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4279    read_char(common);    read_char(common);
4280    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4281    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));
4282    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);
4283    
4284      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4285      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4286      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4287      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4288      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4289      JUMPTO(SLJIT_C_NOT_ZERO, label);
4290    
4291    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4292    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4293      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4294    
4295    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4296      {      {
4297      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 3554  switch(type) Line 4417  switch(type)
4417    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));
4418    
4419    if (!common->endonly)    if (!common->endonly)
4420      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4421    else    else
4422      {      {
4423      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 3634  switch(type) Line 4497  switch(type)
4497      }      }
4498    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4499    bit = c ^ oc;    bit = c ^ oc;
4500    if (ispowerof2(bit))    if (is_powerof2(bit))
4501      {      {
4502      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4503      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 3642  switch(type) Line 4505  switch(type)
4505      }      }
4506    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4507    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4508    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4509    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4510    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4511    return cc + length;    return cc + length;
# Line 3695  switch(type) Line 4558  switch(type)
4558      {      {
4559      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4560      bit = c ^ oc;      bit = c ^ oc;
4561      if (ispowerof2(bit))      if (is_powerof2(bit))
4562        {        {
4563        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4564        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 3712  switch(type) Line 4575  switch(type)
4575    case OP_NCLASS:    case OP_NCLASS:
4576    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4577    read_char(common);    read_char(common);
4578      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4579        return cc + 32 / sizeof(pcre_uchar);
4580    
4581  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4582    jump[0] = NULL;    jump[0] = NULL;
4583  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3740  switch(type) Line 4606  switch(type)
4606  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4607    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4608    
4609  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4610    case OP_XCLASS:    case OP_XCLASS:
4611    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4612    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4613  #endif  #endif
4614    
# Line 3776  SLJIT_ASSERT_STOP(); Line 4642  SLJIT_ASSERT_STOP();
4642  return cc;  return cc;
4643  }  }
4644    
4645  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)
4646  {  {
4647  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4648  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3839  if (context.length > 0) Line 4705  if (context.length > 0)
4705    }    }
4706    
4707  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4708  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4709  }  }
4710    
4711  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 3865  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4731  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4731  }  }
4732    
4733  /* Forward definitions. */  /* Forward definitions. */
4734  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4735  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4736    
4737  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4738    do \    do \
# Line 3896  static void compile_backtrackpath(compil Line 4762  static void compile_backtrackpath(compil
4762    
4763  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4764    
4765  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)
4766  {  {
4767  DEFINE_COMPILER;  DEFINE_COMPILER;
4768  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3978  if (jump != NULL) Line 4844  if (jump != NULL)
4844  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4845  }  }
4846    
4847  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)
4848  {  {
4849  DEFINE_COMPILER;  DEFINE_COMPILER;
4850  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4049  if (!minimize) Line 4915  if (!minimize)
4915      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4916    
4917    label = LABEL();    label = LABEL();
4918    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4919    
4920    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4921      {      {
# Line 4077  if (!minimize) Line 4943  if (!minimize)
4943      }      }
4944    
4945    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4946    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4947    
4948    decrease_call_count(common);    decrease_call_count(common);
4949    return cc;    return cc;
# Line 4097  if (min == 0) Line 4963  if (min == 0)
4963  else  else
4964    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4965    
4966  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4967  if (max > 0)  if (max > 0)
4968    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));
4969    
4970  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4971  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4972    
4973  if (min > 1)  if (min > 1)
# Line 4109  if (min > 1) Line 4975  if (min > 1)
4975    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4976    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4977    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4978    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);
4979    }    }
4980  else if (max > 0)  else if (max > 0)
4981    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4122  decrease_call_count(common); Line 4988  decrease_call_count(common);
4988  return cc;  return cc;
4989  }  }
4990    
4991  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)
4992  {  {
4993  DEFINE_COMPILER;  DEFINE_COMPILER;
4994  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4179  add_jump(compiler, &backtrack->topbacktr Line 5045  add_jump(compiler, &backtrack->topbacktr
5045  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5046  }  }
5047    
5048  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)
5049  {  {
5050  DEFINE_COMPILER;  DEFINE_COMPILER;
5051  int framesize;  int framesize;
5052  int localptr;  int private_data_ptr;
5053  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5054  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5055  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4192  jump_list *tmp = NULL; Line 5058  jump_list *tmp = NULL;
5058  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5059  jump_list **found;  jump_list **found;
5060  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5061  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5062  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5063  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5064  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5065  struct sljit_jump *jump;  struct sljit_jump *jump;
5066  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5071  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5071    bra = *cc;    bra = *cc;
5072    cc++;    cc++;
5073    }    }
5074  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5075  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5076  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5077  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5078  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5079  opcode = *cc;  opcode = *cc;
5080  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5081  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4226  if (bra == OP_BRAMINZERO) Line 5092  if (bra == OP_BRAMINZERO)
5092    
5093  if (framesize < 0)  if (framesize < 0)
5094    {    {
5095    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);
5096    allocate_stack(common, 1);    allocate_stack(common, 1);
5097    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5098    }    }
5099  else  else
5100    {    {
5101    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5102    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5103    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));
5104    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5105    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5106    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5107    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5108    }    }
5109    
5110  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5111  common->leavelabel = NULL;  common->quitlabel = NULL;
5112  common->leave = NULL;  common->quit = NULL;
5113  while (1)  while (1)
5114    {    {
5115    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4255  while (1) Line 5121  while (1)
5121      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5122    
5123    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5124    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5125    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5126      {      {
5127      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5128      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5129      common->leave = save_leave;      common->quit = save_quit;
5130      common->accept = save_accept;      common->accept = save_accept;
5131      return NULL;      return NULL;
5132      }      }
# Line 4270  while (1) Line 5136  while (1)
5136    
5137    /* Reset stack. */    /* Reset stack. */
5138    if (framesize < 0)    if (framesize < 0)
5139      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);
5140    else {    else {
5141      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5142        {        {
5143        /* 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. */
5144        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));
5145        }        }
5146      else      else
5147        {        {
5148        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);
5149        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5150        }        }
5151    }    }
# Line 4297  while (1) Line 5163  while (1)
5163          {          {
5164          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));
5165          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));
5166          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5167          }          }
5168        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));
5169        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 4305  while (1) Line 5171  while (1)
5171      else if (framesize >= 0)      else if (framesize >= 0)
5172        {        {
5173        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5174        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));
5175        }        }
5176      }      }
5177    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5178    
5179    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5180    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5181      {      {
5182      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5183      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5184      common->leave = save_leave;      common->quit = save_quit;
5185      common->accept = save_accept;      common->accept = save_accept;
5186      return NULL;      return NULL;
5187      }      }
# Line 4328  while (1) Line 5194  while (1)
5194    cc += GET(cc, 1);    cc += GET(cc, 1);
5195    }    }
5196  /* None of them matched. */  /* None of them matched. */
5197  if (common->leave != NULL)  if (common->quit != NULL)
5198    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5199    
5200  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5201    {    {
# Line 4356  if (opcode == OP_ASSERT || opcode == OP_ Line 5222  if (opcode == OP_ASSERT || opcode == OP_
5222        }        }
5223      else      else
5224        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5225      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5226      }      }
5227    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5228    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4381  if (opcode == OP_ASSERT || opcode == OP_ Line 5247  if (opcode == OP_ASSERT || opcode == OP_
5247      {      {
5248      if (bra == OP_BRA)      if (bra == OP_BRA)
5249        {        {
5250        /* 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. */
5251        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));
5252        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5253        }        }
5254      else      else
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 + 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));
5258        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5259        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);
5260        }        }
# Line 4396  if (opcode == OP_ASSERT || opcode == OP_ Line 5262  if (opcode == OP_ASSERT || opcode == OP_
5262    
5263    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5264      {      {
5265      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5266      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5267      }      }
5268    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5269      {      {
5270      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5271      JUMPHERE(brajump);      JUMPHERE(brajump);
5272      if (framesize >= 0)      if (framesize >= 0)
5273        {        {
5274        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);
5275        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5276        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));
5277        }        }
5278      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5279      }      }
# Line 4435  else Line 5301  else
5301        }        }
5302      else      else
5303        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5304      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5305      }      }
5306    
5307    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5308      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5309    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5310      {      {
5311      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5312      JUMPHERE(brajump);      JUMPHERE(brajump);
5313      }      }
5314    
# Line 4454  else Line 5320  else
5320      }      }
5321    }    }
5322    
5323  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5324  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5325  common->leave = save_leave;  common->quit = save_quit;
5326  common->accept = save_accept;  common->accept = save_accept;
5327  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5328  }  }
# Line 4625  return condition; Line 5491  return condition;
5491                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5492  */  */
5493    
5494  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)
5495  {  {
5496  DEFINE_COMPILER;  DEFINE_COMPILER;
5497  backtrack_common *backtrack;  backtrack_common *backtrack;
5498  pcre_uchar opcode;  pcre_uchar opcode;
5499  int localptr = 0;  int private_data_ptr = 0;
5500  int offset = 0;  int offset = 0;
5501  int stacksize;  int stacksize;
5502  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5503  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5504  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5505  pcre_uchar ket;  pcre_uchar ket;
5506  assert_backtrack *assert;  assert_backtrack *assert;
# Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5521  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5521    
5522  opcode = *cc;  opcode = *cc;
5523  ccbegin = cc;  ccbegin = cc;
5524  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5525    
5526  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)
5527    {    {
# Line 4672  cc += GET(cc, 1); Line 5538  cc += GET(cc, 1);
5538  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5539  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5540    {    {
5541    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5542    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5543      {      {
5544      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5545      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5546        has_alternatives = FALSE;        has_alternatives = FALSE;
5547      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4694  if (opcode == OP_CBRA || opcode == OP_SC Line 5560  if (opcode == OP_CBRA || opcode == OP_SC
5560    {    {
5561    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5562    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5563    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5564    offset <<= 1;      {
5565    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5566    trypath += IMM2_SIZE;      offset <<= 1;
5567        }
5568      else
5569        {
5570        offset <<= 1;
5571        private_data_ptr = OVECTOR(offset);
5572        }
5573      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5574      matchingpath += IMM2_SIZE;
5575    }    }
5576  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5577    {    {
5578    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5579    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5580    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5581    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5582    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5583      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5584    }    }
# Line 4750  if (bra == OP_BRAMINZERO) Line 5624  if (bra == OP_BRAMINZERO)
5624        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5625        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5626          {          {
5627          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5628          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);
5629          }          }
5630        else        else
5631          {          {
5632          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5633          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5634          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));
5635          }          }
5636        JUMPHERE(skip);        JUMPHERE(skip);
# Line 4771  if (bra == OP_BRAMINZERO) Line 5645  if (bra == OP_BRAMINZERO)
5645    }    }
5646    
5647  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5648    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5649    
5650  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5651    {    {
5652    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5653    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5654      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5655    }    }
5656    
5657  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 4788  if (opcode == OP_ONCE) Line 5662  if (opcode == OP_ONCE)
5662      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5663      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5664        {        {
5665        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5666        allocate_stack(common, 2);        allocate_stack(common, 2);
5667        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5668        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5669        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));
5670        }        }
5671      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5672        {        {
5673        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);
5674        allocate_stack(common, 1);        allocate_stack(common, 1);
5675        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5676        }        }
5677      else      else
5678        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);
5679      }      }
5680    else    else
5681      {      {
5682      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5683        {        {
5684        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5685        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5686        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));
5687        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5688        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5689        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5690        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);
5691        }        }
5692      else      else
5693        {        {
5694        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5695        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5696        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));
5697        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5698        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5699        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5700        }        }
# Line 4829  if (opcode == OP_ONCE) Line 5703  if (opcode == OP_ONCE)
5703  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5704    {    {
5705    /* Saving the previous values. */    /* Saving the previous values. */
5706    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5707    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5708    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5709    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5710    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5711    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5712    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);
5713    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5714        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5715        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5716        }
5717      else
5718        {
5719        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5720        allocate_stack(common, 2);
5721        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5722        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5723        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5724        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5725        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5726        }
5727    }    }
5728  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5729    {    {
5730    /* Saving the previous value. */    /* Saving the previous value. */
5731    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5732    allocate_stack(common, 1);    allocate_stack(common, 1);
5733    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);
5734    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5735    }    }
5736  else if (has_alternatives)  else if (has_alternatives)
# Line 4856  else if (has_alternatives) Line 5743  else if (has_alternatives)
5743  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5744  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5745    {    {
5746    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5747      {      {
5748      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5749      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5750        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)));
5751      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5752      }      }
5753    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5754      {      {
5755      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5756      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5757      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));
5758    
5759      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 4880  if (opcode == OP_COND || opcode == OP_SC Line 5767  if (opcode == OP_COND || opcode == OP_SC
5767      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));
5768    
5769      JUMPHERE(jump);      JUMPHERE(jump);
5770      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5771      }      }
5772    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5773      {      {
5774      /* Never has other case. */      /* Never has other case. */
5775      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5776    
5777      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5778      if (common->currententry == NULL)      if (common->currententry == NULL)
5779        stacksize = 0;        stacksize = 0;
5780      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4897  if (opcode == OP_COND || opcode == OP_SC Line 5784  if (opcode == OP_COND || opcode == OP_SC
5784      else      else
5785        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5786    
5787      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5788        {        {
5789        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5790        if (stacksize != 0)        if (stacksize != 0)
5791          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5792        else        else
5793          {          {
5794          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5795            {            {
5796            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5797            cc += GET(cc, 1);            cc += GET(cc, 1);
5798            }            }
5799          else          else
5800            trypath = cc;            matchingpath = cc;
5801          }          }
5802        }        }
5803      else      else
5804        {        {
5805        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5806    
5807        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5808        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5809        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);
5810        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 4928  if (opcode == OP_COND || opcode == OP_SC Line 5815  if (opcode == OP_COND || opcode == OP_SC
5815        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));
5816        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5817        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));
5818        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5819        }        }
5820      }      }
5821    else    else
5822      {      {
5823      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5824      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5825      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5826      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5827        return NULL;        return NULL;
5828      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5829      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5830      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5831      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5832      }      }
5833    }    }
5834    
5835  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5836  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5837    return NULL;    return NULL;
5838    
# Line 4953  if (opcode == OP_ONCE) Line 5840  if (opcode == OP_ONCE)
5840    {    {
5841    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5842      {      {
5843      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);
5844      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5845      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5846        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5847      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5848        {        {
5849        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5850        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);
5851        }        }
5852      }      }
5853    else    else
5854      {      {
5855      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5856      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));
5857      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5858        {        {
5859        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5001  if (has_alternatives) Line 5888  if (has_alternatives)
5888    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5889      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5890    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5891      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5892    }    }
5893    
5894  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5895  if (offset != 0)  if (offset != 0)
5896    {    {
5897    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5898    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);
5899    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);
5900    }    }
# Line 5017  if (ket == OP_KETRMAX) Line 5904  if (ket == OP_KETRMAX)
5904    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5905      {      {
5906      if (has_alternatives)      if (has_alternatives)
5907        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5908      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5909      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5910        {        {
5911        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);
5912        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5913        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5914          free_stack(common, 1);          free_stack(common, 1);
# Line 5032  if (ket == OP_KETRMAX) Line 5919  if (ket == OP_KETRMAX)
5919      }      }
5920    else    else
5921      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5922    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5923    }    }
5924    
5925  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5926    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5927    
5928  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5929    {    {
5930    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5931    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5932    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5933      {      {
5934      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5050  if (bra == OP_BRAMINZERO) Line 5937  if (bra == OP_BRAMINZERO)
5937      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5938      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5939        {        {
5940        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);
5941        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5942        }        }
5943      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5069  cc += 1 + LINK_SIZE; Line 5956  cc += 1 + LINK_SIZE;
5956  return cc;  return cc;
5957  }  }
5958    
5959  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)
5960  {  {
5961  DEFINE_COMPILER;  DEFINE_COMPILER;
5962  backtrack_common *backtrack;  backtrack_common *backtrack;
5963  pcre_uchar opcode;  pcre_uchar opcode;
5964  int localptr;  int private_data_ptr;
5965  int cbraprivptr = 0;  int cbraprivptr = 0;
5966  int framesize;  int framesize;
5967  int stacksize;  int stacksize;
# Line 5093  if (*cc == OP_BRAPOSZERO) Line 5980  if (*cc == OP_BRAPOSZERO)
5980    }    }
5981    
5982  opcode = *cc;  opcode = *cc;
5983  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5984  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5985  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5986  switch(opcode)  switch(opcode)
5987    {    {
5988    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5106  switch(opcode) Line 5993  switch(opcode)
5993    case OP_CBRAPOS:    case OP_CBRAPOS:
5994    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5995    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5996      /* This case cannot be optimized in the same was as
5997      normal capturing brackets. */
5998      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5999    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6000    offset <<= 1;    offset <<= 1;
6001    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5125  if (framesize < 0) Line 6015  if (framesize < 0)
6015      stacksize++;      stacksize++;
6016    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6017    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6018    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);
6019    
6020    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6021      {      {
# Line 5150  else Line 6040  else
6040    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6041    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6042    
6043    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6044    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));
6045    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6046    stack = 0;    stack = 0;
6047    if (!zero)    if (!zero)
6048      {      {
# Line 5178  while (*cc != OP_KETRPOS) Line 6068  while (*cc != OP_KETRPOS)
6068    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6069    cc += GET(cc, 1);    cc += GET(cc, 1);
6070    
6071    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6072    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6073      return NULL;      return NULL;
6074    
6075    if (framesize < 0)    if (framesize < 0)
6076      {      {
6077      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);
6078    
6079      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6080        {        {
# Line 5210  while (*cc != OP_KETRPOS) Line 6100  while (*cc != OP_KETRPOS)
6100      {      {
6101      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6102        {        {
6103        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));
6104        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6105        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);
6106        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 5218  while (*cc != OP_KETRPOS) Line 6108  while (*cc != OP_KETRPOS)
6108        }        }
6109      else      else
6110        {        {
6111        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6112        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));
6113        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6114          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 5239  while (*cc != OP_KETRPOS) Line 6129  while (*cc != OP_KETRPOS)
6129    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6130    flush_stubs(common);    flush_stubs(common);
6131    
6132    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6133    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6134      return NULL;      return NULL;
6135    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 5257  while (*cc != OP_KETRPOS) Line 6147  while (*cc != OP_KETRPOS)
6147        {        {
6148        /* Last alternative. */        /* Last alternative. */
6149        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6150          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6151        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6152        }        }
6153      else      else
6154        {        {
6155        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6156        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));
6157        }        }
6158      }      }
# Line 5277  if (!zero) Line 6167  if (!zero)
6167    {    {
6168    if (framesize < 0)    if (framesize < 0)
6169      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));
6170    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6171      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));
6172    }    }
6173    
# Line 5379  if (end != NULL) Line 6269  if (end != NULL)
6269  return cc;  return cc;
6270  }  }
6271    
6272  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)
6273  {  {
6274  DEFINE_COMPILER;  DEFINE_COMPILER;
6275  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5390  pcre_uchar* end; Line 6280  pcre_uchar* end;
6280  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6281  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6282  struct sljit_label *label;  struct sljit_label *label;
6283    int private_data_ptr = PRIVATE_DATA(cc);
6284    int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6285    int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6286    int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6287    int tmp_base, tmp_offset;
6288    
6289  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6290    
6291  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6292    
6293    switch (type)
6294      {
6295      case OP_NOT_DIGIT:
6296      case OP_DIGIT:
6297      case OP_NOT_WHITESPACE:
6298      case OP_WHITESPACE:
6299      case OP_NOT_WORDCHAR:
6300      case OP_WORDCHAR:
6301      case OP_ANY:
6302      case OP_ALLANY:
6303      case OP_ANYBYTE:
6304      case OP_ANYNL:
6305      case OP_NOT_HSPACE:
6306      case OP_HSPACE:
6307      case OP_NOT_VSPACE:
6308      case OP_VSPACE:
6309      case OP_CHAR:
6310      case OP_CHARI:
6311      case OP_NOT:
6312      case OP_NOTI:
6313      case OP_CLASS:
6314      case OP_NCLASS:
6315      tmp_base = TMP3;
6316      tmp_offset = 0;
6317      break;
6318    
6319      default:
6320      SLJIT_ASSERT_STOP();
6321      /* Fall through. */
6322    
6323      case OP_EXTUNI:
6324      case OP_XCLASS:
6325      case OP_NOTPROP:
6326      case OP_PROP:
6327      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6328      tmp_offset = POSSESSIVE0;
6329      break;
6330      }
6331    
6332  switch(opcode)  switch(opcode)
6333    {    {
6334    case OP_STAR:    case OP_STAR:
# Line 5403  switch(opcode) Line 6337  switch(opcode)
6337    case OP_CRRANGE:    case OP_CRRANGE:
6338    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6339      {      {
6340        SLJIT_ASSERT(private_data_ptr == 0);
6341      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6342        {        {
6343        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5414  switch(opcode) Line 6349  switch(opcode)
6349        allocate_stack(common, 1);        allocate_stack(common, 1);
6350        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6351        }        }
6352    
6353      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6354        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6355    
6356      label = LABEL();      label = LABEL();
6357      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6358      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6359        {        {
6360        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5430  switch(opcode) Line 6366  switch(opcode)
6366        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6367        }        }
6368    
6369        /* We cannot use TMP3 because of this allocate_stack. */
6370      allocate_stack(common, 1);      allocate_stack(common, 1);
6371      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6372      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5439  switch(opcode) Line 6376  switch(opcode)
6376    else    else
6377      {      {
6378      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6379        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6380      allocate_stack(common, 2);      if (private_data_ptr == 0)
6381      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        allocate_stack(common, 2);
6382      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6383        if (opcode <= OP_PLUS)
6384          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6385        else
6386          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6387      label = LABEL();      label = LABEL();
6388      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6389      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6390      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6391          JUMPTO(SLJIT_JUMP, label);
6392        else if (opcode == OP_CRRANGE && arg1 == 0)
6393        {        {
6394        OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6395        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6396        }        }
6397      else      else
6398        {        {
6399        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6400        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6401        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6402        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6403        }        }
6404      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6405      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6406        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6407      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6408      }      }
6409    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6410    break;    break;
6411    
6412    case OP_MINSTAR:    case OP_MINSTAR:
6413    case OP_MINPLUS:    case OP_MINPLUS:
6414    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6415      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6416    allocate_stack(common, 1);    if (private_data_ptr == 0)
6417    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6418    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6419      BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6420    break;    break;
6421    
6422    case OP_MINUPTO:    case OP_MINUPTO:
6423    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6424    allocate_stack(common, 2);    if (private_data_ptr == 0)
6425    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6426    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6427      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6428    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6429      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6430    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6431    break;    break;
6432    
6433    case OP_QUERY:    case OP_QUERY:
6434    case OP_MINQUERY:    case OP_MINQUERY:
6435    allocate_stack(common, 1);    if (private_data_ptr == 0)
6436    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6437      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6438    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6439      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6440    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6441    break;    break;
6442    
6443    case OP_EXACT:    case OP_EXACT:
6444    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6445    label = LABEL();    label = LABEL();
6446    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6447    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6448    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6449    break;    break;
6450    
6451    case OP_POSSTAR:    case OP_POSSTAR:
6452    case OP_POSPLUS:    case OP_POSPLUS:
6453    case OP_POSUPTO:    case OP_POSUPTO:
6454    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6455      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6456    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6457        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6458      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6459    label = LABEL();    label = LABEL();
6460    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6461    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6462    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6463      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6464    else    else
6465      {      {
6466      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6467      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6468      }      }
6469    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6470    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6471    break;    break;
6472    
6473    case OP_POSQUERY:    case OP_POSQUERY:
6474    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6475    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6476    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6477    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6478    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6479    break;    break;
6480    
6481    default:    default:
# Line 5549  decrease_call_count(common); Line 6487  decrease_call_count(common);
6487  return end;  return end;
6488  }  }
6489    
6490  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)
6491  {  {
6492  DEFINE_COMPILER;  DEFINE_COMPILER;
6493  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5593  add_jump(compiler, &backtrack->topbacktr Line 6531  add_jump(compiler, &backtrack->topbacktr
6531  return cc + 1;  return cc + 1;
6532  }  }
6533    
6534  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)
6535  {  {
6536  DEFINE_COMPILER;  DEFINE_COMPILER;
6537  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6538    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6539    
6540  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6541  if (common->currententry != NULL)  if (common->currententry != NULL)
6542    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6543    
6544  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6545      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6546  offset <<= 1;  offset <<= 1;
6547  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);
6548  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6549      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6550  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6551  }  }
6552    
6553  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)
6554  {  {
6555  DEFINE_COMPILER;  DEFINE_COMPILER;
6556  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5648  while (cc < ccend) Line 6589  while (cc < ccend)
6589      case OP_NOT:      case OP_NOT:
6590      case OP_NOTI:      case OP_NOTI:
6591      case OP_REVERSE:      case OP_REVERSE:
6592      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);
6593      break;      break;
6594    
6595      case OP_SET_SOM:      case OP_SET_SOM:
# Line 5663  while (cc < ccend) Line 6604  while (cc < ccend)
6604      case OP_CHAR:      case OP_CHAR:
6605      case OP_CHARI:      case OP_CHARI:
6606      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6607        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);
6608      else      else
6609        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);
6610      break;      break;
6611    
6612      case OP_STAR:      case OP_STAR:
# Line 5733  while (cc < ccend) Line 6674  while (cc < ccend)
6674      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6675      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6676      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6677      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6678      break;      break;
6679    
6680      case OP_CLASS:      case OP_CLASS:
6681      case OP_NCLASS:      case OP_NCLASS:
6682      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)
6683        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6684      else      else
6685        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);
6686      break;      break;
6687    
6688  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
6689      case OP_XCLASS:      case OP_XCLASS:
6690      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)
6691        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6692      else      else
6693        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);
6694      break;      break;
6695  #endif  #endif
6696    
6697      case OP_REF:      case OP_REF:
6698      case OP_REFI:      case OP_REFI:
6699      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)
6700        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6701      else      else
6702        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);
6703      break;      break;
6704    
6705      case OP_RECURSE:      case OP_RECURSE:
6706      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6707      break;      break;
6708    
6709      case OP_ASSERT:      case OP_ASSERT:
# Line 5770  while (cc < ccend) Line 6711  while (cc < ccend)
6711      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6712      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6713      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);