/[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 974 by zherczeg, Sat Jun 2 05:56:58 2012 UTC revision 1084 by chpe, Tue Oct 16 15:55:28 2012 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 89  vertical (sub-expression) (See struct ba Line 92  vertical (sub-expression) (See struct ba
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
95  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
97  branches on the try path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Try path: match happens.     Matching path: match happens.
101     Backtrack path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Try path: no need to perform a match.     Matching path: no need to perform a match.
104     Backtrack path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A try path   A matching path
115   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B try path   B matching path
117   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D try path   D matching path
119   return with successful match   return with successful match
120    
121   D backtrack path   D backtrack path
122   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
123   B backtrack path   B backtrack path
124   C expected path   C expected path
125   jump to D try path   jump to D matching path
126   C backtrack path   C backtrack path
127   A backtrack path   A backtrack path
128    
# Line 127  The generated code will be the following Line 130  The generated code will be the following
130   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
131   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
132   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
133   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 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 574  switch(*cc) Line 591  switch(*cc)
591    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
592    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
593    cc += 2;    cc += 2;
594  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
595    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
596  #endif  #endif
597    return cc;    return cc;
# Line 596  switch(*cc) Line 613  switch(*cc)
613    case OP_NOTEXACTI:    case OP_NOTEXACTI:
614    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
615    cc += 2 + IMM2_SIZE;    cc += 2 + IMM2_SIZE;
616  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
617    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
618  #endif  #endif
619    return cc;    return cc;
# Line 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;
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;      break;
903    #endif
904    
905      case OP_RECURSE:      case OP_RECURSE:
906      /* Set its value only once. */      /* Set its value only once. */
# 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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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;      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;
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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 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    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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 2531  else Line 3159  else
3159      JUMPHERE(jump);      JUMPHERE(jump);
3160  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3161    }    }
3162  JUMPHERE(skipread);  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  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3296  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    {
3297      if (length >= MAX_RANGE_SIZE)
3298        return FALSE;
3299      ranges[2 + length] = 256;
3300      length++;
3301      }
3302    ranges[0] = length;
3303    
3304    return check_ranges(common, ranges, backtracks, FALSE);
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    
3564  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3565  utflength = 1;  utflength = 1;
3566    #ifndef COMPILE_PCRE32
3567  if (common->utf && HAS_EXTRALEN(*cc))  if (common->utf && HAS_EXTRALEN(*cc))
3568    utflength += GET_EXTRALEN(*cc);    utflength += GET_EXTRALEN(*cc);
3569    #endif
3570    
3571  do  do
3572    {    {
# Line 2810  do Line 3588  do
3588      }      }
3589    context->ucharptr++;    context->ucharptr++;
3590    
3591  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3592    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3593  #else  #elif defined COMPILE_PCRE16
3594    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3595    #elif defined COMPILE_PCRE32
3596      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3597  #endif  #endif
3598      {      {
3599    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3600      if (context->length >= 4)      if (context->length >= 4)
3601        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3602  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3603      else if (context->length >= 2)      else if (context->length >= 2)
3604        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3605      else if (context->length >= 1)      else if (context->length >= 1)
3606        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3607  #else  #elif defined COMPILE_PCRE16
3608      else if (context->length >= 2)      else if (context->length >= 2)
3609        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3610  #endif  #endif /* COMPILE_PCRE[8|16] */
3611    #elif defined COMPILE_PCRE32
3612        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3613    #endif /* COMPILE_PCRE[8|16|32] */
3614      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3615    
3616      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2837  do Line 3621  do
3621        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3622        break;        break;
3623    
3624    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3625        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3626        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3627          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 2851  do Line 3636  do
3636        break;        break;
3637  #endif  #endif
3638    
3639    #endif /* COMPILE_PCRE[8|16] */
3640    
3641        default:        default:
3642        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3643        break;        break;
# Line 2861  do Line 3648  do
3648  #else  #else
3649    
3650    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #else  
3651    if (context->length > 0)    if (context->length > 0)
3652      OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3653  #endif  
3654    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3655    
3656    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 2912  return cc; Line 3695  return cc;
3695      } \      } \
3696    charoffset = (value);    charoffset = (value);
3697    
3698  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3699  {  {
3700  DEFINE_COMPILER;  DEFINE_COMPILER;
3701  jump_list *found = NULL;  jump_list *found = NULL;
3702  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3703  unsigned int c;  pcre_int32 c, charoffset;
3704  int compares;  const pcre_uint32 *other_cases;
3705  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3706  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3707    int compares, invertcmp, numberofcmps;
3708  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3709  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3710  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3711  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3712  unsigned int typeoffset;  pcre_int32 typeoffset;
3713  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3714    
3715  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3716       not necessary in utf mode even in 8 bit mode. */
3717  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3718  read_char(common);  read_char(common);
3719    
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3727  if ((*cc++ & XCL_MAP) != 0)
3727      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3728  #endif  #endif
3729    
3730    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3731    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3732    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3733    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3734    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);
3735    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3736        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3737        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3738        }
3739    
3740  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3741    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2973  while (*cc != XCL_END) Line 3759  while (*cc != XCL_END)
3759    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3760      {      {
3761      cc += 2;      cc += 2;
3762  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3763      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3764  #endif  #endif
3765  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2983  while (*cc != XCL_END) Line 3769  while (*cc != XCL_END)
3769    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3770      {      {
3771      cc += 2;      cc += 2;
3772  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3773      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3774  #endif  #endif
3775      cc++;      cc++;
3776  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3777      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3778  #endif  #endif
3779  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 3022  while (*cc != XCL_END) Line 3808  while (*cc != XCL_END)
3808        needschar = TRUE;        needschar = TRUE;
3809        break;        break;
3810    
3811          case PT_CLIST:
3812          needschar = TRUE;
3813          break;
3814    
3815        default:        default:
3816        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3817        break;        break;
# Line 3231  while (*cc != XCL_END) Line 4021  while (*cc != XCL_END)
4021        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4022        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4023        break;        break;
4024    
4025          case PT_CLIST:
4026          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4027    
4028          /* At least three characters are required.
4029             Otherwise this case would be handled by the normal code path. */
4030          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4031          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4032    
4033          /* Optimizing character pairs, if their difference is power of 2. */
4034          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4035            {
4036            if (charoffset == 0)
4037              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4038            else
4039              {
4040              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4041              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4042              }
4043            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4044            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4045            other_cases += 2;
4046            }
4047          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4048            {
4049            if (charoffset == 0)
4050              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4051            else
4052              {
4053              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4054              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4055              }
4056            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4057            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4058    
4059            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4060            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4061    
4062            other_cases += 3;
4063            }
4064          else
4065            {
4066            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4067            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4068            }
4069    
4070          while (*other_cases != NOTACHAR)
4071            {
4072            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4073            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4074            }
4075          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4076          break;
4077        }        }
4078      cc += 2;      cc += 2;
4079      }      }
# Line 3249  if (found != NULL) Line 4092  if (found != NULL)
4092    
4093  #endif  #endif
4094    
4095  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
4096  {  {
4097  DEFINE_COMPILER;  DEFINE_COMPILER;
4098  int length;  int length;
# Line 3285  switch(type) Line 4128  switch(type)
4128    
4129    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4130    case OP_DIGIT:    case OP_DIGIT:
4131      /* Digits are usually 0-9, so it is worth to optimize them. */
4132      if (common->digits[0] == -2)
4133        get_ctype_ranges(common, ctype_digit, common->digits);
4134    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4135    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4136    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4137    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4138      if (!check_ranges(common, common->digits, backtracks, TRUE))
4139        {
4140        read_char8_type(common);
4141        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4142        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4143        }
4144      if (type == OP_NOT_DIGIT)
4145        common->digits[1] ^= 1;
4146    return cc;    return cc;
4147    
4148    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3335  switch(type) Line 4189  switch(type)
4189      {      {
4190      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4191      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4193    #if defined COMPILE_PCRE8
4194      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4195      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4196      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4197  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4198      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4199      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4200      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4201      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4202      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4203      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4204  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4205      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4206    #endif /* COMPILE_PCRE[8|16] */
4207      return cc;      return cc;
4208      }      }
4209  #endif  #endif
# Line 3370  switch(type) Line 4224  switch(type)
4224    propdata[2] = cc[0];    propdata[2] = cc[0];
4225    propdata[3] = cc[1];    propdata[3] = cc[1];
4226    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4227    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4228    return cc + 2;    return cc + 2;
4229  #endif  #endif
4230  #endif  #endif
# Line 3416  switch(type) Line 4270  switch(type)
4270    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4271    read_char(common);    read_char(common);
4272    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4273    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4274    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4275      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4276      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4277    
4278    label = LABEL();    label = LABEL();
4279    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4280    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4281    read_char(common);    read_char(common);
4282    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4283    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4284    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4285    
4286      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4287      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4288      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4289      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4290      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4291      JUMPTO(SLJIT_C_NOT_ZERO, label);
4292    
4293    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4294    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4295      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4296    
4297    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4298      {      {
4299      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 3554  switch(type) Line 4419  switch(type)
4419    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4420    
4421    if (!common->endonly)    if (!common->endonly)
4422      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4423    else    else
4424      {      {
4425      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
# Line 3602  switch(type) Line 4467  switch(type)
4467    case OP_CHAR:    case OP_CHAR:
4468    case OP_CHARI:    case OP_CHARI:
4469    length = 1;    length = 1;
4470  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4471    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
4472  #endif  #endif
4473    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
# Line 3634  switch(type) Line 4499  switch(type)
4499      }      }
4500    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4501    bit = c ^ oc;    bit = c ^ oc;
4502    if (ispowerof2(bit))    if (is_powerof2(bit))
4503      {      {
4504      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4505      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 3642  switch(type) Line 4507  switch(type)
4507      }      }
4508    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4509    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4510    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4511    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4512    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4513    return cc + length;    return cc + length;
# Line 3695  switch(type) Line 4560  switch(type)
4560      {      {
4561      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4562      bit = c ^ oc;      bit = c ^ oc;
4563      if (ispowerof2(bit))      if (is_powerof2(bit))
4564        {        {
4565        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4566        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 3712  switch(type) Line 4577  switch(type)
4577    case OP_NCLASS:    case OP_NCLASS:
4578    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4579    read_char(common);    read_char(common);
4580      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4581        return cc + 32 / sizeof(pcre_uchar);
4582    
4583  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4584    jump[0] = NULL;    jump[0] = NULL;
4585  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3740  switch(type) Line 4608  switch(type)
4608  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4609    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4610    
4611  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4612    case OP_XCLASS:    case OP_XCLASS:
4613    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4614    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4615  #endif  #endif
4616    
# Line 3776  SLJIT_ASSERT_STOP(); Line 4644  SLJIT_ASSERT_STOP();
4644  return cc;  return cc;
4645  }  }
4646    
4647  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4648  {  {
4649  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4650  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3794  do Line 4662  do
4662    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
4663      {      {
4664      size = 1;      size = 1;
4665  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4666      if (common->utf && HAS_EXTRALEN(cc[1]))      if (common->utf && HAS_EXTRALEN(cc[1]))
4667        size += GET_EXTRALEN(cc[1]);        size += GET_EXTRALEN(cc[1]);
4668  #endif  #endif
# Line 3807  do Line 4675  do
4675        {        {
4676        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
4677          size = 0;          size = 0;
4678    #ifndef COMPILE_PCRE32
4679        else if (HAS_EXTRALEN(cc[1]))        else if (HAS_EXTRALEN(cc[1]))
4680          size += GET_EXTRALEN(cc[1]);          size += GET_EXTRALEN(cc[1]);
4681    #endif
4682        }        }
4683      else      else
4684  #endif  #endif
# Line 3839  if (context.length > 0) Line 4709  if (context.length > 0)
4709    }    }
4710    
4711  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4712  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4713  }  }
4714    
4715  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 3865  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4735  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4735  }  }
4736    
4737  /* Forward definitions. */  /* Forward definitions. */
4738  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4739  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4740    
4741  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4742    do \    do \
# Line 3896  static void compile_backtrackpath(compil Line 4766  static void compile_backtrackpath(compil
4766    
4767  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4768    
4769  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4770  {  {
4771  DEFINE_COMPILER;  DEFINE_COMPILER;
4772  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3978  if (jump != NULL) Line 4848  if (jump != NULL)
4848  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4849  }  }
4850    
4851  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4852  {  {
4853  DEFINE_COMPILER;  DEFINE_COMPILER;
4854  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4049  if (!minimize) Line 4919  if (!minimize)
4919      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4920    
4921    label = LABEL();    label = LABEL();
4922    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4923    
4924    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4925      {      {
# Line 4077  if (!minimize) Line 4947  if (!minimize)
4947      }      }
4948    
4949    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4950    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4951    
4952    decrease_call_count(common);    decrease_call_count(common);
4953    return cc;    return cc;
# Line 4097  if (min == 0) Line 4967  if (min == 0)
4967  else  else
4968    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4969    
4970  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4971  if (max > 0)  if (max > 0)
4972    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4973    
4974  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4975  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4976    
4977  if (min > 1)  if (min > 1)
# Line 4109  if (min > 1) Line 4979  if (min > 1)
4979    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4980    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4981    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4982    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4983    }    }
4984  else if (max > 0)  else if (max > 0)
4985    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4122  decrease_call_count(common); Line 4992  decrease_call_count(common);
4992  return cc;  return cc;
4993  }  }
4994    
4995  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4996  {  {
4997  DEFINE_COMPILER;  DEFINE_COMPILER;
4998  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4179  add_jump(compiler, &backtrack->topbacktr Line 5049  add_jump(compiler, &backtrack->topbacktr
5049  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5050  }  }
5051    
5052  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5053  {  {
5054  DEFINE_COMPILER;  DEFINE_COMPILER;
5055  int framesize;  int framesize;
5056  int localptr;  int private_data_ptr;
5057  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5058  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5059  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4192  jump_list *tmp = NULL; Line 5062  jump_list *tmp = NULL;
5062  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5063  jump_list **found;  jump_list **found;
5064  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5065  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5066  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5067  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5068  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5069  struct sljit_jump *jump;  struct sljit_jump *jump;
5070  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5075  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5075    bra = *cc;    bra = *cc;
5076    cc++;    cc++;
5077    }    }
5078  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5079  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5080  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5081  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5082  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5083  opcode = *cc;  opcode = *cc;
5084  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5085  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4226  if (bra == OP_BRAMINZERO) Line 5096  if (bra == OP_BRAMINZERO)
5096    
5097  if (framesize < 0)  if (framesize < 0)
5098    {    {
5099    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5100    allocate_stack(common, 1);    allocate_stack(common, 1);
5101    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5102    }    }
5103  else  else
5104    {    {
5105    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5106    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5107    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
5108    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5109    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5110    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5111    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5112    }    }
5113    
5114  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5115  common->leavelabel = NULL;  common->quitlabel = NULL;
5116  common->leave = NULL;  common->quit = NULL;
5117  while (1)  while (1)
5118    {    {
5119    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4255  while (1) Line 5125  while (1)
5125      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5126    
5127    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5128    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5129    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5130      {      {
5131      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5132      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5133      common->leave = save_leave;      common->quit = save_quit;
5134      common->accept = save_accept;      common->accept = save_accept;
5135      return NULL;      return NULL;
5136      }      }
# Line 4270  while (1) Line 5140  while (1)
5140    
5141    /* Reset stack. */    /* Reset stack. */
5142    if (framesize < 0)    if (framesize < 0)
5143      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5144    else {    else {
5145      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5146        {        {
5147        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5148        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5149        }        }
5150      else      else
5151        {        {
5152        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5153        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5154        }        }
5155    }    }
# Line 4297  while (1) Line 5167  while (1)
5167          {          {
5168          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5169          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
5170          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5171          }          }
5172        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5173        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 4305  while (1) Line 5175  while (1)
5175      else if (framesize >= 0)      else if (framesize >= 0)
5176        {        {
5177        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5178        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5179        }        }
5180      }      }
5181    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5182    
5183    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5184    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5185      {      {
5186      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5187      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5188      common->leave = save_leave;      common->quit = save_quit;
5189      common->accept = save_accept;      common->accept = save_accept;
5190      return NULL;      return NULL;
5191      }      }
# Line 4328  while (1) Line 5198  while (1)
5198    cc += GET(cc, 1);    cc += GET(cc, 1);
5199    }    }
5200  /* None of them matched. */  /* None of them matched. */
5201  if (common->leave != NULL)  if (common->quit != NULL)
5202    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5203    
5204  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5205    {    {
# Line 4356  if (opcode == OP_ASSERT || opcode == OP_ Line 5226  if (opcode == OP_ASSERT || opcode == OP_
5226        }        }
5227      else      else
5228        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5229      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5230      }      }
5231    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5232    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4381  if (opcode == OP_ASSERT || opcode == OP_ Line 5251  if (opcode == OP_ASSERT || opcode == OP_
5251      {      {
5252      if (bra == OP_BRA)      if (bra == OP_BRA)
5253        {        {
5254        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5255        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5256        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5257        }        }
5258      else      else
5259        {        {
5260        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5261        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5262        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5263        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5264        }        }
# Line 4396  if (opcode == OP_ASSERT || opcode == OP_ Line 5266  if (opcode == OP_ASSERT || opcode == OP_
5266    
5267    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5268      {      {
5269      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5270      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5271      }      }
5272    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5273      {      {
5274      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5275      JUMPHERE(brajump);      JUMPHERE(brajump);
5276      if (framesize >= 0)      if (framesize >= 0)
5277        {        {
5278        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5279        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5280        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5281        }        }
5282      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5283      }      }
# Line 4435  else Line 5305  else
5305        }        }
5306      else      else
5307        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5308      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5309      }      }
5310    
5311    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5312      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5313    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5314      {      {
5315      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5316      JUMPHERE(brajump);      JUMPHERE(brajump);
5317      }      }
5318    
# Line 4454  else Line 5324  else
5324      }      }
5325    }    }
5326    
5327  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5328  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5329  common->leave = save_leave;  common->quit = save_quit;
5330  common->accept = save_accept;  common->accept = save_accept;
5331  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5332  }  }
# Line 4625  return condition; Line 5495  return condition;
5495                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5496  */  */
5497    
5498  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5499  {  {
5500  DEFINE_COMPILER;  DEFINE_COMPILER;
5501  backtrack_common *backtrack;  backtrack_common *backtrack;
5502  pcre_uchar opcode;  pcre_uchar opcode;
5503  int localptr = 0;  int private_data_ptr = 0;
5504  int offset = 0;  int offset = 0;
5505  int stacksize;  int stacksize;
5506  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5507  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5508  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5509  pcre_uchar ket;  pcre_uchar ket;
5510  assert_backtrack *assert;  assert_backtrack *assert;
# Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5525  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5525    
5526  opcode = *cc;  opcode = *cc;
5527  ccbegin = cc;  ccbegin = cc;
5528  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5529    
5530  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5531    {    {
# Line 4672  cc += GET(cc, 1); Line 5542  cc += GET(cc, 1);
5542  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5543  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5544    {    {
5545    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5546    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5547      {      {
5548      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5549      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5550        has_alternatives = FALSE;        has_alternatives = FALSE;
5551      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4694  if (opcode == OP_CBRA || opcode == OP_SC Line 5564  if (opcode == OP_CBRA || opcode == OP_SC
5564    {    {
5565    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5566    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5567    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5568    offset <<= 1;      {
5569    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5570    trypath += IMM2_SIZE;      offset <<= 1;
5571        }
5572      else
5573        {
5574        offset <<= 1;
5575        private_data_ptr = OVECTOR(offset);
5576        }
5577      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5578      matchingpath += IMM2_SIZE;
5579    }    }
5580  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5581    {    {
5582    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5583    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5584    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5585    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5586    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5587      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5588    }    }
# Line 4750  if (bra == OP_BRAMINZERO) Line 5628  if (bra == OP_BRAMINZERO)
5628        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5629        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5630          {          {
5631          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5632          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5633          }          }
5634        else        else
5635          {          {
5636          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5637          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5638          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5639          }          }
5640        JUMPHERE(skip);        JUMPHERE(skip);
# Line 4771  if (bra == OP_BRAMINZERO) Line 5649  if (bra == OP_BRAMINZERO)
5649    }    }
5650    
5651  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5652    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5653    
5654  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5655    {    {
5656    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5657    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5658      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5659    }    }
5660    
5661  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 4788  if (opcode == OP_ONCE) Line 5666  if (opcode == OP_ONCE)
5666      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5667      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5668        {        {
5669        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5670        allocate_stack(common, 2);        allocate_stack(common, 2);
5671        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5672        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5673        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5674        }        }
5675      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5676        {        {
5677        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5678        allocate_stack(common, 1);        allocate_stack(common, 1);
5679        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5680        }        }
5681      else      else
5682        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5683      }      }
5684    else    else
5685      {      {
5686      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5687        {        {
5688        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5689        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5690        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5691        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5692        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5693        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5694        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5695        }        }
5696      else      else
5697        {        {
5698        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5699        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5700        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5701        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5702        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5703        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5704        }        }
# Line 4829  if (opcode == OP_ONCE) Line 5707  if (opcode == OP_ONCE)
5707  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5708    {    {
5709    /* Saving the previous values. */    /* Saving the previous values. */
5710    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5711    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5712    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5713    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5714    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5715    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5716    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5717    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5718        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5719        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5720        }
5721      else
5722        {
5723        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5724        allocate_stack(common, 2);
5725        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5726        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5727        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5728        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5729        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5730        }
5731    }    }
5732  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5733    {    {
5734    /* Saving the previous value. */    /* Saving the previous value. */
5735    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5736    allocate_stack(common, 1);    allocate_stack(common, 1);
5737    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5738    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5739    }    }
5740  else if (has_alternatives)  else if (has_alternatives)
# Line 4856  else if (has_alternatives) Line 5747  else if (has_alternatives)
5747  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5748  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5749    {    {
5750    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5751      {      {
5752      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5753      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5754        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5755      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5756      }      }
5757    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5758      {      {
5759      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5760      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5761      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5762    
5763      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 4880  if (opcode == OP_COND || opcode == OP_SC Line 5771  if (opcode == OP_COND || opcode == OP_SC
5771      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5772    
5773      JUMPHERE(jump);      JUMPHERE(jump);
5774      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5775      }      }
5776    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5777      {      {
5778      /* Never has other case. */      /* Never has other case. */
5779      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5780    
5781      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5782      if (common->currententry == NULL)      if (common->currententry == NULL)
5783        stacksize = 0;        stacksize = 0;
5784      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4897  if (opcode == OP_COND || opcode == OP_SC Line 5788  if (opcode == OP_COND || opcode == OP_SC
5788      else      else
5789        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5790    
5791      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5792        {        {
5793        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5794        if (stacksize != 0)        if (stacksize != 0)
5795          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5796        else        else
5797          {          {
5798          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5799            {            {
5800            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5801            cc += GET(cc, 1);            cc += GET(cc, 1);
5802            }            }
5803          else          else
5804            trypath = cc;            matchingpath = cc;
5805          }          }
5806        }        }
5807      else      else
5808        {        {
5809        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5810    
5811        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5812        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5813        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5814        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 4928  if (opcode == OP_COND || opcode == OP_SC Line 5819  if (opcode == OP_COND || opcode == OP_SC
5819        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5820        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5821        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5822        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5823        }        }
5824      }      }
5825    else    else
5826      {      {
5827      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5828      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5829      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5830      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5831        return NULL;        return NULL;
5832      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5833      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5834      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5835      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5836      }      }
5837    }    }
5838    
5839  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5840  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5841    return NULL;    return NULL;
5842    
# Line 4953  if (opcode == OP_ONCE) Line 5844  if (opcode == OP_ONCE)
5844    {    {
5845    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5846      {      {
5847      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5848      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5849      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5850        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5851      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5852        {        {
5853        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5854        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5855        }        }
5856      }      }
5857    else    else
5858      {      {
5859      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5860      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5861      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5862        {        {
5863        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5001  if (has_alternatives) Line 5892  if (has_alternatives)
5892    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5893      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5894    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5895      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5896    }    }
5897    
5898  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5899  if (offset != 0)  if (offset != 0)
5900    {    {
5901    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5902    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5903    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5904    }    }
# Line 5017  if (ket == OP_KETRMAX) Line 5908  if (ket == OP_KETRMAX)
5908    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5909      {      {
5910      if (has_alternatives)      if (has_alternatives)
5911        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5912      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5913      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5914        {        {
5915        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5916        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5917        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5918          free_stack(common, 1);          free_stack(common, 1);
# Line 5032  if (ket == OP_KETRMAX) Line 5923  if (ket == OP_KETRMAX)
5923      }      }
5924    else    else
5925      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5926    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5927    }    }
5928    
5929  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5930    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5931    
5932  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5933    {    {
5934    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5935    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5936    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5937      {      {
5938      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5050  if (bra == OP_BRAMINZERO) Line 5941  if (bra == OP_BRAMINZERO)
5941      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5942      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5943        {        {
5944        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5945        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5946        }        }
5947      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5069  cc += 1 + LINK_SIZE; Line 5960  cc += 1 + LINK_SIZE;
5960  return cc;  return cc;
5961  }  }
5962    
5963  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5964  {  {
5965  DEFINE_COMPILER;  DEFINE_COMPILER;
5966  backtrack_common *backtrack;  backtrack_common *backtrack;
5967  pcre_uchar opcode;  pcre_uchar opcode;
5968  int localptr;  int private_data_ptr;
5969  int cbraprivptr = 0;  int cbraprivptr = 0;
5970  int framesize;  int framesize;
5971  int stacksize;  int stacksize;
# Line 5093  if (*cc == OP_BRAPOSZERO) Line 5984  if (*cc == OP_BRAPOSZERO)
5984    }    }
5985    
5986  opcode = *cc;  opcode = *cc;
5987  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5988  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5989  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5990  switch(opcode)  switch(opcode)
5991    {    {
5992    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5106  switch(opcode) Line 5997  switch(opcode)
5997    case OP_CBRAPOS:    case OP_CBRAPOS:
5998    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5999    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
6000      /* This case cannot be optimized in the same was as
6001      normal capturing brackets. */
6002      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
6003    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6004    offset <<= 1;    offset <<= 1;
6005    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5125  if (framesize < 0) Line 6019  if (framesize < 0)
6019      stacksize++;      stacksize++;
6020    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6021    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6022    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6023    
6024    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6025      {      {
# Line 5150  else Line 6044  else
6044    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6045    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6046    
6047    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6048    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6049    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6050    stack = 0;    stack = 0;
6051    if (!zero)    if (!zero)
6052      {      {
# Line 5178  while (*cc != OP_KETRPOS) Line 6072  while (*cc != OP_KETRPOS)
6072    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
6073    cc += GET(cc, 1);    cc += GET(cc, 1);
6074    
6075    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
6076    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6077      return NULL;      return NULL;
6078    
6079    if (framesize < 0)    if (framesize < 0)
6080      {      {
6081      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6082    
6083      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6084        {        {
# Line 5210  while (*cc != OP_KETRPOS) Line 6104  while (*cc != OP_KETRPOS)
6104      {      {
6105      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6106        {        {
6107        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
6108        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6109        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6110        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5218  while (*cc != OP_KETRPOS) Line 6112  while (*cc != OP_KETRPOS)
6112        }        }
6113      else      else
6114        {        {
6115        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6116        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
6117        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6118          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
# Line 5239  while (*cc != OP_KETRPOS) Line 6133  while (*cc != OP_KETRPOS)
6133    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6134    flush_stubs(common);    flush_stubs(common);
6135    
6136    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6137    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6138      return NULL;      return NULL;
6139    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 5257  while (*cc != OP_KETRPOS) Line 6151  while (*cc != OP_KETRPOS)
6151        {        {
6152        /* Last alternative. */        /* Last alternative. */
6153        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6154          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6155        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6156        }        }
6157      else      else
6158        {        {
6159        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6160        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6161        }        }
6162      }      }
# Line 5277  if (!zero) Line 6171  if (!zero)
6171    {    {
6172    if (framesize < 0)    if (framesize < 0)
6173      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
6174    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6175      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
6176    }    }
6177    
# Line 5372  if (*type == 0) Line 6266  if (*type == 0)
6266  if (end != NULL)  if (end != NULL)
6267    {    {
6268    *end = cc + 1;    *end = cc + 1;
6269  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
6270    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
6271  #endif  #endif
6272    }    }
6273  return cc;  return cc;
6274  }  }
6275    
6276  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6277  {  {
6278  DEFINE_COMPILER;  DEFINE_COMPILER;
6279  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5390  pcre_uchar* end; Line 6284  pcre_uchar* end;
6284  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6285  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6286  struct sljit_label *label;  struct sljit_label *label;
6287    int private_data_ptr = PRIVATE_DATA(cc);
6288    int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6289    int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6290    int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6291    int tmp_base, tmp_offset;
6292    
6293  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6294    
6295  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6296    
6297    switch (type)
6298      {
6299      case OP_NOT_DIGIT:
6300      case OP_DIGIT:
6301      case OP_NOT_WHITESPACE:
6302      case OP_WHITESPACE:
6303      case OP_NOT_WORDCHAR:
6304      case OP_WORDCHAR:
6305      case OP_ANY:
6306      case OP_ALLANY:
6307      case OP_ANYBYTE:
6308      case OP_ANYNL:
6309      case OP_NOT_HSPACE:
6310      case OP_HSPACE:
6311      case OP_NOT_VSPACE:
6312      case OP_VSPACE:
6313      case OP_CHAR:
6314      case OP_CHARI:
6315      case OP_NOT:
6316      case OP_NOTI:
6317      case OP_CLASS:
6318      case OP_NCLASS:
6319      tmp_base = TMP3;
6320      tmp_offset = 0;
6321      break;
6322    
6323      default:
6324      SLJIT_ASSERT_STOP();
6325      /* Fall through. */
6326    
6327      case OP_EXTUNI:
6328      case OP_XCLASS:
6329      case OP_NOTPROP:
6330      case OP_PROP:
6331      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6332      tmp_offset = POSSESSIVE0;
6333      break;
6334      }
6335    
6336  switch(opcode)  switch(opcode)
6337    {    {
6338    case OP_STAR:    case OP_STAR:
# Line 5403  switch(opcode) Line 6341  switch(opcode)
6341    case OP_CRRANGE:    case OP_CRRANGE:
6342    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6343      {      {
6344        SLJIT_ASSERT(private_data_ptr == 0);
6345      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6346        {        {
6347        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5414  switch(opcode) Line 6353  switch(opcode)
6353        allocate_stack(common, 1);        allocate_stack(common, 1);
6354        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6355        }        }
6356    
6357      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6358        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6359    
6360      label = LABEL();      label = LABEL();
6361      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6362      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6363        {        {
6364        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5430  switch(opcode) Line 6370  switch(opcode)
6370        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6371        }        }
6372    
6373        /* We cannot use TMP3 because of this allocate_stack. */
6374      allocate_stack(common, 1);      allocate_stack(common, 1);
6375      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6376      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5438  switch(opcode) Line 6379  switch(opcode)
6379      }      }
6380    else    else
6381      {      {
6382      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6383      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6384      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (private_data_ptr == 0)
6385          allocate_stack(common, 2);
6386        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6387        if (opcode <= OP_PLUS)
6388          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6389        else
6390          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6391      label = LABEL();      label = LABEL();
6392      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6393      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6394      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6395          JUMPTO(SLJIT_JUMP, label);
6396        else if (opcode == OP_CRRANGE && arg1 == 0)
6397        {        {
6398        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);
6399        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6400        }        }
6401      else      else
6402        {        {
6403        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6404        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6405        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6406        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6407        }        }
6408      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6409      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6410        add_jump(compiler, &backtrack->topbacktracks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6411          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6412      }      }
6413    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6414    break;    break;
6415    
6416    case OP_MINSTAR:    case OP_MINSTAR:
6417    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6418    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6419      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6420    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    if (private_data_ptr == 0)
6421        allocate_stack(common, 1);
6422      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6423      BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6424    break;    break;
6425    
6426    case OP_MINUPTO:    case OP_MINUPTO:
6427    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6428    allocate_stack(common, 2);    if (private_data_ptr == 0)
6429    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6430    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6431      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6432    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6433      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6434    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6435    break;    break;
6436    
6437    case OP_QUERY:    case OP_QUERY:
6438    case OP_MINQUERY:    case OP_MINQUERY:
6439    allocate_stack(common, 1);    if (private_data_ptr == 0)
6440    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6441      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6442    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6443      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6444    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6445    break;    break;
6446    
6447    case OP_EXACT:    case OP_EXACT:
6448    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6449    label = LABEL();    label = LABEL();
6450    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6451    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);
6452    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);  
6453    break;    break;
6454    
6455    case OP_POSSTAR:    case OP_POSSTAR:
6456    case OP_POSPLUS:    case OP_POSPLUS:
6457    case OP_POSUPTO:    case OP_POSUPTO:
6458    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6459      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6460    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6461        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6462      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6463    label = LABEL();    label = LABEL();
6464    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6465    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6466    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6467      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6468    else    else
6469      {      {
6470      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);
6471      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);  
6472      }      }
6473    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6474    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);  
6475    break;    break;
6476    
6477    case OP_POSQUERY:    case OP_POSQUERY:
6478    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6479    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6480    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6481    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6482    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6483    break;    break;
6484    
6485    default:    default:
# Line 5548  decrease_call_count(common); Line 6491  decrease_call_count(common);
6491  return end;  return end;
6492  }  }
6493    
6494  static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6495  {  {
6496  DEFINE_COMPILER;  DEFINE_COMPILER;
6497  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5592  add_jump(compiler, &backtrack->topbacktr Line 6535  add_jump(compiler, &backtrack->topbacktr
6535  return cc + 1;  return cc + 1;
6536  }  }
6537    
6538  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
6539  {  {
6540  DEFINE_COMPILER;  DEFINE_COMPILER;
6541  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6542    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6543    
6544  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6545  if (common->currententry != NULL)  if (common->currententry != NULL)
6546    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6547    
6548  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6549      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6550  offset <<= 1;  offset <<= 1;
6551  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6552  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6553      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6554  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6555  }  }
6556    
6557  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6558  {  {
6559  DEFINE_COMPILER;  DEFINE_COMPILER;
6560  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5647  while (cc < ccend) Line 6593  while (cc < ccend)
6593      case OP_NOT:      case OP_NOT:
6594      case OP_NOTI:      case OP_NOTI:
6595      case OP_REVERSE:      case OP_REVERSE:
6596      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6597      break;      break;
6598    
6599      case OP_SET_SOM:      case OP_SET_SOM:
# Line 5662  while (cc < ccend) Line 6608  while (cc < ccend)
6608      case OP_CHAR:      case OP_CHAR:
6609      case OP_CHARI:      case OP_CHARI:
6610      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6611        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6612      else      else
6613        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6614      break;      break;
6615    
6616      case OP_STAR:      case OP_STAR:
# Line 5732  while (cc < ccend) Line 6678  while (cc < ccend)
6678      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6679      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY: