/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 970 by zherczeg, Sun May 27 05:28:19 2012 UTC revision 1195 by zherczeg, Thu Nov 1 15:21:27 2012 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 89  vertical (sub-expression) (See struct ba Line 92  vertical (sub-expression) (See struct ba
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
95  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
97  branches on the try path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Try path: match happens.     Matching path: match happens.
101     Backtrack path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Try path: no need to perform a match.     Matching path: no need to perform a match.
104     Backtrack path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A try path   A matching path
115   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B try path   B matching path
117   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D try path   D matching path
119   return with successful match   return with successful match
120    
121   D backtrack path   D backtrack path
122   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
123   B backtrack path   B backtrack path
124   C expected path   C expected path
125   jump to D try path   jump to D matching path
126   C backtrack path   C backtrack path
127   A backtrack path   A backtrack path
128    
# Line 127  The generated code will be the following Line 130  The generated code will be the following
130   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
131   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
132   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
133   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 167  typedef struct executable_functions { Line 170  typedef struct executable_functions {
170    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
171    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
172    void *userdata;    void *userdata;
173      pcre_uint32 top_bracket;
174    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
175  } executable_functions;  } executable_functions;
176    
# Line 181  typedef struct stub_list { Line 185  typedef struct stub_list {
185    enum stub_types type;    enum stub_types type;
186    int data;    int data;
187    struct sljit_jump *start;    struct sljit_jump *start;
188    struct sljit_label *leave;    struct sljit_label *quit;
189    struct stub_list *next;    struct stub_list *next;
190  } stub_list;  } stub_list;
191    
192  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
193    
194  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
195  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
196  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
197  of its descendants. */  of its descendants. */
198  typedef struct backtrack_common {  typedef struct backtrack_common {
199    /* Concatenation stack. */    /* Concatenation stack. */
# Line 208  typedef struct assert_backtrack { Line 212  typedef struct assert_backtrack {
212    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
213    int framesize;    int framesize;
214    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
215    int localptr;    int private_data_ptr;
216    /* For iterators. */    /* For iterators. */
217    struct sljit_label *trypath;    struct sljit_label *matchingpath;
218  } assert_backtrack;  } assert_backtrack;
219    
220  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
221    backtrack_common common;    backtrack_common common;
222    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
223    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
224    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
225    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
226    /* For greedy ? operator. */    /* For greedy ? operator. */
227    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
228    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
229    union {    union {
230      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 230  typedef struct bracket_backtrack { Line 234  typedef struct bracket_backtrack {
234      int framesize;      int framesize;
235    } u;    } u;
236    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
237    int localptr;    int private_data_ptr;
238  } bracket_backtrack;  } bracket_backtrack;
239    
240  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
241    backtrack_common common;    backtrack_common common;
242    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
243    int localptr;    int private_data_ptr;
244    /* Reverting stack is needed. */    /* Reverting stack is needed. */
245    int framesize;    int framesize;
246    /* Allocated stack size. */    /* Allocated stack size. */
# Line 245  typedef struct bracketpos_backtrack { Line 249  typedef struct bracketpos_backtrack {
249    
250  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
251    backtrack_common common;    backtrack_common common;
252    struct sljit_label *trypath;    struct sljit_label *matchingpath;
253  } braminzero_backtrack;  } braminzero_backtrack;
254    
255  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
256    backtrack_common common;    backtrack_common common;
257    /* Next iteration. */    /* Next iteration. */
258    struct sljit_label *trypath;    struct sljit_label *matchingpath;
259  } iterator_backtrack;  } iterator_backtrack;
260    
261  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 268  typedef struct recurse_backtrack { Line 272  typedef struct recurse_backtrack {
272    backtrack_common common;    backtrack_common common;
273  } recurse_backtrack;  } recurse_backtrack;
274    
275    #define MAX_RANGE_SIZE 6
276    
277  typedef struct compiler_common {  typedef struct compiler_common {
278    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
279    pcre_uchar *start;    pcre_uchar *start;
280    
281    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
282    int *localptrs;    int *private_data_ptrs;
283      /* Tells whether the capturing bracket is optimized. */
284      pcre_uint8 *optimized_cbracket;
285      /* Starting offset of private data for capturing brackets. */
286    int cbraptr;    int cbraptr;
287    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
288    int ovector_start;    int ovector_start;
# Line 290  typedef struct compiler_common { Line 299  typedef struct compiler_common {
299    /* Points to the marked string. */    /* Points to the marked string. */
300    int mark_ptr;    int mark_ptr;
301    
302    /* Other  */    /* Flipped and lower case tables. */
303    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
304    sljit_w lcc;    sljit_sw lcc;
305      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
306    int mode;    int mode;
307      /* Newline control. */
308    int nltype;    int nltype;
309    int newline;    int newline;
310    int bsr_nltype;    int bsr_nltype;
311      /* Dollar endonly. */
312    int endonly;    int endonly;
313    BOOL has_set_som;    BOOL has_set_som;
314    sljit_w ctypes;    /* Tables. */
315      sljit_sw ctypes;
316      int digits[2 + MAX_RANGE_SIZE];
317      /* Named capturing brackets. */
318    sljit_uw name_table;    sljit_uw name_table;
319    sljit_w name_count;    sljit_sw name_count;
320    sljit_w name_entry_size;    sljit_sw name_entry_size;
321    
322    /* Labels and jump lists. */    /* Labels and jump lists. */
323    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
324    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
325    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
326    stub_list *stubs;    stub_list *stubs;
327    recurse_entry *entries;    recurse_entry *entries;
328    recurse_entry *currententry;    recurse_entry *currententry;
329    jump_list *partialmatch;    jump_list *partialmatch;
330    jump_list *leave;    jump_list *quit;
331    jump_list *accept;    jump_list *accept;
332    jump_list *calllimit;    jump_list *calllimit;
333    jump_list *stackalloc;    jump_list *stackalloc;
# Line 329  typedef struct compiler_common { Line 344  typedef struct compiler_common {
344  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
345    BOOL use_ucp;    BOOL use_ucp;
346  #endif  #endif
347    #ifndef COMPILE_PCRE32
348    jump_list *utfreadchar;    jump_list *utfreadchar;
349    #endif
350  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
351    jump_list *utfreadtype8;    jump_list *utfreadtype8;
352  #endif  #endif
# Line 347  typedef struct compare_context { Line 364  typedef struct compare_context {
364  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
365    int ucharptr;    int ucharptr;
366    union {    union {
367      sljit_i asint;      sljit_si asint;
368      sljit_uh asushort;      sljit_uh asushort;
369  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
370      sljit_ub asbyte;      sljit_ub asbyte;
371      sljit_ub asuchars[4];      sljit_ub asuchars[4];
372  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
373      sljit_uh asuchars[2];      sljit_uh asuchars[2];
374  #endif  #elif defined COMPILE_PCRE32
375        sljit_ui asuchars[1];
376  #endif  #endif
377    } c;    } c;
378    union {    union {
379      sljit_i asint;      sljit_si asint;
380      sljit_uh asushort;      sljit_uh asushort;
381  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
382      sljit_ub asbyte;      sljit_ub asbyte;
383      sljit_ub asuchars[4];      sljit_ub asuchars[4];
384  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
385      sljit_uh asuchars[2];      sljit_uh asuchars[2];
386  #endif  #elif defined COMPILE_PCRE32
387        sljit_ui asuchars[1];
388  #endif  #endif
389    } oc;    } oc;
390  #endif  #endif
# Line 383  enum { Line 400  enum {
400  #undef CMP  #undef CMP
401    
402  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
403  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
404    
405  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
406  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
# Line 396  enum { Line 413  enum {
413  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
414  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
415    
416  /* Locals layout. */  /* Local space layout. */
417  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
418  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
419  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
420  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
421  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
422  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
423  /* Max limit of recursions. */  /* Max limit of recursions. */
424  #define CALL_LIMIT       (4 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
425  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
426  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
427  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
428  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
429  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
430  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
431  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))
432  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
433    
434  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
435  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
436  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
437  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
438  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
439  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
440    #elif defined COMPILE_PCRE32
441    #define MOV_UCHAR  SLJIT_MOV_UI
442    #define MOVU_UCHAR SLJIT_MOVU_UI
443  #else  #else
444  #error Unsupported compiling mode  #error Unsupported compiling mode
445  #endif  #endif
 #endif  
446    
447  /* Shortcuts. */  /* Shortcuts. */
448  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 461  return cc; Line 479  return cc;
479    
480  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
481   next_opcode   next_opcode
482   get_localspace   get_private_data_length
483   set_localptrs   set_private_data_ptrs
484   get_framesize   get_framesize
485   init_frame   init_frame
486   get_localsize   get_private_data_length_for_copy
487   copy_locals   copy_private_data
488   compile_trypath   compile_matchingpath
489   compile_backtrackpath   compile_backtrackingpath
490  */  */
491    
492  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 667  switch(*cc) Line 685  switch(*cc)
685    }    }
686  }  }
687    
688  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
689        case OP_MINSTAR: \
690        case OP_MINPLUS: \
691        case OP_QUERY: \
692        case OP_MINQUERY: \
693        case OP_MINSTARI: \
694        case OP_MINPLUSI: \
695        case OP_QUERYI: \
696        case OP_MINQUERYI: \
697        case OP_NOTMINSTAR: \
698        case OP_NOTMINPLUS: \
699        case OP_NOTQUERY: \
700        case OP_NOTMINQUERY: \
701        case OP_NOTMINSTARI: \
702        case OP_NOTMINPLUSI: \
703        case OP_NOTQUERYI: \
704        case OP_NOTMINQUERYI:
705    
706    #define CASE_ITERATOR_PRIVATE_DATA_2A \
707        case OP_STAR: \
708        case OP_PLUS: \
709        case OP_STARI: \
710        case OP_PLUSI: \
711        case OP_NOTSTAR: \
712        case OP_NOTPLUS: \
713        case OP_NOTSTARI: \
714        case OP_NOTPLUSI:
715    
716    #define CASE_ITERATOR_PRIVATE_DATA_2B \
717        case OP_UPTO: \
718        case OP_MINUPTO: \
719        case OP_UPTOI: \
720        case OP_MINUPTOI: \
721        case OP_NOTUPTO: \
722        case OP_NOTMINUPTO: \
723        case OP_NOTUPTOI: \
724        case OP_NOTMINUPTOI:
725    
726    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
727        case OP_TYPEMINSTAR: \
728        case OP_TYPEMINPLUS: \
729        case OP_TYPEQUERY: \
730        case OP_TYPEMINQUERY:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
733        case OP_TYPESTAR: \
734        case OP_TYPEPLUS:
735    
736    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
737        case OP_TYPEUPTO: \
738        case OP_TYPEMINUPTO:
739    
740    static int get_class_iterator_size(pcre_uchar *cc)
741  {  {
742  int localspace = 0;  switch(*cc)
743      {
744      case OP_CRSTAR:
745      case OP_CRPLUS:
746      return 2;
747    
748      case OP_CRMINSTAR:
749      case OP_CRMINPLUS:
750      case OP_CRQUERY:
751      case OP_CRMINQUERY:
752      return 1;
753    
754      case OP_CRRANGE:
755      case OP_CRMINRANGE:
756      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
757        return 0;
758      return 2;
759    
760      default:
761      return 0;
762      }
763    }
764    
765    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
766    {
767    int private_data_length = 0;
768  pcre_uchar *alternative;  pcre_uchar *alternative;
769    pcre_uchar *name;
770    pcre_uchar *end = NULL;
771    int space, size, i;
772    pcre_uint32 bracketlen;
773    
774  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
775  while (cc < ccend)  while (cc < ccend)
776    {    {
777      space = 0;
778      size = 0;
779      bracketlen = 0;
780    switch(*cc)    switch(*cc)
781      {      {
782      case OP_SET_SOM:      case OP_SET_SOM:
# Line 681  while (cc < ccend) Line 784  while (cc < ccend)
784      cc += 1;      cc += 1;
785      break;      break;
786    
787        case OP_REF:
788        case OP_REFI:
789        common->optimized_cbracket[GET2(cc, 1)] = 0;
790        cc += 1 + IMM2_SIZE;
791        break;
792    
793      case OP_ASSERT:      case OP_ASSERT:
794      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
795      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 690  while (cc < ccend) Line 799  while (cc < ccend)
799      case OP_BRAPOS:      case OP_BRAPOS:
800      case OP_SBRA:      case OP_SBRA:
801      case OP_SBRAPOS:      case OP_SBRAPOS:
802      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
803      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
804      break;      break;
805    
806      case OP_CBRAPOS:      case OP_CBRAPOS:
807      case OP_SCBRAPOS:      case OP_SCBRAPOS:
808      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
809      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
810        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
811      break;      break;
812    
813      case OP_COND:      case OP_COND:
814      /* Might be a hidden SCOND. */      case OP_SCOND:
815      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
816      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
817        localspace += sizeof(sljit_w);        {
818      cc += 1 + LINK_SIZE;        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          common->optimized_cbracket[bracketlen] = 0;
820          }
821        else if (bracketlen == OP_NCREF)
822          {
823          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
824          name = (pcre_uchar *)common->name_table;
825          alternative = name;
826          for (i = 0; i < common->name_count; i++)
827            {
828            if (GET2(name, 0) == bracketlen) break;
829            name += common->name_entry_size;
830            }
831          SLJIT_ASSERT(i != common->name_count);
832    
833          for (i = 0; i < common->name_count; i++)
834            {
835            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
836              common->optimized_cbracket[GET2(alternative, 0)] = 0;
837            alternative += common->name_entry_size;
838            }
839          }
840    
841        if (*cc == OP_COND)
842          {
843          /* Might be a hidden SCOND. */
844          alternative = cc + GET(cc, 1);
845          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
846            private_data_length += sizeof(sljit_sw);
847          }
848        else
849          private_data_length += sizeof(sljit_sw);
850        bracketlen = 1 + LINK_SIZE;
851        break;
852    
853        case OP_BRA:
854        bracketlen = 1 + LINK_SIZE;
855        break;
856    
857        case OP_CBRA:
858        case OP_SCBRA:
859        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_1
863        space = 1;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2A
868        space = 2;
869        size = -2;
870        break;
871    
872        CASE_ITERATOR_PRIVATE_DATA_2B
873        space = 2;
874        size = -(2 + IMM2_SIZE);
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
878        space = 1;
879        size = 1;
880      break;      break;
881    
882        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
883        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
884          space = 2;
885        size = 1;
886        break;
887    
888        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
889        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
890          space = 2;
891        size = 1 + IMM2_SIZE;
892        break;
893    
894        case OP_CLASS:
895        case OP_NCLASS:
896        size += 1 + 32 / sizeof(pcre_uchar);
897        space = get_class_iterator_size(cc + size);
898        break;
899    
900    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
901        case OP_XCLASS:
902        size = GET(cc, 1);
903        space = get_class_iterator_size(cc + size);
904        break;
905    #endif
906    
907      case OP_RECURSE:      case OP_RECURSE:
908      /* Set its value only once. */      /* Set its value only once. */
909      if (common->recursive_head == 0)      if (common->recursive_head == 0)
910        {        {
911        common->recursive_head = common->ovector_start;        common->recursive_head = common->ovector_start;
912        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
913        }        }
914      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
915      break;      break;
# Line 723  while (cc < ccend) Line 918  while (cc < ccend)
918      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
919        {        {
920        common->mark_ptr = common->ovector_start;        common->mark_ptr = common->ovector_start;
921        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
922        }        }
923      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
924      break;      break;
# Line 734  while (cc < ccend) Line 929  while (cc < ccend)
929        return -1;        return -1;
930      break;      break;
931      }      }
932    
933      if (space > 0 && cc >= end)
934        private_data_length += sizeof(sljit_sw) * space;
935    
936      if (size != 0)
937        {
938        if (size < 0)
939          {
940          cc += -size;
941    #ifdef SUPPORT_UTF
942          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
943    #endif
944          }
945        else
946          cc += size;
947        }
948    
949      if (bracketlen != 0)
950        {
951        if (cc >= end)
952          {
953          end = bracketend(cc);
954          if (end[-1 - LINK_SIZE] == OP_KET)
955            end = NULL;
956          }
957        cc += bracketlen;
958        }
959    }    }
960  return localspace;  return private_data_length;
961  }  }
962    
963  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
964  {  {
965  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
966  pcre_uchar *alternative;  pcre_uchar *alternative;
967    pcre_uchar *end = NULL;
968    int space, size, bracketlen;
969    
970  while (cc < ccend)  while (cc < ccend)
971    {    {
972      space = 0;
973      size = 0;
974      bracketlen = 0;
975    switch(*cc)    switch(*cc)
976      {      {
977      case OP_ASSERT:      case OP_ASSERT:
# Line 756  while (cc < ccend) Line 984  while (cc < ccend)
984      case OP_SBRA:      case OP_SBRA:
985      case OP_SBRAPOS:      case OP_SBRAPOS:
986      case OP_SCOND:      case OP_SCOND:
987      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
988      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
989      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
990      break;      break;
991    
992      case OP_CBRAPOS:      case OP_CBRAPOS:
993      case OP_SCBRAPOS:      case OP_SCBRAPOS:
994      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
995      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
996      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
997      break;      break;
998    
999      case OP_COND:      case OP_COND:
# Line 773  while (cc < ccend) Line 1001  while (cc < ccend)
1001      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1002      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1003        {        {
1004        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1005        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1006        }        }
1007      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1008        break;
1009    
1010        case OP_BRA:
1011        bracketlen = 1 + LINK_SIZE;
1012        break;
1013    
1014        case OP_CBRA:
1015        case OP_SCBRA:
1016        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1017        break;
1018    
1019        CASE_ITERATOR_PRIVATE_DATA_1
1020        space = 1;
1021        size = -2;
1022        break;
1023    
1024        CASE_ITERATOR_PRIVATE_DATA_2A
1025        space = 2;
1026        size = -2;
1027        break;
1028    
1029        CASE_ITERATOR_PRIVATE_DATA_2B
1030        space = 2;
1031        size = -(2 + IMM2_SIZE);
1032        break;
1033    
1034        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1035        space = 1;
1036        size = 1;
1037        break;
1038    
1039        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1040        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1041          space = 2;
1042        size = 1;
1043        break;
1044    
1045        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1046        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1047          space = 2;
1048        size = 1 + IMM2_SIZE;
1049        break;
1050    
1051        case OP_CLASS:
1052        case OP_NCLASS:
1053        size += 1 + 32 / sizeof(pcre_uchar);
1054        space = get_class_iterator_size(cc + size);
1055        break;
1056    
1057    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1058        case OP_XCLASS:
1059        size = GET(cc, 1);
1060        space = get_class_iterator_size(cc + size);
1061      break;      break;
1062    #endif
1063    
1064      default:      default:
1065      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1066      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1067      break;      break;
1068      }      }
1069    
1070      if (space > 0 && cc >= end)
1071        {
1072        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1073        private_data_ptr += sizeof(sljit_sw) * space;
1074        }
1075    
1076      if (size != 0)
1077        {
1078        if (size < 0)
1079          {
1080          cc += -size;
1081    #ifdef SUPPORT_UTF
1082          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1083    #endif
1084          }
1085        else
1086          cc += size;
1087        }
1088    
1089      if (bracketlen > 0)
1090        {
1091        if (cc >= end)
1092          {
1093          end = bracketend(cc);
1094          if (end[-1 - LINK_SIZE] == OP_KET)
1095            end = NULL;
1096          }
1097        cc += bracketlen;
1098        }
1099    }    }
1100  }  }
1101    
# Line 889  while (cc < ccend) Line 1201  while (cc < ccend)
1201        {        {
1202        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1203        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1204        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1205        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1206        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1207        setsom_found = TRUE;        setsom_found = TRUE;
1208        }        }
1209      cc += 1;      cc += 1;
# Line 903  while (cc < ccend) Line 1215  while (cc < ccend)
1215        {        {
1216        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1217        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1218        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1219        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1220        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1221        setmark_found = TRUE;        setmark_found = TRUE;
1222        }        }
1223      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
# Line 916  while (cc < ccend) Line 1228  while (cc < ccend)
1228        {        {
1229        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1230        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1231        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1232        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1233        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1234        setsom_found = TRUE;        setsom_found = TRUE;
1235        }        }
1236      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1237        {        {
1238        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1239        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1240        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1241        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1242        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1243        setmark_found = TRUE;        setmark_found = TRUE;
1244        }        }
1245      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
# Line 939  while (cc < ccend) Line 1251  while (cc < ccend)
1251      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1252      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1253      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1254      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1255      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1256      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
1257      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1258      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1259      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1260      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1261    
1262      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1263      break;      break;
# Line 960  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1272  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1272  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1273  }  }
1274    
1275  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1276  {  {
1277  int localsize = 2;  int private_data_length = 2;
1278    int size;
1279  pcre_uchar *alternative;  pcre_uchar *alternative;
1280  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1281  while (cc < ccend)  while (cc < ccend)
1282    {    {
1283      size = 0;
1284    switch(*cc)    switch(*cc)
1285      {      {
1286      case OP_ASSERT:      case OP_ASSERT:
# Line 979  while (cc < ccend) Line 1293  while (cc < ccend)
1293      case OP_SBRA:      case OP_SBRA:
1294      case OP_SBRAPOS:      case OP_SBRAPOS:
1295      case OP_SCOND:      case OP_SCOND:
1296      localsize++;      private_data_length++;
1297      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1298      break;      break;
1299    
1300      case OP_CBRA:      case OP_CBRA:
1301      case OP_SCBRA:      case OP_SCBRA:
1302      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1303          private_data_length++;
1304      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1305      break;      break;
1306    
1307      case OP_CBRAPOS:      case OP_CBRAPOS:
1308      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1309      localsize += 2;      private_data_length += 2;
1310      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1311      break;      break;
1312    
# Line 999  while (cc < ccend) Line 1314  while (cc < ccend)
1314      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1315      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1316      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1317        localsize++;        private_data_length++;
1318      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1319      break;      break;
1320    
1321        CASE_ITERATOR_PRIVATE_DATA_1
1322        if (PRIVATE_DATA(cc))
1323          private_data_length++;
1324        cc += 2;
1325    #ifdef SUPPORT_UTF
1326        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1327    #endif
1328        break;
1329    
1330        CASE_ITERATOR_PRIVATE_DATA_2A
1331        if (PRIVATE_DATA(cc))
1332          private_data_length += 2;
1333        cc += 2;
1334    #ifdef SUPPORT_UTF
1335        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1336    #endif
1337        break;
1338    
1339        CASE_ITERATOR_PRIVATE_DATA_2B
1340        if (PRIVATE_DATA(cc))
1341          private_data_length += 2;
1342        cc += 2 + IMM2_SIZE;
1343    #ifdef SUPPORT_UTF
1344        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1345    #endif
1346        break;
1347    
1348        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1349        if (PRIVATE_DATA(cc))
1350          private_data_length++;
1351        cc += 1;
1352        break;
1353    
1354        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1355        if (PRIVATE_DATA(cc))
1356          private_data_length += 2;
1357        cc += 1;
1358        break;
1359    
1360        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1361        if (PRIVATE_DATA(cc))
1362          private_data_length += 2;
1363        cc += 1 + IMM2_SIZE;
1364        break;
1365    
1366        case OP_CLASS:
1367        case OP_NCLASS:
1368    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1369        case OP_XCLASS:
1370        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1371    #else
1372        size = 1 + 32 / (int)sizeof(pcre_uchar);
1373    #endif
1374        if (PRIVATE_DATA(cc))
1375          private_data_length += get_class_iterator_size(cc + size);
1376        cc += size;
1377        break;
1378    
1379      default:      default:
1380      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1381      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1010  while (cc < ccend) Line 1383  while (cc < ccend)
1383      }      }
1384    }    }
1385  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1386  return localsize;  return private_data_length;
1387  }  }
1388    
1389  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1390    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1391  {  {
1392  DEFINE_COMPILER;  DEFINE_COMPILER;
1393  int srcw[2];  int srcw[2];
1394  int count;  int count, size;
1395  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1396  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1397  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1035  stacktop = STACK(stacktop - 1); Line 1408  stacktop = STACK(stacktop - 1);
1408    
1409  if (!save)  if (!save)
1410    {    {
1411    stackptr += sizeof(sljit_w);    stackptr += sizeof(sljit_sw);
1412    if (stackptr < stacktop)    if (stackptr < stacktop)
1413      {      {
1414      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1415      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1416      tmp1empty = FALSE;      tmp1empty = FALSE;
1417      }      }
1418    if (stackptr < stacktop)    if (stackptr < stacktop)
1419      {      {
1420      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1421      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1422      tmp2empty = FALSE;      tmp2empty = FALSE;
1423      }      }
1424    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
# Line 1083  while (status != end) Line 1456  while (status != end)
1456        case OP_SBRAPOS:        case OP_SBRAPOS:
1457        case OP_SCOND:        case OP_SCOND:
1458        count = 1;        count = 1;
1459        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1460        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1461        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1462        break;        break;
1463    
1464        case OP_CBRA:        case OP_CBRA:
1465        case OP_SCBRA:        case OP_SCBRA:
1466        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1467        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1468            count = 1;
1469            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1470            }
1471        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1472        break;        break;
1473    
1474        case OP_CBRAPOS:        case OP_CBRAPOS:
1475        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1476        count = 2;        count = 2;
1477          srcw[0] = PRIVATE_DATA(cc);
1478        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1479        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1480        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1481        break;        break;
1482    
# Line 1110  while (status != end) Line 1486  while (status != end)
1486        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1487          {          {
1488          count = 1;          count = 1;
1489          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1490          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1491          }          }
1492        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1493        break;        break;
1494    
1495          CASE_ITERATOR_PRIVATE_DATA_1
1496          if (PRIVATE_DATA(cc))
1497            {
1498            count = 1;
1499            srcw[0] = PRIVATE_DATA(cc);
1500            }
1501          cc += 2;
1502    #ifdef SUPPORT_UTF
1503          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1504    #endif
1505          break;
1506    
1507          CASE_ITERATOR_PRIVATE_DATA_2A
1508          if (PRIVATE_DATA(cc))
1509            {
1510            count = 2;
1511            srcw[0] = PRIVATE_DATA(cc);
1512            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1513            }
1514          cc += 2;
1515    #ifdef SUPPORT_UTF
1516          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1517    #endif
1518          break;
1519    
1520          CASE_ITERATOR_PRIVATE_DATA_2B
1521          if (PRIVATE_DATA(cc))
1522            {
1523            count = 2;
1524            srcw[0] = PRIVATE_DATA(cc);
1525            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1526            }
1527          cc += 2 + IMM2_SIZE;
1528    #ifdef SUPPORT_UTF
1529          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1530    #endif
1531          break;
1532    
1533          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1534          if (PRIVATE_DATA(cc))
1535            {
1536            count = 1;
1537            srcw[0] = PRIVATE_DATA(cc);
1538            }
1539          cc += 1;
1540          break;
1541    
1542          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1543          if (PRIVATE_DATA(cc))
1544            {
1545            count = 2;
1546            srcw[0] = PRIVATE_DATA(cc);
1547            srcw[1] = srcw[0] + sizeof(sljit_sw);
1548            }
1549          cc += 1;
1550          break;
1551    
1552          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1553          if (PRIVATE_DATA(cc))
1554            {
1555            count = 2;
1556            srcw[0] = PRIVATE_DATA(cc);
1557            srcw[1] = srcw[0] + sizeof(sljit_sw);
1558            }
1559          cc += 1 + IMM2_SIZE;
1560          break;
1561    
1562          case OP_CLASS:
1563          case OP_NCLASS:
1564    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1565          case OP_XCLASS:
1566          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1567    #else
1568          size = 1 + 32 / (int)sizeof(pcre_uchar);
1569    #endif
1570          if (PRIVATE_DATA(cc))
1571            switch(get_class_iterator_size(cc + size))
1572              {
1573              case 1:
1574              count = 1;
1575              srcw[0] = PRIVATE_DATA(cc);
1576              break;
1577    
1578              case 2:
1579              count = 2;
1580              srcw[0] = PRIVATE_DATA(cc);
1581              srcw[1] = srcw[0] + sizeof(sljit_sw);
1582              break;
1583    
1584              default:
1585              SLJIT_ASSERT_STOP();
1586              break;
1587              }
1588          cc += size;
1589          break;
1590    
1591        default:        default:
1592        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1593        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1138  while (status != end) Line 1610  while (status != end)
1610          if (!tmp1empty)          if (!tmp1empty)
1611            {            {
1612            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1613            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1614            }            }
1615          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1616          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1149  while (status != end) Line 1621  while (status != end)
1621          if (!tmp2empty)          if (!tmp2empty)
1622            {            {
1623            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1624            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1625            }            }
1626          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1627          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1166  while (status != end) Line 1638  while (status != end)
1638          if (!tmp1empty)          if (!tmp1empty)
1639            {            {
1640            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1641            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1642            }            }
1643          tmp1next = FALSE;          tmp1next = FALSE;
1644          }          }
# Line 1178  while (status != end) Line 1650  while (status != end)
1650          if (!tmp2empty)          if (!tmp2empty)
1651            {            {
1652            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1653            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1654            }            }
1655          tmp1next = TRUE;          tmp1next = TRUE;
1656          }          }
# Line 1193  if (save) Line 1665  if (save)
1665      if (!tmp1empty)      if (!tmp1empty)
1666        {        {
1667        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1668        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1669        }        }
1670      if (!tmp2empty)      if (!tmp2empty)
1671        {        {
1672        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1673        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1674        }        }
1675      }      }
1676    else    else
# Line 1206  if (save) Line 1678  if (save)
1678      if (!tmp2empty)      if (!tmp2empty)
1679        {        {
1680        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1681        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1682        }        }
1683      if (!tmp1empty)      if (!tmp1empty)
1684        {        {
1685        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1686        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1687        }        }
1688      }      }
1689    }    }
1690  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1691  }  }
1692    
1693  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1694    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1695    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1696    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1697    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1698    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1699    
1700    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1701  {  {
1702  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1703  }  }
# Line 1228  static SLJIT_INLINE void set_jumps(jump_ Line 1707  static SLJIT_INLINE void set_jumps(jump_
1707  while (list)  while (list)
1708    {    {
1709    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1710    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1711    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1712    list = list->next;    list = list->next;
1713    }    }
# Line 1255  if (list_item) Line 1734  if (list_item)
1734    list_item->type = type;    list_item->type = type;
1735    list_item->data = data;    list_item->data = data;
1736    list_item->start = start;    list_item->start = start;
1737    list_item->leave = LABEL();    list_item->quit = LABEL();
1738    list_item->next = common->stubs;    list_item->next = common->stubs;
1739    common->stubs = list_item;    common->stubs = list_item;
1740    }    }
# Line 1275  while (list_item) Line 1754  while (list_item)
1754      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1755      break;      break;
1756      }      }
1757    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1758    list_item = list_item->next;    list_item = list_item->next;
1759    }    }
1760  common->stubs = NULL;  common->stubs = NULL;
# Line 1294  static SLJIT_INLINE void allocate_stack( Line 1773  static SLJIT_INLINE void allocate_stack(
1773  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
1774  DEFINE_COMPILER;  DEFINE_COMPILER;
1775    
1776  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1777  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
1778  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1779  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1308  add_stub(common, stack_alloc, 0, CMP(SLJ Line 1787  add_stub(common, stack_alloc, 0, CMP(SLJ
1787  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1788  {  {
1789  DEFINE_COMPILER;  DEFINE_COMPILER;
1790  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1791  }  }
1792    
1793  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1326  if (length < 8) Line 1805  if (length < 8)
1805    }    }
1806  else  else
1807    {    {
1808    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_sw));
1809    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1810    loop = LABEL();    loop = LABEL();
1811    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_sw), SLJIT_TEMPORARY_REG1, 0);
1812    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1813    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1814    }    }
# Line 1358  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVEC Line 1837  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVEC
1837  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1838  loop = LABEL();  loop = LABEL();
1839  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1840  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
1841  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1842  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1843  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1844  #endif  #endif
1845  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1846  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
# Line 1371  JUMPHERE(earlyexit); Line 1850  JUMPHERE(earlyexit);
1850  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1851  if (topbracket > 1)  if (topbracket > 1)
1852    {    {
1853    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
1854    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1855    
1856    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1857    loop = LABEL();    loop = LABEL();
1858    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
1859    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1860    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1861    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
# Line 1385  else Line 1864  else
1864    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1865  }  }
1866    
1867  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)
1868  {  {
1869  DEFINE_COMPILER;  DEFINE_COMPILER;
1870    
# Line 1395  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1874  SLJIT_ASSERT(common->start_used_ptr != 0
1874  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1875  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1876  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));
1877  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1878    
1879  /* Store match begin and end. */  /* Store match begin and end. */
1880  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));
1881  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1882  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1883  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1884  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1885  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1886  #endif  #endif
1887  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1888    
1889  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1890  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1891  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1892  #endif  #endif
1893  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1894    
1895  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1896  }  }
1897    
1898  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 2003  if (c <= 127 && bit == 0x20)
2003    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2004    
2005  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2006  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2007    return 0;    return 0;
2008    
2009  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2010    
2011  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2012  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1543  if (common->utf && c > 127) Line 2022  if (common->utf && c > 127)
2022  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2023  return (0 << 8) | bit;  return (0 << 8) | bit;
2024    
2025  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2026    
 #ifdef COMPILE_PCRE16  
2027  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2028  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2029    {    {
# Line 1556  if (common->utf && c > 65535) Line 2034  if (common->utf && c > 65535)
2034    }    }
2035  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2036  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2037    
2038  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2039  }  }
2040    
2041  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 1656  static void read_char(compiler_common *c Line 2133  static void read_char(compiler_common *c
2133  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2134  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2135  DEFINE_COMPILER;  DEFINE_COMPILER;
2136  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2137  struct sljit_jump *jump;  struct sljit_jump *jump;
2138  #endif  #endif
2139    
2140  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2141  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2142  if (common->utf)  if (common->utf)
2143    {    {
2144  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2146  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2147    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2148  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2149    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2150    JUMPHERE(jump);    JUMPHERE(jump);
2151    }    }
2152  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2153  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2154  }  }
2155    
# Line 1683  static void peek_char(compiler_common *c Line 2158  static void peek_char(compiler_common *c
2158  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2159  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2160  DEFINE_COMPILER;  DEFINE_COMPILER;
2161  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2162  struct sljit_jump *jump;  struct sljit_jump *jump;
2163  #endif  #endif
2164    
2165  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2166  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2167  if (common->utf)  if (common->utf)
2168    {    {
2169  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2171  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2172    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2173  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2174    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2175    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2176    JUMPHERE(jump);    JUMPHERE(jump);
2177    }    }
2178  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2179  }  }
2180    
2181  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2182  {  {
2183  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2184  DEFINE_COMPILER;  DEFINE_COMPILER;
2185  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2186  struct sljit_jump *jump;  struct sljit_jump *jump;
2187  #endif  #endif
2188    
# Line 1718  if (common->utf) Line 2191  if (common->utf)
2191    {    {
2192    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2193    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2194  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2195    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2196    it is needed in most cases. */    it is needed in most cases. */
2197    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2198    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2199    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2200    JUMPHERE(jump);    JUMPHERE(jump);
2201  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2202    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2203    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2204    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 1737  if (common->utf) Line 2209  if (common->utf)
2209    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2210    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2211    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2212  #endif  #elif defined COMPILE_PCRE32
2213  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2214      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2215      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2216      JUMPHERE(jump);
2217    #endif /* COMPILE_PCRE[8|16|32] */
2218    return;    return;
2219    }    }
2220  #endif  #endif /* SUPPORT_UTF */
2221  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2222  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2223  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2224  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2225  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2226  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2227  #endif  #endif
2228  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2229  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2230  JUMPHERE(jump);  JUMPHERE(jump);
2231  #endif  #endif
2232  }  }
# Line 1759  static void skip_char_back(compiler_comm Line 2235  static void skip_char_back(compiler_comm
2235  {  {
2236  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2237  DEFINE_COMPILER;  DEFINE_COMPILER;
2238  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2239    #if defined COMPILE_PCRE8
2240  struct sljit_label *label;  struct sljit_label *label;
2241    
2242  if (common->utf)  if (common->utf)
# Line 1771  if (common->utf) Line 2248  if (common->utf)
2248    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2249    return;    return;
2250    }    }
2251  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2252  if (common->utf)  if (common->utf)
2253    {    {
2254    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 1785  if (common->utf) Line 2261  if (common->utf)
2261    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2262    return;    return;
2263    }    }
2264  #endif  #endif /* COMPILE_PCRE[8|16] */
2265    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2266  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2267  }  }
2268    
# Line 1816  else Line 2293  else
2293    
2294  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2295    
2296  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2297  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2298  {  {
2299  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 1904  sljit_emit_fast_return(compiler, RETURN_ Line 2381  sljit_emit_fast_return(compiler, RETURN_
2381  JUMPHERE(jump);  JUMPHERE(jump);
2382    
2383  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2384  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2385  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2386  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2387  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2388  }  }
2389    
2390  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2391    
 #ifdef COMPILE_PCRE16  
2392  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2393  {  {
2394  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 1937  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2413  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2413  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2414  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2415  }  }
 #endif /* COMPILE_PCRE16 */  
2416    
2417  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2418    
2419  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2420    
# Line 1959  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 2434  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
2434    
2435  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2436  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2437  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
2438  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2439  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2440  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2441  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2442  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2443  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
2444  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2445  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2446  }  }
# Line 1979  struct sljit_label *newlinelabel = NULL; Line 2454  struct sljit_label *newlinelabel = NULL;
2454  struct sljit_jump *start;  struct sljit_jump *start;
2455  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2456  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2457  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2458  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2459  #endif  #endif
2460  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 1994  if (firstline) Line 2469  if (firstline)
2469    {    {
2470    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2471    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2472    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);  
2473    
2474    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2475      {      {
# Line 2006  if (firstline) Line 2480  if (firstline)
2480      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2481      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);
2482      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);
2483        JUMPHERE(end);
2484      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));
2485      }      }
2486    else    else
# Line 2017  if (firstline) Line 2492  if (firstline)
2492      read_char(common);      read_char(common);
2493      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2494      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2495        JUMPHERE(end);
2496      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);
2497      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2498      }      }
2499    
2500    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2501    }    }
2502    
2503  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2035  if (newlinecheck) Line 2510  if (newlinecheck)
2510    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2511    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2512    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2513  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2514    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2515  #endif  #endif
2516    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2517    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2057  if (newlinecheck) Line 2532  if (newlinecheck)
2532    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2533    
2534  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2535  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2536    #if defined COMPILE_PCRE8
2537  if (common->utf)  if (common->utf)
2538    {    {
2539    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2540    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_sw)PRIV(utf8_table4) - 0xc0);
2541    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2542    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2543    }    }
2544  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2545  if (common->utf)  if (common->utf)
2546    {    {
2547    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
# Line 2077  if (common->utf) Line 2552  if (common->utf)
2552    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2553    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2554    }    }
2555  #endif  #endif /* COMPILE_PCRE[8|16] */
2556    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2557  JUMPHERE(start);  JUMPHERE(start);
2558    
2559  if (newlinecheck)  if (newlinecheck)
# Line 2089  if (newlinecheck) Line 2565  if (newlinecheck)
2565  return mainloop;  return mainloop;
2566  }  }
2567    
2568    #define MAX_N_CHARS 3
2569    
2570    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2571    {
2572    DEFINE_COMPILER;
2573    struct sljit_label *start;
2574    struct sljit_jump *quit;
2575    pcre_uint32 chars[MAX_N_CHARS * 2];
2576    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2577    int location = 0;
2578    pcre_int32 len, c, bit, caseless;
2579    int must_stop;
2580    
2581    /* We do not support alternatives now. */
2582    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2583      return FALSE;
2584    
2585    while (TRUE)
2586      {
2587      caseless = 0;
2588      must_stop = 1;
2589      switch(*cc)
2590        {
2591        case OP_CHAR:
2592        must_stop = 0;
2593        cc++;
2594        break;
2595    
2596        case OP_CHARI:
2597        caseless = 1;
2598        must_stop = 0;
2599        cc++;
2600        break;
2601    
2602        case OP_SOD:
2603        case OP_SOM:
2604        case OP_SET_SOM:
2605        case OP_NOT_WORD_BOUNDARY:
2606        case OP_WORD_BOUNDARY:
2607        case OP_EODN:
2608        case OP_EOD:
2609        case OP_CIRC:
2610        case OP_CIRCM:
2611        case OP_DOLL:
2612        case OP_DOLLM:
2613        /* Zero width assertions. */
2614        cc++;
2615        continue;
2616    
2617        case OP_PLUS:
2618        case OP_MINPLUS:
2619        case OP_POSPLUS:
2620        cc++;
2621        break;
2622    
2623        case OP_EXACT:
2624        cc += 1 + IMM2_SIZE;
2625        break;
2626    
2627        case OP_PLUSI:
2628        case OP_MINPLUSI:
2629        case OP_POSPLUSI:
2630        caseless = 1;
2631        cc++;
2632        break;
2633    
2634        case OP_EXACTI:
2635        caseless = 1;
2636        cc += 1 + IMM2_SIZE;
2637        break;
2638    
2639        default:
2640        must_stop = 2;
2641        break;
2642        }
2643    
2644      if (must_stop == 2)
2645          break;
2646    
2647      len = 1;
2648    #ifdef SUPPORT_UTF
2649      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2650    #endif
2651    
2652      if (caseless && char_has_othercase(common, cc))
2653        {
2654        caseless = char_get_othercase_bit(common, cc);
2655        if (caseless == 0)
2656          return FALSE;
2657    #ifdef COMPILE_PCRE8
2658        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2659    #else
2660        if ((caseless & 0x100) != 0)
2661          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2662        else
2663          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2664    #endif
2665        }
2666      else
2667        caseless = 0;
2668    
2669      while (len > 0 && location < MAX_N_CHARS * 2)
2670        {
2671        c = *cc;
2672        bit = 0;
2673        if (len == (caseless & 0xff))
2674          {
2675          bit = caseless >> 8;
2676          c |= bit;
2677          }
2678    
2679        chars[location] = c;
2680        chars[location + 1] = bit;
2681    
2682        len--;
2683        location += 2;
2684        cc++;
2685        }
2686    
2687      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2688        break;
2689      }
2690    
2691    /* At least two characters are required. */
2692    if (location < 2 * 2)
2693        return FALSE;
2694    
2695    if (firstline)
2696      {
2697      SLJIT_ASSERT(common->first_line_end != 0);
2698      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2699      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2700      }
2701    else
2702      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2703    
2704    start = LABEL();
2705    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2706    
2707    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2708    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2709    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2710    if (chars[1] != 0)
2711      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2712    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2713    if (location > 2 * 2)
2714      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2715    if (chars[3] != 0)
2716      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2717    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2718    if (location > 2 * 2)
2719      {
2720      if (chars[5] != 0)
2721        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2722      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2723      }
2724    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2725    
2726    JUMPHERE(quit);
2727    
2728    if (firstline)
2729      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2730    else
2731      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2732    return TRUE;
2733    }
2734    
2735    #undef MAX_N_CHARS
2736    
2737  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2738  {  {
2739  DEFINE_COMPILER;  DEFINE_COMPILER;
2740  struct sljit_label *start;  struct sljit_label *start;
2741  struct sljit_jump *leave;  struct sljit_jump *quit;
2742  struct sljit_jump *found;  struct sljit_jump *found;
2743  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2744    
2745  if (firstline)  if (firstline)
2746    {    {
2747    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2748      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2749    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);
2750    }    }
2751    
2752  start = LABEL();  start = LABEL();
2753  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2754  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2755    
2756  oc = first_char;  oc = first_char;
# Line 2121  if (first_char == oc) Line 2767  if (first_char == oc)
2767  else  else
2768    {    {
2769    bit = first_char ^ oc;    bit = first_char ^ oc;
2770    if (ispowerof2(bit))    if (is_powerof2(bit))
2771      {      {
2772      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2773      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2137  else Line 2783  else
2783    }    }
2784    
2785  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  
2786  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2787  JUMPHERE(found);  JUMPHERE(found);
2788  JUMPHERE(leave);  JUMPHERE(quit);
2789    
2790  if (firstline)  if (firstline)
2791    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2792  }  }
2793    
2794  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 2797  DEFINE_COMPILER;
2797  struct sljit_label *loop;  struct sljit_label *loop;
2798  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2799  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2800  struct sljit_jump *leave;  struct sljit_jump *quit;
2801  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2802  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2803  jump_list *newline = NULL;  jump_list *newline = NULL;
2804    
2805  if (firstline)  if (firstline)
2806    {    {
2807    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2808      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2809    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);
2810    }    }
2811    
# Line 2192  if (common->nltype == NLTYPE_FIXED && co Line 2820  if (common->nltype == NLTYPE_FIXED && co
2820    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2821    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2822    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2823  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2824    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2825  #endif  #endif
2826    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2827    
2828    loop = LABEL();    loop = LABEL();
2829    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));
2830    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2831    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2832    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2833    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);
2834    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);
2835    
2836    JUMPHERE(leave);    JUMPHERE(quit);
2837    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2838    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2839    
# Line 2229  set_jumps(newline, loop); Line 2857  set_jumps(newline, loop);
2857    
2858  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2859    {    {
2860    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2861    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2862    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2863    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2864    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2865    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2866  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2867    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2868  #endif  #endif
2869    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2870    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2871    JUMPHERE(leave);    JUMPHERE(quit);
2872    }    }
2873  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2874  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2875    
2876  if (firstline)  if (firstline)
2877    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2878  }  }
2879    
2880  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)
2881  {  {
2882  DEFINE_COMPILER;  DEFINE_COMPILER;
2883  struct sljit_label *start;  struct sljit_label *start;
2884  struct sljit_jump *leave;  struct sljit_jump *quit;
2885  struct sljit_jump *found;  struct sljit_jump *found;
2886  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2887  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2261  struct sljit_jump *jump; Line 2889  struct sljit_jump *jump;
2889    
2890  if (firstline)  if (firstline)
2891    {    {
2892    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2893      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2894    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);
2895    }    }
2896    
2897  start = LABEL();  start = LABEL();
2898  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2899  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2900  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2901  if (common->utf)  if (common->utf)
# Line 2289  if (common->utf) Line 2918  if (common->utf)
2918    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2919  #endif  #endif
2920  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2921  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2922    #if defined COMPILE_PCRE8
2923  if (common->utf)  if (common->utf)
2924    {    {
2925    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2926    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2927    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2928    }    }
2929  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2930  if (common->utf)  if (common->utf)
2931    {    {
2932    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2307  if (common->utf) Line 2936  if (common->utf)
2936    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2937    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2938    }    }
2939  #endif  #endif /* COMPILE_PCRE[8|16] */
2940    #endif /* SUPPORT_UTF */
2941  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2942  JUMPHERE(found);  JUMPHERE(found);
2943  JUMPHERE(leave);  JUMPHERE(quit);
2944    
2945  if (firstline)  if (firstline)
2946    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2947  }  }
2948    
2949  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 2955  struct sljit_jump *alreadyfound;
2955  struct sljit_jump *found;  struct sljit_jump *found;
2956  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2957  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2958  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2959    
2960  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2961  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2356  if (req_char == oc) Line 2986  if (req_char == oc)
2986  else  else
2987    {    {
2988    bit = req_char ^ oc;    bit = req_char ^ oc;
2989    if (ispowerof2(bit))    if (is_powerof2(bit))
2990      {      {
2991      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2992      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 2394  mainloop = LABEL(); Line 3024  mainloop = LABEL();
3024  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3025  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
3026  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3027  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3028  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3029  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
3030  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3031    
3032  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2407  sljit_emit_fast_return(compiler, RETURN_ Line 3037  sljit_emit_fast_return(compiler, RETURN_
3037  JUMPHERE(jump);  JUMPHERE(jump);
3038  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
3039  /* Set string begin. */  /* Set string begin. */
3040  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3041  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3042  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
3043  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3044    
# Line 2416  JUMPHERE(jump); Line 3046  JUMPHERE(jump);
3046  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
3047    {    {
3048    jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);    jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3049    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3050    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3051    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3052    JUMPTO(SLJIT_JUMP, mainloop);    JUMPTO(SLJIT_JUMP, mainloop);
3053    
# Line 2425  if (common->mark_ptr != 0) Line 3055  if (common->mark_ptr != 0)
3055    }    }
3056    
3057  /* Unknown command. */  /* Unknown command. */
3058  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3059  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3060  }  }
3061    
# Line 2537  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3167  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3167  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3168  }  }
3169    
3170    /*
3171      range format:
3172    
3173      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3174      ranges[1] = first bit (0 or 1)
3175      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3176    */
3177    
3178    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3179    {
3180    DEFINE_COMPILER;
3181    struct sljit_jump *jump;
3182    
3183    if (ranges[0] < 0)
3184      return FALSE;
3185    
3186    switch(ranges[0])
3187      {
3188      case 1:
3189      if (readch)
3190        read_char(common);
3191      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3192      return TRUE;
3193    
3194      case 2:
3195      if (readch)
3196        read_char(common);
3197      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3198      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3199      return TRUE;
3200    
3201      case 4:
3202      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3203        {
3204        if (readch)
3205          read_char(common);
3206        if (ranges[1] != 0)
3207          {
3208          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3209          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3210          }
3211        else
3212          {
3213          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3214          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3215          JUMPHERE(jump);
3216          }
3217        return TRUE;
3218        }
3219      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3220        {
3221        if (readch)
3222          read_char(common);
3223        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3224        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3225        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3226        return TRUE;
3227        }
3228      return FALSE;
3229    
3230      default:
3231      return FALSE;
3232      }
3233    }
3234    
3235    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3236    {
3237    int i, bit, length;
3238    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3239    
3240    bit = ctypes[0] & flag;
3241    ranges[0] = -1;
3242    ranges[1] = bit != 0 ? 1 : 0;
3243    length = 0;
3244    
3245    for (i = 1; i < 256; i++)
3246      if ((ctypes[i] & flag) != bit)
3247        {
3248        if (length >= MAX_RANGE_SIZE)
3249          return;
3250        ranges[2 + length] = i;
3251        length++;
3252        bit ^= flag;
3253        }
3254    
3255    if (bit != 0)
3256      {
3257      if (length >= MAX_RANGE_SIZE)
3258        return;
3259      ranges[2 + length] = 256;
3260      length++;
3261      }
3262    ranges[0] = length;
3263    }
3264    
3265    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3266    {
3267    int ranges[2 + MAX_RANGE_SIZE];
3268    pcre_uint8 bit, cbit, all;
3269    int i, byte, length = 0;
3270    
3271    bit = bits[0] & 0x1;
3272    ranges[1] = bit;
3273    /* Can be 0 or 255. */
3274    all = -bit;
3275    
3276    for (i = 0; i < 256; )
3277      {
3278      byte = i >> 3;
3279      if ((i & 0x7) == 0 && bits[byte] == all)
3280        i += 8;
3281      else
3282        {
3283        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3284        if (cbit != bit)
3285          {
3286          if (length >= MAX_RANGE_SIZE)
3287            return FALSE;
3288          ranges[2 + length] = i;
3289          length++;
3290          bit = cbit;
3291          all = -cbit;
3292          }
3293        i++;
3294        }
3295      }
3296    
3297    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3298      {
3299      if (length >= MAX_RANGE_SIZE)
3300        return FALSE;
3301      ranges[2 + length] = 256;
3302      length++;
3303      }
3304    ranges[0] = length;
3305    
3306    return check_ranges(common, ranges, backtracks, FALSE);
3307    }
3308    
3309  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3310  {  {
3311  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 2548  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3317  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3317  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3318  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3319  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3320  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3321  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3322  if (common->utf)  if (common->utf)
3323    {    {
# Line 2559  if (common->utf) Line 3328  if (common->utf)
3328  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3329    }    }
3330  #endif  #endif
3331  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3332  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3333  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3334  }  }
# Line 2576  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 3345  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
3345  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3346  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3347  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3348  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3350  if (common->utf)  if (common->utf)
3351    {    {
# Line 2597  if (common->utf) Line 3366  if (common->utf)
3366  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3367    }    }
3368  #endif  #endif
3369  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3370  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3371    
3372  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2614  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3383  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3383  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3384  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3385  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3386  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3387  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3388  if (common->utf)  if (common->utf)
3389    {    {
# Line 2625  if (common->utf) Line 3394  if (common->utf)
3394  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3395    }    }
3396  #endif  #endif
3397  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3398  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3399    
3400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2715  sljit_emit_fast_return(compiler, RETURN_ Line 3484  sljit_emit_fast_return(compiler, RETURN_
3484  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3485  {  {
3486  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3487  int c1, c2;  pcre_uint32 c1, c2;
3488  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3489  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3490    const ucd_record *ur;
3491    const pcre_uint32 *pp;
3492    
3493  while (src1 < end1)  while (src1 < end1)
3494    {    {
# Line 2725  while (src1 < end1) Line 3496  while (src1 < end1)
3496      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3497    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3498    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3499    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3500      if (c1 != c2 && c1 != c2 + ur->other_case)
3501        {
3502        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3503        for (;;)
3504          {
3505          if (c1 < *pp) return NULL;
3506          if (c1 == *pp++) break;
3507          }
3508        }
3509    }    }
3510  return src2;  return src2;
3511  }  }
# Line 2747  if (caseless && char_has_othercase(commo Line 3527  if (caseless && char_has_othercase(commo
3527    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3528    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3529    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3530  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3531    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3532    othercasebit &= 0xff;    othercasebit &= 0xff;
3533  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3534  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3535      ever are characters outside the BMP whose othercase differs in only one
3536      bit from itself (there currently are none), this code will need to be
3537      revised for COMPILE_PCRE32. */
3538    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3539    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3540      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3541    else    else
3542      othercasebit &= 0xff;      othercasebit &= 0xff;
3543  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3544    }    }
3545    
3546  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3547    {    {
3548  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3549  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3550    if (context->length >= 4)    if (context->length >= 4)
3551      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 2772  if (context->sourcereg == -1) Line 3554  if (context->sourcereg == -1)
3554    else    else
3555  #endif  #endif
3556      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3557  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3558  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3559    if (context->length >= 4)    if (context->length >= 4)
3560      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3561    else    else
3562  #endif  #endif
3563      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3564  #endif  #elif defined COMPILE_PCRE32
3565  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3566    #endif /* COMPILE_PCRE[8|16|32] */
3567    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3568    }    }
3569    
# Line 2810  do Line 3592  do
3592      }      }
3593    context->ucharptr++;    context->ucharptr++;
3594    
3595  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3596    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3597  #else  #elif defined COMPILE_PCRE16
3598    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3599    #elif defined COMPILE_PCRE32
3600      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3601  #endif  #endif
3602      {      {
3603    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3604      if (context->length >= 4)      if (context->length >= 4)
3605        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3606  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3607      else if (context->length >= 2)      else if (context->length >= 2)
3608        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3609      else if (context->length >= 1)      else if (context->length >= 1)
3610        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3611  #else  #elif defined COMPILE_PCRE16
3612      else if (context->length >= 2)      else if (context->length >= 2)
3613        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3614  #endif  #endif /* COMPILE_PCRE[8|16] */
3615    #elif defined COMPILE_PCRE32
3616        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3617    #endif /* COMPILE_PCRE[8|16|32] */
3618      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3619    
3620      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2837  do Line 3625  do
3625        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3626        break;        break;
3627    
3628    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3629        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3630        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3631          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 2851  do Line 3640  do
3640        break;        break;
3641  #endif  #endif
3642    
3643    #endif /* COMPILE_PCRE[8|16] */
3644    
3645        default:        default:
3646        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3647        break;        break;
# Line 2861  do Line 3652  do
3652  #else  #else
3653    
3654    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
3655    if (context->length > 0)    if (context->length > 0)
3656      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3657  #else  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3658    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3659    
3660    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 2912  return cc; Line 3699  return cc;
3699      } \      } \
3700    charoffset = (value);    charoffset = (value);
3701    
3702  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3703  {  {
3704  DEFINE_COMPILER;  DEFINE_COMPILER;
3705  jump_list *found = NULL;  jump_list *found = NULL;
3706  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3707  unsigned int c;  pcre_int32 c, charoffset;
3708  int compares;  const pcre_uint32 *other_cases;
3709  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3710  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3711    int compares, invertcmp, numberofcmps;
3712  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3713  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3714  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3715  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3716  unsigned int typeoffset;  pcre_int32 typeoffset;
3717  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3718    
3719  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3720       not necessary in utf mode even in 8 bit mode. */
3721  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3722  read_char(common);  read_char(common);
3723    
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3731  if ((*cc++ & XCL_MAP) != 0)
3731      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3732  #endif  #endif
3733    
3734    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3735    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3736    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3737    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3738    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
3739    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3740        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3741        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3742        }
3743    
3744  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3745    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3022  while (*cc != XCL_END) Line 3812  while (*cc != XCL_END)
3812        needschar = TRUE;        needschar = TRUE;
3813        break;        break;
3814    
3815          case PT_CLIST:
3816          needschar = TRUE;
3817          break;
3818    
3819        default:        default:
3820        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3821        break;        break;
# Line 3058  if (needstype || needsscript) Line 3852  if (needstype || needsscript)
3852      {      {
3853      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3854        {        {
3855        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3856        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3857        }        }
3858      else      else
3859        {        {
3860        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3861        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3862        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3863        }        }
3864      }      }
# Line 3217  while (*cc != XCL_END) Line 4011  while (*cc != XCL_END)
4011        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4012        break;        break;
4013    
4014        case PT_WORD:        case PT_WORD:
4015        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
4016        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4017        /* ... fall through */        /* ... fall through */
4018    
4019          case PT_ALNUM:
4020          SET_TYPE_OFFSET(ucp_Ll);
4021          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4022          COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
4023          SET_TYPE_OFFSET(ucp_Nd);
4024          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4025          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4026          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4027          break;
4028    
4029          case PT_CLIST:
4030          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4031    
4032          /* At least three characters are required.
4033             Otherwise this case would be handled by the normal code path. */
4034          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4035          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4036    
4037          /* Optimizing character pairs, if their difference is power of 2. */
4038          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4039            {
4040            if (charoffset == 0)
4041              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4042            else
4043              {
4044              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4045              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4046              }
4047            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4048            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4049            other_cases += 2;
4050            }
4051          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4052            {
4053            if (charoffset == 0)
4054              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4055            else
4056              {
4057              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4058              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4059              }
4060            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4061            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4062    
4063            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4064            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4065    
4066        case PT_ALNUM:          other_cases += 3;
4067        SET_TYPE_OFFSET(ucp_Ll);          }
4068        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);        else
4069        COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);          {
4070        SET_TYPE_OFFSET(ucp_Nd);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4071        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4072        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);          }
4073    
4074          while (*other_cases != NOTACHAR)
4075            {
4076            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4077            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4078            }
4079        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4080        break;        break;
4081        }        }
# Line 3249  if (found != NULL) Line 4096  if (found != NULL)
4096    
4097  #endif  #endif
4098    
4099  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
4100  {  {
4101  DEFINE_COMPILER;  DEFINE_COMPILER;
4102  int length;  int length;
# Line 3285  switch(type) Line 4132  switch(type)
4132    
4133    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4134    case OP_DIGIT:    case OP_DIGIT:
4135      /* Digits are usually 0-9, so it is worth to optimize them. */
4136      if (common->digits[0] == -2)
4137        get_ctype_ranges(common, ctype_digit, common->digits);
4138    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4139    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4140    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4141    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4142      if (!check_ranges(common, common->digits, backtracks, TRUE))
4143        {
4144        read_char8_type(common);
4145        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4146        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4147        }
4148      if (type == OP_NOT_DIGIT)
4149        common->digits[1] ^= 1;
4150    return cc;    return cc;
4151    
4152    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3335  switch(type) Line 4193  switch(type)
4193      {      {
4194      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4195      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4196  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4197    #if defined COMPILE_PCRE8
4198      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4199      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4200      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4201  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4202      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4203      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4204      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4205      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4206      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4207      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4208  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4209      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4210    #endif /* COMPILE_PCRE[8|16] */
4211      return cc;      return cc;
4212      }      }
4213  #endif  #endif
# Line 3370  switch(type) Line 4228  switch(type)
4228    propdata[2] = cc[0];    propdata[2] = cc[0];
4229    propdata[3] = cc[1];    propdata[3] = cc[1];
4230    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4231    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4232    return cc + 2;    return cc + 2;
4233  #endif  #endif
4234  #endif  #endif
# Line 3416  switch(type) Line 4274  switch(type)
4274    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4275    read_char(common);    read_char(common);
4276    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4277    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4278    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4279      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4280      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4281    
4282    label = LABEL();    label = LABEL();
4283    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4284    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4285    read_char(common);    read_char(common);
4286    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4287    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4288    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4289    
4290      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4291      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
4292      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4293      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4294      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4295      JUMPTO(SLJIT_C_NOT_ZERO, label);
4296    
4297    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4298    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4299      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4300    
4301    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4302      {      {
4303      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 3554  switch(type) Line 4423  switch(type)
4423    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4424    
4425    if (!common->endonly)    if (!common->endonly)
4426      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4427    else    else
4428      {      {
4429      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
# Line 3634  switch(type) Line 4503  switch(type)
4503      }      }
4504    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4505    bit = c ^ oc;    bit = c ^ oc;
4506    if (ispowerof2(bit))    if (is_powerof2(bit))
4507      {      {
4508      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4509      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 3642  switch(type) Line 4511  switch(type)
4511      }      }
4512    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);
4513    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4514    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);
4515    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4516    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4517    return cc + length;    return cc + length;
# Line 3670  switch(type) Line 4539  switch(type)
4539        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4540        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));
4541        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4542        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4543        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4544        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
4545        return cc + 1;        return cc + 1;
# Line 3695  switch(type) Line 4564  switch(type)
4564      {      {
4565      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4566      bit = c ^ oc;      bit = c ^ oc;
4567      if (ispowerof2(bit))      if (is_powerof2(bit))
4568        {        {
4569        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4570        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 3712  switch(type) Line 4581  switch(type)
4581    case OP_NCLASS:    case OP_NCLASS:
4582    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4583    read_char(common);    read_char(common);
4584      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4585        return cc + 32 / sizeof(pcre_uchar);
4586    
4587  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4588    jump[0] = NULL;    jump[0] = NULL;
4589  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3730  switch(type) Line 4602  switch(type)
4602  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4603    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4604    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4605    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4606    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4607    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4608    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
# Line 3740  switch(type) Line 4612  switch(type)
4612  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4613    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4614    
4615  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4616    case OP_XCLASS:    case OP_XCLASS:
4617    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4618    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4619  #endif  #endif
4620    
# Line 3776  SLJIT_ASSERT_STOP(); Line 4648  SLJIT_ASSERT_STOP();
4648  return cc;  return cc;
4649  }  }
4650    
4651  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4652  {  {
4653  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4654  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3839  if (context.length > 0) Line 4711  if (context.length > 0)
4711    }    }
4712    
4713  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4714  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4715  }  }
4716    
4717  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 3865  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4737  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4737  }  }
4738    
4739  /* Forward definitions. */  /* Forward definitions. */
4740  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4741  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4742    
4743  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4744    do \    do \
# Line 3896  static void compile_backtrackpath(compil Line 4768  static void compile_backtrackpath(compil
4768    
4769  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4770    
4771  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4772  {  {
4773  DEFINE_COMPILER;  DEFINE_COMPILER;
4774  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3978  if (jump != NULL) Line 4850  if (jump != NULL)
4850  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4851  }  }
4852    
4853  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4854  {  {
4855  DEFINE_COMPILER;  DEFINE_COMPILER;
4856  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4033  if (!minimize) Line 4905  if (!minimize)
4905      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4906      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
4907      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
4908      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
4909      zerolength = compile_ref_checks(common, ccbegin, NULL);      zerolength = compile_ref_checks(common, ccbegin, NULL);
4910      /* Restore if not zero length. */      /* Restore if not zero length. */
4911      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_sw));
4912      }      }
4913    else    else
4914      {      {
# Line 4049  if (!minimize) Line 4921  if (!minimize)
4921      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4922    
4923    label = LABEL();    label = LABEL();
4924    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4925    
4926    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4927      {      {
# Line 4077  if (!minimize) Line 4949  if (!minimize)
4949      }      }
4950    
4951    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4952    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4953    
4954    decrease_call_count(common);    decrease_call_count(common);
4955    return cc;    return cc;
# Line 4097  if (min == 0) Line 4969  if (min == 0)
4969  else  else
4970    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4971    
4972  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4973  if (max > 0)  if (max > 0)
4974    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4975    
4976  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4977  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4978    
4979  if (min > 1)  if (min > 1)
# Line 4109  if (min > 1) Line 4981  if (min > 1)
4981    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4982    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4983    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4984    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4985    }    }
4986  else if (max > 0)  else if (max > 0)
4987    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4122  decrease_call_count(common); Line 4994  decrease_call_count(common);
4994  return cc;  return cc;
4995  }  }
4996    
4997  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4998  {  {
4999  DEFINE_COMPILER;  DEFINE_COMPILER;
5000  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4179  add_jump(compiler, &backtrack->topbacktr Line 5051  add_jump(compiler, &backtrack->topbacktr
5051  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5052  }  }
5053    
5054  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5055  {  {
5056  DEFINE_COMPILER;  DEFINE_COMPILER;
5057  int framesize;  int framesize;
5058  int localptr;  int private_data_ptr;
5059  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5060  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5061  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4192  jump_list *tmp = NULL; Line 5064  jump_list *tmp = NULL;
5064  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5065  jump_list **found;  jump_list **found;
5066  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5067  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5068  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5069  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5070  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5071  struct sljit_jump *jump;  struct sljit_jump *jump;
5072  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5077  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5077    bra = *cc;    bra = *cc;
5078    cc++;    cc++;
5079    }    }
5080  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5081  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5082  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5083  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5084  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5085  opcode = *cc;  opcode = *cc;
5086  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5087  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4226  if (bra == OP_BRAMINZERO) Line 5098  if (bra == OP_BRAMINZERO)
5098    
5099  if (framesize < 0)  if (framesize < 0)
5100    {    {
5101    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5102    allocate_stack(common, 1);    allocate_stack(common, 1);
5103    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5104    }    }
5105  else  else
5106    {    {
5107    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5108    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5109    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
5110    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5111    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5112    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5113    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5114    }    }
5115    
5116  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5117  common->leavelabel = NULL;  common->quitlabel = NULL;
5118  common->leave = NULL;  common->quit = NULL;
5119  while (1)  while (1)
5120    {    {
5121    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4255  while (1) Line 5127  while (1)
5127      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5128    
5129    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5130    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5131    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5132      {      {
5133      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5134      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5135      common->leave = save_leave;      common->quit = save_quit;
5136      common->accept = save_accept;      common->accept = save_accept;
5137      return NULL;      return NULL;
5138      }      }
# Line 4270  while (1) Line 5142  while (1)
5142    
5143    /* Reset stack. */    /* Reset stack. */
5144    if (framesize < 0)    if (framesize < 0)
5145      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5146    else {    else {
5147      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5148        {        {
5149        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5150        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5151        }        }
5152      else      else
5153        {        {
5154        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5155        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5156        }        }
5157    }    }
# Line 4295  while (1) Line 5167  while (1)
5167          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5168        else        else
5169          {          {
5170          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5171          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5172          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5173          }          }
5174        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5175        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5176        }        }
5177      else if (framesize >= 0)      else if (framesize >= 0)
5178        {        {
5179        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5180        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5181        }        }
5182      }      }
5183    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5184    
5185    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5186    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5187      {      {
5188      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5189      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5190      common->leave = save_leave;      common->quit = save_quit;
5191      common->accept = save_accept;      common->accept = save_accept;
5192      return NULL;      return NULL;
5193      }      }
# Line 4328  while (1) Line 5200  while (1)
5200    cc += GET(cc, 1);    cc += GET(cc, 1);
5201    }    }
5202  /* None of them matched. */  /* None of them matched. */
5203  if (common->leave != NULL)  if (common->quit != NULL)
5204    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5205    
5206  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5207    {    {
# Line 4356  if (opcode == OP_ASSERT || opcode == OP_ Line 5228  if (opcode == OP_ASSERT || opcode == OP_
5228        }        }
5229      else      else
5230        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5231      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5232      }      }
5233    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5234    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4370  if (opcode == OP_ASSERT || opcode == OP_ Line 5242  if (opcode == OP_ASSERT || opcode == OP_
5242      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5243      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5244      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5245        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_sw));
5246      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5247        {        {
5248        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_sw));
5249        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5250        }        }
5251      }      }
# Line 4381  if (opcode == OP_ASSERT || opcode == OP_ Line 5253  if (opcode == OP_ASSERT || opcode == OP_
5253      {      {
5254      if (bra == OP_BRA)      if (bra == OP_BRA)
5255        {        {
5256        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5257        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5258        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5259        }        }
5260      else      else
5261        {        {
5262        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5263        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
5264        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5265        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5266        }        }
# Line 4396  if (opcode == OP_ASSERT || opcode == OP_ Line 5268  if (opcode == OP_ASSERT || opcode == OP_
5268    
5269    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5270      {      {
5271      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5272      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5273      }      }
5274    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5275      {      {
5276      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5277      JUMPHERE(brajump);      JUMPHERE(brajump);
5278      if (framesize >= 0)      if (framesize >= 0)
5279        {        {
5280        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5281        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5282        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5283        }        }
5284      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5285      }      }
# Line 4435  else Line 5307  else
5307        }        }
5308      else      else
5309        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5310      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5311      }      }
5312    
5313    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5314      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5315    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5316      {      {
5317      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5318      JUMPHERE(brajump);      JUMPHERE(brajump);
5319      }      }
5320    
# Line 4454  else Line 5326  else
5326      }      }
5327    }    }
5328    
5329  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5330  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5331  common->leave = save_leave;  common->quit = save_quit;
5332  common->accept = save_accept;  common->accept = save_accept;
5333  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5334  }  }
5335    
5336  static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)  static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table)
5337  {  {
5338  int condition = FALSE;  int condition = FALSE;
5339  pcre_uchar *slotA = name_table;  pcre_uchar *slotA = name_table;
5340  pcre_uchar *slotB;  pcre_uchar *slotB;
5341  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)];
5342  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];
5343  sljit_w no_capture;  sljit_sw no_capture;
5344  int i;  int i;
5345    
5346  locals += refno & 0xff;  locals += refno & 0xff;
# Line 4518  if (i < name_count) Line 5390  if (i < name_count)
5390  return condition;  return condition;
5391  }  }
5392    
5393  static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)  static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table)
5394  {  {
5395  int condition = FALSE;  int condition = FALSE;
5396  pcre_uchar *slotA = name_table;  pcre_uchar *slotA = name_table;
5397  pcre_uchar *slotB;  pcre_uchar *slotB;
5398  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)];
5399  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];
5400  sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];  sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)];
5401  int i;  sljit_uw i;
5402    
5403  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
5404    {    {
# Line 4625  return condition; Line 5497  return condition;
5497                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5498  */  */
5499    
5500  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5501  {  {
5502  DEFINE_COMPILER;  DEFINE_COMPILER;
5503  backtrack_common *backtrack;  backtrack_common *backtrack;
5504  pcre_uchar opcode;  pcre_uchar opcode;
5505  int localptr = 0;  int private_data_ptr = 0;
5506  int offset = 0;  int offset = 0;
5507  int stacksize;  int stacksize;
5508  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5509  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5510  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5511  pcre_uchar ket;  pcre_uchar ket;
5512  assert_backtrack *assert;  assert_backtrack *assert;
# Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5527  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5527    
5528  opcode = *cc;  opcode = *cc;
5529  ccbegin = cc;  ccbegin = cc;
5530  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5531    
5532  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5533    {    {
# Line 4672  cc += GET(cc, 1); Line 5544  cc += GET(cc, 1);
5544  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5545  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5546    {    {
5547    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5548    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5549      {      {
5550      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5551      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5552        has_alternatives = FALSE;        has_alternatives = FALSE;
5553      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
5554        has_alternatives = stacksize != 0;        has_alternatives = stacksize != 0;
5555      else      else
5556        has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        has_alternatives = stacksize != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5557      }      }
5558    }    }
5559    
# Line 4694  if (opcode == OP_CBRA || opcode == OP_SC Line 5566  if (opcode == OP_CBRA || opcode == OP_SC
5566    {    {
5567    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5568    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5569    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5570    offset <<= 1;      {
5571    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5572    trypath += IMM2_SIZE;      offset <<= 1;
5573        }
5574      else
5575        {
5576        offset <<= 1;
5577        private_data_ptr = OVECTOR(offset);
5578        }
5579      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5580      matchingpath += IMM2_SIZE;
5581    }    }
5582  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5583    {    {
5584    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5585    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5586    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5587    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5588    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5589      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5590    }    }
# Line 4750  if (bra == OP_BRAMINZERO) Line 5630  if (bra == OP_BRAMINZERO)
5630        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5631        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5632          {          {
5633          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5634          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5635          }          }
5636        else        else
5637          {          {
5638          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5639          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5640          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
5641          }          }
5642        JUMPHERE(skip);        JUMPHERE(skip);
5643        }        }
# Line 4771  if (bra == OP_BRAMINZERO) Line 5651  if (bra == OP_BRAMINZERO)
5651    }    }
5652    
5653  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5654    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5655    
5656  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5657    {    {
5658    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5659    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5660      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5661    }    }
5662    
5663  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 4788  if (opcode == OP_ONCE) Line 5668  if (opcode == OP_ONCE)
5668      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5669      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5670        {        {
5671        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5672        allocate_stack(common, 2);        allocate_stack(common, 2);
5673        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5674        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5675        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5676        }        }
5677      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5678        {        {
5679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5680        allocate_stack(common, 1);        allocate_stack(common, 1);
5681        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5682        }        }
5683      else      else
5684        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5685      }      }
5686    else    else
5687      {      {
5688      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5689        {        {
5690        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5691        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5692        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5693        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5694        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5695        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5696        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5697        }        }
5698      else      else
5699        {        {
5700        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5701        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5702        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5703        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5704        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5705        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5706        }        }
# Line 4829  if (opcode == OP_ONCE) Line 5709  if (opcode == OP_ONCE)
5709  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5710    {    {
5711    /* Saving the previous values. */    /* Saving the previous values. */
5712    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5713    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5714    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5715    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5716    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5717    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5719    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5720        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5721        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5722        }
5723      else
5724        {
5725        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5726        allocate_stack(common, 2);
5727        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5728        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_sw));
5729        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5730        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5731        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5732        }
5733    }    }
5734  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5735    {    {
5736    /* Saving the previous value. */    /* Saving the previous value. */
5737    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5738    allocate_stack(common, 1);    allocate_stack(common, 1);
5739    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5740    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5741    }    }
5742  else if (has_alternatives)  else if (has_alternatives)
# Line 4856  else if (has_alternatives) Line 5749  else if (has_alternatives)
5749  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5750  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5751    {    {
5752    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5753      {      {
5754      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5755      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5756        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5757      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5758      }      }
5759    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5760      {      {
5761      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5762      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5763      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5764    
5765      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5766      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);
5767      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);
5768      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));
5769      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5770      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5771      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
# Line 4880  if (opcode == OP_COND || opcode == OP_SC Line 5773  if (opcode == OP_COND || opcode == OP_SC
5773      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5774    
5775      JUMPHERE(jump);      JUMPHERE(jump);
5776      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5777      }      }
5778    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5779      {      {
5780      /* Never has other case. */      /* Never has other case. */
5781      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5782    
5783      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5784      if (common->currententry == NULL)      if (common->currententry == NULL)
5785        stacksize = 0;        stacksize = 0;
5786      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4895  if (opcode == OP_COND || opcode == OP_SC Line 5788  if (opcode == OP_COND || opcode == OP_SC
5788      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
5789        stacksize = stacksize == 0;        stacksize = stacksize == 0;
5790      else      else
5791        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5792    
5793      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5794        {        {
5795        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5796        if (stacksize != 0)        if (stacksize != 0)
5797          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5798        else        else
5799          {          {
5800          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5801            {            {
5802            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5803            cc += GET(cc, 1);            cc += GET(cc, 1);
5804            }            }
5805          else          else
5806            trypath = cc;            matchingpath = cc;
5807          }          }
5808        }        }
5809      else      else
5810        {        {
5811        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5812    
5813        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5814        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5815        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5816        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 4928  if (opcode == OP_COND || opcode == OP_SC Line 5821  if (opcode == OP_COND || opcode == OP_SC
5821        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5822        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5823        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5824        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5825        }        }
5826      }      }
5827    else    else
5828      {      {
5829      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5830      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5831      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5832      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5833        return NULL;        return NULL;
5834      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5835      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5836      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5837      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5838      }      }
5839    }    }
5840    
5841  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5842  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5843    return NULL;    return NULL;
5844    
# Line 4953  if (opcode == OP_ONCE) Line 5846  if (opcode == OP_ONCE)
5846    {    {
5847    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5848      {      {
5849      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5850      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5851      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5852        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5853      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5854        {        {
5855        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5856        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5857        }        }
5858      }      }
5859    else    else
5860      {      {
5861      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5862      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw));
5863      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5864        {        {
5865        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5001  if (has_alternatives) Line 5894  if (has_alternatives)
5894    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5895      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5896    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5897      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5898    }    }
5899    
5900  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5901  if (offset != 0)  if (offset != 0)
5902    {    {
5903    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5904    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5905    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5906    }    }
# Line 5017  if (ket == OP_KETRMAX) Line 5910  if (ket == OP_KETRMAX)
5910    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5911      {      {
5912      if (has_alternatives)      if (has_alternatives)
5913        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5914      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5915      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5916        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        {
5917          CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5918          /* Drop STR_PTR for greedy plus quantifier. */
5919          if (bra != OP_BRAZERO)
5920            free_stack(common, 1);
5921          }
5922      else      else
5923        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5924        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5925      }      }
5926    else    else
5927      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5928    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5929    }    }
5930    
5931  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5932    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5933    
5934  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5935    {    {
5936    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5937    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5938    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5939      {      {
5940      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5045  if (bra == OP_BRAMINZERO) Line 5943  if (bra == OP_BRAMINZERO)
5943      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5944      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5945        {        {
5946        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5947        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5948        }        }
5949      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5064  cc += 1 + LINK_SIZE; Line 5962  cc += 1 + LINK_SIZE;
5962  return cc;  return cc;
5963  }  }
5964    
5965  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5966  {  {
5967  DEFINE_COMPILER;  DEFINE_COMPILER;
5968  backtrack_common *backtrack;  backtrack_common *backtrack;
5969  pcre_uchar opcode;  pcre_uchar opcode;
5970  int localptr;  int private_data_ptr;
5971  int cbraprivptr = 0;  int cbraprivptr = 0;
5972  int framesize;  int framesize;
5973  int stacksize;  int stacksize;
# Line 5088  if (*cc == OP_BRAPOSZERO) Line 5986  if (*cc == OP_BRAPOSZERO)
5986    }    }
5987    
5988  opcode = *cc;  opcode = *cc;
5989  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5990  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5991  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5992  switch(opcode)  switch(opcode)
5993    {    {
5994    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5101  switch(opcode) Line 5999  switch(opcode)
5999    case OP_CBRAPOS:    case OP_CBRAPOS:
6000    case OP_SCBRAPOS:    case OP_SCBRAPOS:
6001    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
6002      /* This case cannot be optimized in the same was as
6003      normal capturing brackets. */
6004      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
6005    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6006    offset <<= 1;    offset <<= 1;
6007    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5120  if (framesize < 0) Line 6021  if (framesize < 0)
6021      stacksize++;      stacksize++;
6022    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6023    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6024    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6025    
6026    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6027      {      {
# Line 5145  else Line 6046  else
6046    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6047    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6048    
6049    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6050    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6051    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6052    stack = 0;    stack = 0;
6053    if (!zero)    if (!zero)
6054      {      {
#