/[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 884 by zherczeg, Tue Jan 17 11:52:43 2012 UTC revision 1015 by ph10, Sun Aug 26 16:07:14 2012 UTC
# 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 82  The code generator follows the recursive Line 85  The code generator follows the recursive
85  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
86  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
87  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
88  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
89    
90    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
91    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
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 hot 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 'fallback' 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 hot path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Hot path: match happens.     Matching path: match happens.
101     Fallback path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Hot path: no need to perform a match.     Matching path: no need to perform a match.
104     Fallback 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
107  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# 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 hot path   A matching path
115   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B hot path   B matching path
117   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D hot path   D matching path
119   return with successful match   return with successful match
120    
121   D fallback path   D backtrack path
122   ')' fallback path (If we arrived from "C" jump to the fallback of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
123   B fallback path   B backtrack path
124   C expected path   C expected path
125   jump to D hot path   jump to D matching path
126   C fallback path   C backtrack path
127   A fallback path   A backtrack path
128    
129   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of backtrack code paths are the opposite of the fast
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 fallback code path. The fallback code 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 hot 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 fallback 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 fallback 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 152  typedef struct jit_arguments { Line 155  typedef struct jit_arguments {
155    const pcre_uchar *begin;    const pcre_uchar *begin;
156    const pcre_uchar *end;    const pcre_uchar *end;
157    int *offsets;    int *offsets;
158    pcre_uchar *ptr;    pcre_uchar *uchar_ptr;
159      pcre_uchar *mark_ptr;
160    /* Everything else after. */    /* Everything else after. */
161    int offsetcount;    int offsetcount;
162    int calllimit;    int calllimit;
# Line 162  typedef struct jit_arguments { Line 166  typedef struct jit_arguments {
166    pcre_uint8 notempty_atstart;    pcre_uint8 notempty_atstart;
167  } jit_arguments;  } jit_arguments;
168    
169  typedef struct executable_function {  typedef struct executable_functions {
170    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
171    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
172    void *userdata;    void *userdata;
173    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
174  } executable_function;  } executable_functions;
175    
176  typedef struct jump_list {  typedef struct jump_list {
177    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 180  typedef struct stub_list { Line 184  typedef struct stub_list {
184    enum stub_types type;    enum stub_types type;
185    int data;    int data;
186    struct sljit_jump *start;    struct sljit_jump *start;
187    struct sljit_label *leave;    struct sljit_label *quit;
188    struct stub_list *next;    struct stub_list *next;
189  } stub_list;  } stub_list;
190    
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct fallback_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
199    struct fallback_common *prev;    struct backtrack_common *prev;
200    jump_list *nextfallbacks;    jump_list *nextbacktracks;
201    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
202    struct fallback_common *top;    struct backtrack_common *top;
203    jump_list *topfallbacks;    jump_list *topbacktracks;
204    /* Opcode pointer. */    /* Opcode pointer. */
205    pcre_uchar *cc;    pcre_uchar *cc;
206  } fallback_common;  } backtrack_common;
207    
208  typedef struct assert_fallback {  typedef struct assert_backtrack {
209    fallback_common common;    backtrack_common common;
210    jump_list *condfailed;    jump_list *condfailed;
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
217  } assert_fallback;  } assert_backtrack;
218    
219  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
220    fallback_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
230      jump_list *condfailed;      jump_list *condfailed;
231      assert_fallback *assert;      assert_backtrack *assert;
232      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_fallback;  } bracket_backtrack;
238    
239  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
240    fallback_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
246    int stacksize;    int stacksize;
247  } bracketpos_fallback;  } bracketpos_backtrack;
248    
249  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
250    fallback_common common;    backtrack_common common;
251    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
252  } braminzero_fallback;  } braminzero_backtrack;
253    
254  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
255    fallback_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
258  } iterator_fallback;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
261    struct recurse_entry *next;    struct recurse_entry *next;
# Line 263  typedef struct recurse_entry { Line 267  typedef struct recurse_entry {
267    int start;    int start;
268  } recurse_entry;  } recurse_entry;
269    
270  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
271    fallback_common common;    backtrack_common common;
272  } recurse_fallback;  } recurse_backtrack;
273    
274    #define MAX_RANGE_SIZE 6
275    
276  typedef struct compiler_common {  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    int localsize;  
280    int *localptrs;    /* Maps private data offset to each opcode. */
281      int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285      int cbraptr;
286      /* OVector starting point. Must be divisible by 2. */
287      int ovector_start;
288      /* Last known position of the requested byte. */
289      int req_char_ptr;
290      /* Head of the last recursion. */
291      int recursive_head;
292      /* First inspected character for partial matching. */
293      int start_used_ptr;
294      /* Starting pointer for partial soft matches. */
295      int hit_start;
296      /* End pointer of the first line. */
297      int first_line_end;
298      /* Points to the marked string. */
299      int mark_ptr;
300    
301      /* Flipped and lower case tables. */
302    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
303    sljit_w lcc;    sljit_w lcc;
304    int cbraptr;    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
305      int mode;
306      /* Newline control. */
307    int nltype;    int nltype;
308    int newline;    int newline;
309    int bsr_nltype;    int bsr_nltype;
310      /* Dollar endonly. */
311    int endonly;    int endonly;
312      BOOL has_set_som;
313      /* Tables. */
314    sljit_w ctypes;    sljit_w ctypes;
315      int digits[2 + MAX_RANGE_SIZE];
316      /* Named capturing brackets. */
317    sljit_uw name_table;    sljit_uw name_table;
318    sljit_w name_count;    sljit_w name_count;
319    sljit_w name_entry_size;    sljit_w name_entry_size;
320    
321      /* Labels and jump lists. */
322      struct sljit_label *partialmatchlabel;
323      struct sljit_label *quitlabel;
324    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
325    stub_list *stubs;    stub_list *stubs;
326    recurse_entry *entries;    recurse_entry *entries;
327    recurse_entry *currententry;    recurse_entry *currententry;
328      jump_list *partialmatch;
329      jump_list *quit;
330    jump_list *accept;    jump_list *accept;
331    jump_list *calllimit;    jump_list *calllimit;
332    jump_list *stackalloc;    jump_list *stackalloc;
# Line 349  typedef struct compare_context { Line 389  typedef struct compare_context {
389    
390  enum {  enum {
391    frame_end = 0,    frame_end = 0,
392    frame_setstrbegin = -1    frame_setstrbegin = -1,
393      frame_setmark = -2
394  };  };
395    
396  /* Undefine sljit macros. */  /* Undefine sljit macros. */
# Line 369  enum { Line 410  enum {
410  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
411  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
412    
413  /* Locals layout. */  /* Local space layout. */
414  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
415  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
416  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
417  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
418  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
419  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
420  /* Max limit of recursions. */  /* Max limit of recursions. */
421  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
422  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
423  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
424  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
425  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. */
426  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
427  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
428  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
429  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
430    
431  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
432  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
# Line 426  the start pointers when the end of the c Line 461  the start pointers when the end of the c
461    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
462  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
463    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
464    #define GET_LOCAL_BASE(dst, dstw, offset) \
465      sljit_get_local_base(compiler, (dst), (dstw), (offset))
466    
467  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
468  {  {
# Line 438  return cc; Line 475  return cc;
475    
476  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
477   next_opcode   next_opcode
478   get_localspace   get_private_data_length
479   set_localptrs   set_private_data_ptrs
480   get_framesize   get_framesize
481   init_frame   init_frame
482   get_localsize   get_private_data_length_for_copy
483   copy_locals   copy_private_data
484   compile_hotpath   compile_matchingpath
485   compile_fallbackpath   compile_backtrackingpath
486  */  */
487    
488  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 497  switch(*cc) Line 534  switch(*cc)
534    case OP_BRAZERO:    case OP_BRAZERO:
535    case OP_BRAMINZERO:    case OP_BRAMINZERO:
536    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
537      case OP_COMMIT:
538    case OP_FAIL:    case OP_FAIL:
539    case OP_ACCEPT:    case OP_ACCEPT:
540    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 635  switch(*cc) Line 673  switch(*cc)
673    case OP_SCBRAPOS:    case OP_SCBRAPOS:
674    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
675    
676      case OP_MARK:
677      return cc + 1 + 2 + cc[1];
678    
679    default:    default:
680    return NULL;    return NULL;
681    }    }
682  }  }
683    
684  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
685        case OP_MINSTAR: \
686        case OP_MINPLUS: \
687        case OP_QUERY: \
688        case OP_MINQUERY: \
689        case OP_MINSTARI: \
690        case OP_MINPLUSI: \
691        case OP_QUERYI: \
692        case OP_MINQUERYI: \
693        case OP_NOTMINSTAR: \
694        case OP_NOTMINPLUS: \
695        case OP_NOTQUERY: \
696        case OP_NOTMINQUERY: \
697        case OP_NOTMINSTARI: \
698        case OP_NOTMINPLUSI: \
699        case OP_NOTQUERYI: \
700        case OP_NOTMINQUERYI:
701    
702    #define CASE_ITERATOR_PRIVATE_DATA_2A \
703        case OP_STAR: \
704        case OP_PLUS: \
705        case OP_STARI: \
706        case OP_PLUSI: \
707        case OP_NOTSTAR: \
708        case OP_NOTPLUS: \
709        case OP_NOTSTARI: \
710        case OP_NOTPLUSI:
711    
712    #define CASE_ITERATOR_PRIVATE_DATA_2B \
713        case OP_UPTO: \
714        case OP_MINUPTO: \
715        case OP_UPTOI: \
716        case OP_MINUPTOI: \
717        case OP_NOTUPTO: \
718        case OP_NOTMINUPTO: \
719        case OP_NOTUPTOI: \
720        case OP_NOTMINUPTOI:
721    
722    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
723        case OP_TYPEMINSTAR: \
724        case OP_TYPEMINPLUS: \
725        case OP_TYPEQUERY: \
726        case OP_TYPEMINQUERY:
727    
728    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
729        case OP_TYPESTAR: \
730        case OP_TYPEPLUS:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
733        case OP_TYPEUPTO: \
734        case OP_TYPEMINUPTO:
735    
736    static int get_class_iterator_size(pcre_uchar *cc)
737    {
738    switch(*cc)
739      {
740      case OP_CRSTAR:
741      case OP_CRPLUS:
742      return 2;
743    
744      case OP_CRMINSTAR:
745      case OP_CRMINPLUS:
746      case OP_CRQUERY:
747      case OP_CRMINQUERY:
748      return 1;
749    
750      case OP_CRRANGE:
751      case OP_CRMINRANGE:
752      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
753        return 0;
754      return 2;
755    
756      default:
757      return 0;
758      }
759    }
760    
761    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
762  {  {
763  int localspace = 0;  int private_data_length = 0;
764  pcre_uchar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766    pcre_uchar *end = NULL;
767    int space, size, bracketlen, i;
768    
769  /* 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. */
770  while (cc < ccend)  while (cc < ccend)
771    {    {
772      space = 0;
773      size = 0;
774      bracketlen = 0;
775    switch(*cc)    switch(*cc)
776      {      {
777        case OP_SET_SOM:
778        common->has_set_som = TRUE;
779        cc += 1;
780        break;
781    
782        case OP_REF:
783        case OP_REFI:
784        common->optimized_cbracket[GET2(cc, 1)] = 0;
785        cc += 1 + IMM2_SIZE;
786        break;
787    
788      case OP_ASSERT:      case OP_ASSERT:
789      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
790      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 658  while (cc < ccend) Line 794  while (cc < ccend)
794      case OP_BRAPOS:      case OP_BRAPOS:
795      case OP_SBRA:      case OP_SBRA:
796      case OP_SBRAPOS:      case OP_SBRAPOS:
797      case OP_SCOND:      private_data_length += sizeof(sljit_w);
798      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
799      break;      break;
800    
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
804      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
806      break;      break;
807    
808      case OP_COND:      case OP_COND:
809      /* Might be a hidden SCOND. */      case OP_SCOND:
810      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
811      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
812        localspace += sizeof(sljit_w);        {
813          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
814          common->optimized_cbracket[bracketlen] = 0;
815          }
816        else if (bracketlen == OP_NCREF)
817          {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          name = (pcre_uchar *)common->name_table;
820          alternative = name;
821          for (i = 0; i < common->name_count; i++)
822            {
823            if (GET2(name, 0) == bracketlen) break;
824            name += common->name_entry_size;
825            }
826          SLJIT_ASSERT(i != common->name_count);
827    
828          for (i = 0; i < common->name_count; i++)
829            {
830            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
831              common->optimized_cbracket[GET2(alternative, 0)] = 0;
832            alternative += common->name_entry_size;
833            }
834          }
835    
836        if (*cc == OP_COND)
837          {
838          /* Might be a hidden SCOND. */
839          alternative = cc + GET(cc, 1);
840          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
841            private_data_length += sizeof(sljit_w);
842          }
843        else
844          private_data_length += sizeof(sljit_w);
845        bracketlen = 1 + LINK_SIZE;
846        break;
847    
848        case OP_BRA:
849        bracketlen = 1 + LINK_SIZE;
850        break;
851    
852        case OP_CBRA:
853        case OP_SCBRA:
854        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
855        break;
856    
857        CASE_ITERATOR_PRIVATE_DATA_1
858        space = 1;
859        size = -2;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_2A
863        space = 2;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2B
868        space = 2;
869        size = -(2 + IMM2_SIZE);
870        break;
871    
872        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
873        space = 1;
874        size = 1;
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
878        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
879          space = 2;
880        size = 1;
881        break;
882    
883        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
884        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
885          space = 2;
886        size = 1 + IMM2_SIZE;
887        break;
888    
889        case OP_CLASS:
890        case OP_NCLASS:
891        size += 1 + 32 / sizeof(pcre_uchar);
892        space = get_class_iterator_size(cc + size);
893        break;
894    
895    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
896        case OP_XCLASS:
897        size = GET(cc, 1);
898        space = get_class_iterator_size(cc + size);
899        break;
900    #endif
901    
902        case OP_RECURSE:
903        /* Set its value only once. */
904        if (common->recursive_head == 0)
905          {
906          common->recursive_head = common->ovector_start;
907          common->ovector_start += sizeof(sljit_w);
908          }
909      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
910      break;      break;
911    
912        case OP_MARK:
913        if (common->mark_ptr == 0)
914          {
915          common->mark_ptr = common->ovector_start;
916          common->ovector_start += sizeof(sljit_w);
917          }
918        cc += 1 + 2 + cc[1];
919        break;
920    
921      default:      default:
922      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
923      if (cc == NULL)      if (cc == NULL)
924        return -1;        return -1;
925      break;      break;
926      }      }
927    
928      if (space > 0 && cc >= end)
929        private_data_length += sizeof(sljit_w) * space;
930    
931      if (size != 0)
932        {
933        if (size < 0)
934          {
935          cc += -size;
936    #ifdef SUPPORT_UTF
937          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
938    #endif
939          }
940        else
941          cc += size;
942        }
943    
944      if (bracketlen > 0)
945        {
946        if (cc >= end)
947          {
948          end = bracketend(cc);
949          if (end[-1 - LINK_SIZE] == OP_KET)
950            end = NULL;
951          }
952        cc += bracketlen;
953        }
954    }    }
955  return localspace;  return private_data_length;
956  }  }
957    
958  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)
959  {  {
960  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
961  pcre_uchar *alternative;  pcre_uchar *alternative;
962    pcre_uchar *end = NULL;
963    int space, size, bracketlen;
964    
965  while (cc < ccend)  while (cc < ccend)
966    {    {
967      space = 0;
968      size = 0;
969      bracketlen = 0;
970    switch(*cc)    switch(*cc)
971      {      {
972      case OP_ASSERT:      case OP_ASSERT:
# Line 705  while (cc < ccend) Line 979  while (cc < ccend)
979      case OP_SBRA:      case OP_SBRA:
980      case OP_SBRAPOS:      case OP_SBRAPOS:
981      case OP_SCOND:      case OP_SCOND:
982      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
983      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
984      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
985      break;      break;
986    
987      case OP_CBRAPOS:      case OP_CBRAPOS:
988      case OP_SCBRAPOS:      case OP_SCBRAPOS:
989      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
990      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
991      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
994      case OP_COND:      case OP_COND:
# Line 722  while (cc < ccend) Line 996  while (cc < ccend)
996      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
997      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
998        {        {
999        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1000        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1001        }        }
1002      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1003        break;
1004    
1005        case OP_BRA:
1006        bracketlen = 1 + LINK_SIZE;
1007        break;
1008    
1009        case OP_CBRA:
1010        case OP_SCBRA:
1011        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1012        break;
1013    
1014        CASE_ITERATOR_PRIVATE_DATA_1
1015        space = 1;
1016        size = -2;
1017        break;
1018    
1019        CASE_ITERATOR_PRIVATE_DATA_2A
1020        space = 2;
1021        size = -2;
1022        break;
1023    
1024        CASE_ITERATOR_PRIVATE_DATA_2B
1025        space = 2;
1026        size = -(2 + IMM2_SIZE);
1027        break;
1028    
1029        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1030        space = 1;
1031        size = 1;
1032        break;
1033    
1034        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1035        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1036          space = 2;
1037        size = 1;
1038        break;
1039    
1040        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1041        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1042          space = 2;
1043        size = 1 + IMM2_SIZE;
1044        break;
1045    
1046        case OP_CLASS:
1047        case OP_NCLASS:
1048        size += 1 + 32 / sizeof(pcre_uchar);
1049        space = get_class_iterator_size(cc + size);
1050        break;
1051    
1052    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1053        case OP_XCLASS:
1054        size = GET(cc, 1);
1055        space = get_class_iterator_size(cc + size);
1056      break;      break;
1057    #endif
1058    
1059      default:      default:
1060      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1061      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1062      break;      break;
1063      }      }
1064    
1065      if (space > 0 && cc >= end)
1066        {
1067        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1068        private_data_ptr += sizeof(sljit_w) * space;
1069        }
1070    
1071      if (size != 0)
1072        {
1073        if (size < 0)
1074          {
1075          cc += -size;
1076    #ifdef SUPPORT_UTF
1077          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1078    #endif
1079          }
1080        else
1081          cc += size;
1082        }
1083    
1084      if (bracketlen > 0)
1085        {
1086        if (cc >= end)
1087          {
1088          end = bracketend(cc);
1089          if (end[-1 - LINK_SIZE] == OP_KET)
1090            end = NULL;
1091          }
1092        cc += bracketlen;
1093        }
1094    }    }
1095  }  }
1096    
# Line 742  static int get_framesize(compiler_common Line 1100  static int get_framesize(compiler_common
1100  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1101  int length = 0;  int length = 0;
1102  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1103  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1104    BOOL setmark_found = recursive;
1105    
1106  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1107    {    {
# Line 756  while (cc < ccend) Line 1115  while (cc < ccend)
1115    switch(*cc)    switch(*cc)
1116      {      {
1117      case OP_SET_SOM:      case OP_SET_SOM:
1118      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1119      if (!setsom_found)      if (!setsom_found)
1120        {        {
1121        length += 2;        length += 2;
1122        setsom_found = TRUE;        setsom_found = TRUE;
1123        }        }
1124      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1125        break;
1126    
1127        case OP_MARK:
1128        SLJIT_ASSERT(common->mark_ptr != 0);
1129        if (!setmark_found)
1130          {
1131          length += 2;
1132          setmark_found = TRUE;
1133          }
1134        cc += 1 + 2 + cc[1];
1135        break;
1136    
1137        case OP_RECURSE:
1138        if (common->has_set_som && !setsom_found)
1139          {
1140          length += 2;
1141          setsom_found = TRUE;
1142          }
1143        if (common->mark_ptr != 0 && !setmark_found)
1144          {
1145          length += 2;
1146          setmark_found = TRUE;
1147          }
1148        cc += 1 + LINK_SIZE;
1149      break;      break;
1150    
1151      case OP_CBRA:      case OP_CBRA:
# Line 792  static void init_frame(compiler_common * Line 1175  static void init_frame(compiler_common *
1175  {  {
1176  DEFINE_COMPILER;  DEFINE_COMPILER;
1177  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1178  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1179    BOOL setmark_found = recursive;
1180  int offset;  int offset;
1181    
1182  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1183    SLJIT_UNUSED_ARG(stacktop);
1184  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1185    
1186  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 806  while (cc < ccend) Line 1191  while (cc < ccend)
1191    switch(*cc)    switch(*cc)
1192      {      {
1193      case OP_SET_SOM:      case OP_SET_SOM:
1194      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1195      if (!setsom_found)      if (!setsom_found)
1196        {        {
1197        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 816  while (cc < ccend) Line 1201  while (cc < ccend)
1201        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1202        setsom_found = TRUE;        setsom_found = TRUE;
1203        }        }
1204      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1205        break;
1206    
1207        case OP_MARK:
1208        SLJIT_ASSERT(common->mark_ptr != 0);
1209        if (!setmark_found)
1210          {
1211          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1212          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1213          stackpos += (int)sizeof(sljit_w);
1214          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1215          stackpos += (int)sizeof(sljit_w);
1216          setmark_found = TRUE;
1217          }
1218        cc += 1 + 2 + cc[1];
1219        break;
1220    
1221        case OP_RECURSE:
1222        if (common->has_set_som && !setsom_found)
1223          {
1224          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1225          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1226          stackpos += (int)sizeof(sljit_w);
1227          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1228          stackpos += (int)sizeof(sljit_w);
1229          setsom_found = TRUE;
1230          }
1231        if (common->mark_ptr != 0 && !setmark_found)
1232          {
1233          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1234          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1235          stackpos += (int)sizeof(sljit_w);
1236          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1237          stackpos += (int)sizeof(sljit_w);
1238          setmark_found = TRUE;
1239          }
1240        cc += 1 + LINK_SIZE;
1241      break;      break;
1242    
1243      case OP_CBRA:      case OP_CBRA:
# Line 846  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1267  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1267  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1268  }  }
1269    
1270  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)
1271  {  {
1272  int localsize = 2;  int private_data_length = 2;
1273    int size;
1274  pcre_uchar *alternative;  pcre_uchar *alternative;
1275  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1276  while (cc < ccend)  while (cc < ccend)
1277    {    {
1278      size = 0;
1279    switch(*cc)    switch(*cc)
1280      {      {
1281      case OP_ASSERT:      case OP_ASSERT:
# Line 865  while (cc < ccend) Line 1288  while (cc < ccend)
1288      case OP_SBRA:      case OP_SBRA:
1289      case OP_SBRAPOS:      case OP_SBRAPOS:
1290      case OP_SCOND:      case OP_SCOND:
1291      localsize++;      private_data_length++;
1292      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1293      break;      break;
1294    
1295      case OP_CBRA:      case OP_CBRA:
1296      case OP_SCBRA:      case OP_SCBRA:
1297      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1298          private_data_length++;
1299      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1300      break;      break;
1301    
1302      case OP_CBRAPOS:      case OP_CBRAPOS:
1303      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1304      localsize += 2;      private_data_length += 2;
1305      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1306      break;      break;
1307    
# Line 885  while (cc < ccend) Line 1309  while (cc < ccend)
1309      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1310      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1311      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1312        localsize++;        private_data_length++;
1313      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1314      break;      break;
1315    
1316        CASE_ITERATOR_PRIVATE_DATA_1
1317        if (PRIVATE_DATA(cc))
1318          private_data_length++;
1319        cc += 2;
1320    #ifdef SUPPORT_UTF
1321        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1322    #endif
1323        break;
1324    
1325        CASE_ITERATOR_PRIVATE_DATA_2A
1326        if (PRIVATE_DATA(cc))
1327          private_data_length += 2;
1328        cc += 2;
1329    #ifdef SUPPORT_UTF
1330        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1331    #endif
1332        break;
1333    
1334        CASE_ITERATOR_PRIVATE_DATA_2B
1335        if (PRIVATE_DATA(cc))
1336          private_data_length += 2;
1337        cc += 2 + IMM2_SIZE;
1338    #ifdef SUPPORT_UTF
1339        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1340    #endif
1341        break;
1342    
1343        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1344        if (PRIVATE_DATA(cc))
1345          private_data_length++;
1346        cc += 1;
1347        break;
1348    
1349        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1350        if (PRIVATE_DATA(cc))
1351          private_data_length += 2;
1352        cc += 1;
1353        break;
1354    
1355        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1356        if (PRIVATE_DATA(cc))
1357          private_data_length += 2;
1358        cc += 1 + IMM2_SIZE;
1359        break;
1360    
1361        case OP_CLASS:
1362        case OP_NCLASS:
1363    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1364        case OP_XCLASS:
1365        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1366    #else
1367        size = 1 + 32 / (int)sizeof(pcre_uchar);
1368    #endif
1369        if (PRIVATE_DATA(cc))
1370          private_data_length += get_class_iterator_size(cc + size);
1371        cc += size;
1372        break;
1373    
1374      default:      default:
1375      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1376      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 896  while (cc < ccend) Line 1378  while (cc < ccend)
1378      }      }
1379    }    }
1380  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1381  return localsize;  return private_data_length;
1382  }  }
1383    
1384  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,
1385    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1386  {  {
1387  DEFINE_COMPILER;  DEFINE_COMPILER;
1388  int srcw[2];  int srcw[2];
1389  int count;  int count, size;
1390  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1391  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1392  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 943  while (status != end) Line 1425  while (status != end)
1425    switch(status)    switch(status)
1426      {      {
1427      case start:      case start:
1428      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1429      count = 1;      count = 1;
1430      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1431      status = loop;      status = loop;
1432      break;      break;
1433    
# Line 969  while (status != end) Line 1451  while (status != end)
1451        case OP_SBRAPOS:        case OP_SBRAPOS:
1452        case OP_SCOND:        case OP_SCOND:
1453        count = 1;        count = 1;
1454        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1455        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1456        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1457        break;        break;
1458    
1459        case OP_CBRA:        case OP_CBRA:
1460        case OP_SCBRA:        case OP_SCBRA:
1461        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1462        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1463            count = 1;
1464            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1465            }
1466        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1467        break;        break;
1468    
1469        case OP_CBRAPOS:        case OP_CBRAPOS:
1470        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1471        count = 2;        count = 2;
1472          srcw[0] = PRIVATE_DATA(cc);
1473        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1474        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1475        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1476        break;        break;
1477    
# Line 996  while (status != end) Line 1481  while (status != end)
1481        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1482          {          {
1483          count = 1;          count = 1;
1484          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1485          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1486          }          }
1487        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1488        break;        break;
1489    
1490          CASE_ITERATOR_PRIVATE_DATA_1
1491          if (PRIVATE_DATA(cc))
1492            {
1493            count = 1;
1494            srcw[0] = PRIVATE_DATA(cc);
1495            }
1496          cc += 2;
1497    #ifdef SUPPORT_UTF
1498          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1499    #endif
1500          break;
1501    
1502          CASE_ITERATOR_PRIVATE_DATA_2A
1503          if (PRIVATE_DATA(cc))
1504            {
1505            count = 2;
1506            srcw[0] = PRIVATE_DATA(cc);
1507            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1508            }
1509          cc += 2;
1510    #ifdef SUPPORT_UTF
1511          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1512    #endif
1513          break;
1514    
1515          CASE_ITERATOR_PRIVATE_DATA_2B
1516          if (PRIVATE_DATA(cc))
1517            {
1518            count = 2;
1519            srcw[0] = PRIVATE_DATA(cc);
1520            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1521            }
1522          cc += 2 + IMM2_SIZE;
1523    #ifdef SUPPORT_UTF
1524          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1525    #endif
1526          break;
1527    
1528          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1529          if (PRIVATE_DATA(cc))
1530            {
1531            count = 1;
1532            srcw[0] = PRIVATE_DATA(cc);
1533            }
1534          cc += 1;
1535          break;
1536    
1537          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1538          if (PRIVATE_DATA(cc))
1539            {
1540            count = 2;
1541            srcw[0] = PRIVATE_DATA(cc);
1542            srcw[1] = srcw[0] + sizeof(sljit_w);
1543            }
1544          cc += 1;
1545          break;
1546    
1547          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1548          if (PRIVATE_DATA(cc))
1549            {
1550            count = 2;
1551            srcw[0] = PRIVATE_DATA(cc);
1552            srcw[1] = srcw[0] + sizeof(sljit_w);
1553            }
1554          cc += 1 + IMM2_SIZE;
1555          break;
1556    
1557          case OP_CLASS:
1558          case OP_NCLASS:
1559    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1560          case OP_XCLASS:
1561          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1562    #else
1563          size = 1 + 32 / (int)sizeof(pcre_uchar);
1564    #endif
1565          if (PRIVATE_DATA(cc))
1566            switch(get_class_iterator_size(cc + size))
1567              {
1568              case 1:
1569              count = 1;
1570              srcw[0] = PRIVATE_DATA(cc);
1571              break;
1572    
1573              case 2:
1574              count = 2;
1575              srcw[0] = PRIVATE_DATA(cc);
1576              srcw[1] = srcw[0] + sizeof(sljit_w);
1577              break;
1578    
1579              default:
1580              SLJIT_ASSERT_STOP();
1581              break;
1582              }
1583          cc += size;
1584          break;
1585    
1586        default:        default:
1587        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1588        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1104  if (save) Line 1685  if (save)
1685  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1686  }  }
1687    
1688    #undef CASE_ITERATOR_PRIVATE_DATA_1
1689    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1690    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1691    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1692    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1693    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1694    
1695  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1696  {  {
1697  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1114  static SLJIT_INLINE void set_jumps(jump_ Line 1702  static SLJIT_INLINE void set_jumps(jump_
1702  while (list)  while (list)
1703    {    {
1704    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1705    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1706    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1707    list = list->next;    list = list->next;
1708    }    }
# Line 1141  if (list_item) Line 1729  if (list_item)
1729    list_item->type = type;    list_item->type = type;
1730    list_item->data = data;    list_item->data = data;
1731    list_item->start = start;    list_item->start = start;
1732    list_item->leave = LABEL();    list_item->quit = LABEL();
1733    list_item->next = common->stubs;    list_item->next = common->stubs;
1734    common->stubs = list_item;    common->stubs = list_item;
1735    }    }
# Line 1161  while (list_item) Line 1749  while (list_item)
1749      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1750      break;      break;
1751      }      }
1752    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1753    list_item = list_item->next;    list_item = list_item->next;
1754    }    }
1755  common->stubs = NULL;  common->stubs = NULL;
# Line 1212  if (length < 8) Line 1800  if (length < 8)
1800    }    }
1801  else  else
1802    {    {
1803    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1804    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1805    loop = LABEL();    loop = LABEL();
1806    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_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1232  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI Line 1820  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI
1820  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1821    
1822  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1823    if (common->mark_ptr != 0)
1824      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1825  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1826    if (common->mark_ptr != 0)
1827      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1828  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1829  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1830  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1831  /* Unlikely, but possible */  /* Unlikely, but possible */
1832  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1833  loop = LABEL();  loop = LABEL();
# Line 1253  JUMPHERE(earlyexit); Line 1845  JUMPHERE(earlyexit);
1845  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1846  if (topbracket > 1)  if (topbracket > 1)
1847    {    {
1848    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1849    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1850    
1851    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
# Line 1267  else Line 1859  else
1859    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1860  }  }
1861    
1862    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1863    {
1864    DEFINE_COMPILER;
1865    
1866    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1867    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1868    
1869    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1870    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1871    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1872    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1873    
1874    /* Store match begin and end. */
1875    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1876    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1877    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);
1878    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1879    #ifdef COMPILE_PCRE16
1880    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1881    #endif
1882    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1883    
1884    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1885    #ifdef COMPILE_PCRE16
1886    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1887    #endif
1888    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1889    
1890    JUMPTO(SLJIT_JUMP, quit);
1891    }
1892    
1893    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1894    {
1895    /* May destroy TMP1. */
1896    DEFINE_COMPILER;
1897    struct sljit_jump *jump;
1898    
1899    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1900      {
1901      /* The value of -1 must be kept for start_used_ptr! */
1902      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1903      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1904      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1905      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1906      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1907      JUMPHERE(jump);
1908      }
1909    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1910      {
1911      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1912      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1913      JUMPHERE(jump);
1914      }
1915    }
1916    
1917  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1918  {  {
1919  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1388  return (bit < 256) ? ((0 << 8) | bit) : Line 2035  return (bit < 256) ? ((0 << 8) | bit) :
2035  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2036  }  }
2037    
2038  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
2039  {  {
2040    /* Checks whether a partial matching is occured. Does not modify registers. */
2041  DEFINE_COMPILER;  DEFINE_COMPILER;
2042  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump = NULL;
2043    
2044    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2045    
2046    if (common->mode == JIT_COMPILE)
2047      return;
2048    
2049    if (!force)
2050      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2051    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2052      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2053    
2054    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2055      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2056    else
2057      {
2058      if (common->partialmatchlabel != NULL)
2059        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2060      else
2061        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2062      }
2063    
2064    if (jump != NULL)
2065      JUMPHERE(jump);
2066    }
2067    
2068    static struct sljit_jump *check_str_end(compiler_common *common)
2069    {
2070    /* Does not affect registers. Usually used in a tight spot. */
2071    DEFINE_COMPILER;
2072    struct sljit_jump *jump;
2073    struct sljit_jump *nohit;
2074    struct sljit_jump *return_value;
2075    
2076    if (common->mode == JIT_COMPILE)
2077      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2078    
2079    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2080    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2081      {
2082      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2083      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2084      JUMPHERE(nohit);
2085      return_value = JUMP(SLJIT_JUMP);
2086      }
2087    else
2088      {
2089      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2090      if (common->partialmatchlabel != NULL)
2091        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2092      else
2093        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2094      }
2095    JUMPHERE(jump);
2096    return return_value;
2097    }
2098    
2099    static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2100    {
2101    DEFINE_COMPILER;
2102    struct sljit_jump *jump;
2103    
2104    if (common->mode == JIT_COMPILE)
2105      {
2106      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2107      return;
2108      }
2109    
2110    /* Partial matching mode. */
2111    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2112    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2113    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2114      {
2115      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2116      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2117      }
2118    else
2119      {
2120      if (common->partialmatchlabel != NULL)
2121        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2122      else
2123        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2124      }
2125    JUMPHERE(jump);
2126  }  }
2127    
2128  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1532  if (common->utf) Line 2263  if (common->utf)
2263  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));
2264  }  }
2265    
2266  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
2267  {  {
2268  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2269  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1540  DEFINE_COMPILER; Line 2271  DEFINE_COMPILER;
2271  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2272    {    {
2273    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2274    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2275    }    }
2276  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2277    {    {
# Line 1548  else if (nltype == NLTYPE_ANYCRLF) Line 2279  else if (nltype == NLTYPE_ANYCRLF)
2279    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2280    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);
2281    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2282    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2283    }    }
2284  else  else
2285    {    {
2286    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2287    add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2288    }    }
2289  }  }
2290    
# Line 1567  of the character (>= 0xc0). Return char Line 2298  of the character (>= 0xc0). Return char
2298  DEFINE_COMPILER;  DEFINE_COMPILER;
2299  struct sljit_jump *jump;  struct sljit_jump *jump;
2300    
2301  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2302  /* Searching for the first zero. */  /* Searching for the first zero. */
2303  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2304  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1626  DEFINE_COMPILER; Line 2357  DEFINE_COMPILER;
2357  struct sljit_jump *jump;  struct sljit_jump *jump;
2358  struct sljit_jump *compare;  struct sljit_jump *compare;
2359    
2360  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2361    
2362  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
2363  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1663  of the character (>= 0xd800). Return cha Line 2394  of the character (>= 0xd800). Return cha
2394  DEFINE_COMPILER;  DEFINE_COMPILER;
2395  struct sljit_jump *jump;  struct sljit_jump *jump;
2396    
2397  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2398  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2399  /* Do nothing, only return. */  /* Do nothing, only return. */
2400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1700  DEFINE_COMPILER; Line 2431  DEFINE_COMPILER;
2431    
2432  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2433    
2434  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2435  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2436  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
2437  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
# Line 1736  if (!(hascrorlf || firstline) && (common Line 2467  if (!(hascrorlf || firstline) && (common
2467  if (firstline)  if (firstline)
2468    {    {
2469    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2470    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2471    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2472    
2473    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2474      {      {
# Line 1748  if (firstline) Line 2479  if (firstline)
2479      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2480      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);
2481      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);
2482      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      JUMPHERE(end);
2483        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2484      }      }
2485    else    else
2486      {      {
2487      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2488      mainloop = LABEL();      mainloop = LABEL();
2489      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2490      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2491      read_char(common);      read_char(common);
2492      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2493      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2494      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2495        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2496      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2497      }      }
2498    
2499    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2500    }    }
2501    
2502  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1831  if (newlinecheck) Line 2563  if (newlinecheck)
2563  return mainloop;  return mainloop;
2564  }  }
2565    
2566    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2567    {
2568    DEFINE_COMPILER;
2569    struct sljit_label *start;
2570    struct sljit_jump *quit;
2571    struct sljit_jump *found;
2572    pcre_int32 chars[4];
2573    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2574    int location = 0;
2575    pcre_int32 len, c, bit, caseless;
2576    BOOL must_end;
2577    
2578    #ifdef COMPILE_PCRE8
2579    union {
2580        sljit_uh ascombined;
2581        sljit_ub asuchars[2];
2582    } pair;
2583    #else
2584    union {
2585        sljit_ui ascombined;
2586        sljit_uh asuchars[2];
2587    } pair;
2588    #endif
2589    
2590    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2591      return FALSE;
2592    
2593    while (TRUE)
2594      {
2595      caseless = 0;
2596      must_end = TRUE;
2597      switch(*cc)
2598        {
2599        case OP_CHAR:
2600        must_end = FALSE;
2601        cc++;
2602        break;
2603    
2604        case OP_CHARI:
2605        caseless = 1;
2606        must_end = FALSE;
2607        cc++;
2608        break;
2609    
2610        case OP_SOD:
2611        case OP_SOM:
2612        case OP_SET_SOM:
2613        case OP_NOT_WORD_BOUNDARY:
2614        case OP_WORD_BOUNDARY:
2615        case OP_EODN:
2616        case OP_EOD:
2617        case OP_CIRC:
2618        case OP_CIRCM:
2619        case OP_DOLL:
2620        case OP_DOLLM:
2621        /* Zero width assertions. */
2622        cc++;
2623        continue;
2624    
2625        case OP_PLUS:
2626        case OP_MINPLUS:
2627        case OP_POSPLUS:
2628        cc++;
2629        break;
2630    
2631        case OP_EXACT:
2632        cc += 1 + IMM2_SIZE;
2633        break;
2634    
2635        case OP_PLUSI:
2636        case OP_MINPLUSI:
2637        case OP_POSPLUSI:
2638        caseless = 1;
2639        cc++;
2640        break;
2641    
2642        case OP_EXACTI:
2643        caseless = 1;
2644        cc += 1 + IMM2_SIZE;
2645        break;
2646    
2647        default:
2648        return FALSE;
2649        }
2650    
2651      len = 1;
2652    #ifdef SUPPORT_UTF
2653      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2654    #endif
2655    
2656      if (caseless && char_has_othercase(common, cc))
2657        {
2658        caseless = char_get_othercase_bit(common, cc);
2659        if (caseless == 0)
2660          return FALSE;
2661    #ifdef COMPILE_PCRE8
2662        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2663    #else
2664        if ((caseless & 0x100) != 0)
2665          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2666        else
2667          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2668    #endif
2669        }
2670      else
2671        caseless = 0;
2672    
2673      while (len > 0 && location < 2 * 2)
2674        {
2675        c = *cc;
2676        bit = 0;
2677        if (len == (caseless & 0xff))
2678          {
2679          bit = caseless >> 8;
2680          c |= bit;
2681          }
2682    
2683        chars[location] = c;
2684        chars[location + 1] = bit;
2685    
2686        len--;
2687        location += 2;
2688        cc++;
2689        }
2690    
2691      if (location == 2 * 2)
2692        break;
2693      else if (must_end)
2694        return FALSE;
2695      }
2696    
2697    if (firstline)
2698      {
2699      SLJIT_ASSERT(common->first_line_end != 0);
2700      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2701      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2702      }
2703    else
2704      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    
2706    start = LABEL();
2707    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2708    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2709    #ifdef COMPILE_PCRE8
2710    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2711    #else /* COMPILE_PCRE8 */
2712    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2713    #endif
2714    
2715    #else /* SLJIT_UNALIGNED */
2716    
2717    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2718    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2719    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2720    #else /* SLJIT_BIG_ENDIAN */
2721    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2722    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2723    #endif /* SLJIT_BIG_ENDIAN */
2724    
2725    #ifdef COMPILE_PCRE8
2726    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2727    #else /* COMPILE_PCRE8 */
2728    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2729    #endif
2730    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2731    
2732    #endif
2733    
2734    if (chars[1] != 0 || chars[3] != 0)
2735      {
2736      pair.asuchars[0] = chars[1];
2737      pair.asuchars[1] = chars[3];
2738      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2739      }
2740    
2741    pair.asuchars[0] = chars[0];
2742    pair.asuchars[1] = chars[2];
2743    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2744    
2745    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2746    JUMPTO(SLJIT_JUMP, start);
2747    JUMPHERE(found);
2748    JUMPHERE(quit);
2749    
2750    if (firstline)
2751      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2752    else
2753      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2754    return TRUE;
2755    }
2756    
2757  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)
2758  {  {
2759  DEFINE_COMPILER;  DEFINE_COMPILER;
2760  struct sljit_label *start;  struct sljit_label *start;
2761  struct sljit_jump *leave;  struct sljit_jump *quit;
2762  struct sljit_jump *found;  struct sljit_jump *found;
2763  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2764    
2765  if (firstline)  if (firstline)
2766    {    {
2767    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2768    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2769      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2770    }    }
2771    
2772  start = LABEL();  start = LABEL();
2773  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2774  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2775    
2776  oc = first_char;  oc = first_char;
# Line 1879  else Line 2803  else
2803    }    }
2804    
2805  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  
2806  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2807  JUMPHERE(found);  JUMPHERE(found);
2808  JUMPHERE(leave);  JUMPHERE(quit);
2809    
2810  if (firstline)  if (firstline)
2811    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2812  }  }
2813    
2814  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 1912  DEFINE_COMPILER; Line 2817  DEFINE_COMPILER;
2817  struct sljit_label *loop;  struct sljit_label *loop;
2818  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2819  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2820  struct sljit_jump *leave;  struct sljit_jump *quit;
2821  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2822  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2823  jump_list *newline = NULL;  jump_list *newline = NULL;
2824    
2825  if (firstline)  if (firstline)
2826    {    {
2827    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2828    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2829      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2830    }    }
2831    
2832  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1941  if (common->nltype == NLTYPE_FIXED && co Line 2847  if (common->nltype == NLTYPE_FIXED && co
2847    
2848    loop = LABEL();    loop = LABEL();
2849    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));
2850    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2851    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2852    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2853    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);
2854    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);
2855    
2856    JUMPHERE(leave);    JUMPHERE(quit);
2857    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2858    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2859    
# Line 1971  set_jumps(newline, loop); Line 2877  set_jumps(newline, loop);
2877    
2878  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2879    {    {
2880    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2881    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2882    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2883    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 1982  if (common->nltype == NLTYPE_ANY || comm Line 2888  if (common->nltype == NLTYPE_ANY || comm
2888  #endif  #endif
2889    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2890    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2891    JUMPHERE(leave);    JUMPHERE(quit);
2892    }    }
2893  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2894  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2895    
2896  if (firstline)  if (firstline)
2897    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2898  }  }
2899    
2900  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)
2901  {  {
2902  DEFINE_COMPILER;  DEFINE_COMPILER;
2903  struct sljit_label *start;  struct sljit_label *start;
2904  struct sljit_jump *leave;  struct sljit_jump *quit;
2905  struct sljit_jump *found;  struct sljit_jump *found;
2906  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2907  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2003  struct sljit_jump *jump; Line 2909  struct sljit_jump *jump;
2909    
2910  if (firstline)  if (firstline)
2911    {    {
2912    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2913    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2914      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2915    }    }
2916    
2917  start = LABEL();  start = LABEL();
2918  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2919  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2920  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2921  if (common->utf)  if (common->utf)
# Line 2052  if (common->utf) Line 2959  if (common->utf)
2959  #endif  #endif
2960  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2961  JUMPHERE(found);  JUMPHERE(found);
2962  JUMPHERE(leave);  JUMPHERE(quit);
2963    
2964  if (firstline)  if (firstline)
2965    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2966  }  }
2967    
2968  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 2069  struct sljit_jump *foundoc = NULL; Line 2976  struct sljit_jump *foundoc = NULL;
2976  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2977  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2978    
2979  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2980    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2981  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2982  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2983  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2114  JUMPTO(SLJIT_JUMP, loop); Line 3022  JUMPTO(SLJIT_JUMP, loop);
3022  JUMPHERE(found);  JUMPHERE(found);
3023  if (foundoc)  if (foundoc)
3024    JUMPHERE(foundoc);    JUMPHERE(foundoc);
3025  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
3026  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
3027  JUMPHERE(toolong);  JUMPHERE(toolong);
3028  return notfound;  return notfound;
# Line 2126  DEFINE_COMPILER; Line 3034  DEFINE_COMPILER;
3034  struct sljit_jump *jump;  struct sljit_jump *jump;
3035  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3036    
3037  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3038  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3039    GET_LOCAL_BASE(TMP3, 0, 0);
3040    
3041  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3042  mainloop = LABEL();  mainloop = LABEL();
3043  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3044  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);
3045  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3046  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_w));
3047  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
3048  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_w));
# Line 2153  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 3062  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
3062  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3063    
3064  JUMPHERE(jump);  JUMPHERE(jump);
3065    if (common->mark_ptr != 0)
3066      {
3067      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3068      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3069      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3070      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3071      JUMPTO(SLJIT_JUMP, mainloop);
3072    
3073      JUMPHERE(jump);
3074      }
3075    
3076  /* Unknown command. */  /* Unknown command. */
3077  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_w));
3078  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2161  JUMPTO(SLJIT_JUMP, mainloop); Line 3081  JUMPTO(SLJIT_JUMP, mainloop);
3081  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3082  {  {
3083  DEFINE_COMPILER;  DEFINE_COMPILER;
3084  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3085  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3086  struct sljit_jump *jump;  struct sljit_jump *jump;
3087  #endif  #endif
3088    
3089  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3090    
3091  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3092  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3093  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3094  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3095  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3096  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3097  skip_char_back(common);  skip_char_back(common);
3098    check_start_used_ptr(common);
3099  read_char(common);  read_char(common);
3100    
3101  /* Testing char type. */  /* Testing char type. */
# Line 2215  else Line 3136  else
3136      JUMPHERE(jump);      JUMPHERE(jump);
3137  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3138    }    }
3139  JUMPHERE(beginend);  JUMPHERE(skipread);
3140    
3141  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3142  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3143  peek_char(common);  peek_char(common);
3144    
3145  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2259  else Line 3180  else
3180      JUMPHERE(jump);      JUMPHERE(jump);
3181  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3182    }    }
3183  JUMPHERE(beginend);  JUMPHERE(skipread);
3184    
3185  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3186  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3187  }  }
3188    
3189    /*
3190      range format:
3191    
3192      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3193      ranges[1] = first bit (0 or 1)
3194      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3195    */
3196    
3197    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3198    {
3199    DEFINE_COMPILER;
3200    struct sljit_jump *jump;
3201    
3202    if (ranges[0] < 0)
3203      return FALSE;
3204    
3205    switch(ranges[0])
3206      {
3207      case 1:
3208      if (readch)
3209        read_char(common);
3210      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3211      return TRUE;
3212    
3213      case 2:
3214      if (readch)
3215        read_char(common);
3216      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3217      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3218      return TRUE;
3219    
3220      case 4:
3221      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3222        {
3223        if (readch)
3224          read_char(common);
3225        if (ranges[1] != 0)
3226          {
3227          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3228          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3229          }
3230        else
3231          {
3232          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3233          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3234          JUMPHERE(jump);
3235          }
3236        return TRUE;
3237        }
3238      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3239        {
3240        if (readch)
3241          read_char(common);
3242        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3243        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3244        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3245        return TRUE;
3246        }
3247      return FALSE;
3248    
3249      default:
3250      return FALSE;
3251      }
3252    }
3253    
3254    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3255    {
3256    int i, bit, length;
3257    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3258    
3259    bit = ctypes[0] & flag;
3260    ranges[0] = -1;
3261    ranges[1] = bit != 0 ? 1 : 0;
3262    length = 0;
3263    
3264    for (i = 1; i < 256; i++)
3265      if ((ctypes[i] & flag) != bit)
3266        {
3267        if (length >= MAX_RANGE_SIZE)
3268          return;
3269        ranges[2 + length] = i;
3270        length++;
3271        bit ^= flag;
3272        }
3273    
3274    if (bit != 0)
3275      {
3276      if (length >= MAX_RANGE_SIZE)
3277        return;
3278      ranges[2 + length] = 256;
3279      length++;
3280      }
3281    ranges[0] = length;
3282    }
3283    
3284    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3285    {
3286    int ranges[2 + MAX_RANGE_SIZE];
3287    pcre_uint8 bit, cbit, all;
3288    int i, byte, length = 0;
3289    
3290    bit = bits[0] & 0x1;
3291    ranges[1] = bit;
3292    /* Can be 0 or 255. */
3293    all = -bit;
3294    
3295    for (i = 0; i < 256; )
3296      {
3297      byte = i >> 3;
3298      if ((i & 0x7) == 0 && bits[byte] == all)
3299        i += 8;
3300      else
3301        {
3302        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3303        if (cbit != bit)
3304          {
3305          if (length >= MAX_RANGE_SIZE)
3306            return FALSE;
3307          ranges[2 + length] = i;
3308          length++;
3309          bit = cbit;
3310          all = -cbit;
3311          }
3312        i++;
3313        }
3314      }
3315    
3316    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3317      {
3318      if (length >= MAX_RANGE_SIZE)
3319        return FALSE;
3320      ranges[2 + length] = 256;
3321      length++;
3322      }
3323    ranges[0] = length;
3324    
3325    return check_ranges(common, ranges, backtracks, FALSE);
3326    }
3327    
3328  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3329  {  {
3330  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3331  DEFINE_COMPILER;  DEFINE_COMPILER;
3332    
3333  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3334    
3335  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3336  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);
# Line 2297  static void check_hspace(compiler_common Line 3357  static void check_hspace(compiler_common
3357  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3358  DEFINE_COMPILER;  DEFINE_COMPILER;
3359    
3360  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3361    
3362  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3363  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
# Line 2336  static void check_vspace(compiler_common Line 3396  static void check_vspace(compiler_common
3396  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3397  DEFINE_COMPILER;  DEFINE_COMPILER;
3398    
3399  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3400    
3401  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3402  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);
# Line 2368  DEFINE_COMPILER; Line 3428  DEFINE_COMPILER;
3428  struct sljit_jump *jump;  struct sljit_jump *jump;
3429  struct sljit_label *label;  struct sljit_label *label;
3430    
3431  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3432  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3433  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3434  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2397  DEFINE_COMPILER; Line 3457  DEFINE_COMPILER;
3457  struct sljit_jump *jump;  struct sljit_jump *jump;
3458  struct sljit_label *label;  struct sljit_label *label;
3459    
3460  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3461  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3462    
3463  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2444  static const pcre_uchar *SLJIT_CALL do_u Line 3504  static const pcre_uchar *SLJIT_CALL do_u
3504  {  {
3505  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3506  int c1, c2;  int c1, c2;
3507  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3508  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3509    
3510  while (src1 < end1)  while (src1 < end1)
3511    {    {
3512    if (src2 >= end2)    if (src2 >= end2)
3513      return 0;      return (pcre_uchar*)1;
3514    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3515    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3516    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
3517    }    }
3518  return src2;  return src2;
3519  }  }
# Line 2461  return src2; Line 3521  return src2;
3521  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3522    
3523  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
3524      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3525  {  {
3526  DEFINE_COMPILER;  DEFINE_COMPILER;
3527  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2562  do Line 3622  do
3622        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3623        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3624          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
3625        add_jump(compiler, fallbacks, 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        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3629        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3630          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);
3631        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
3632        break;        break;
3633    
3634  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3635        case 1:        case 1:
3636        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3637          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
3638        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
3639        break;        break;
3640  #endif  #endif
3641    
# Line 2601  do Line 3661  do
3661    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3662      {      {
3663      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3664      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
3665      }      }
3666    else    else
3667      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
3668    
3669  #endif  #endif
3670    
# Line 2640  return cc; Line 3700  return cc;
3700      } \      } \
3701    charoffset = (value);    charoffset = (value);
3702    
3703  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3704  {  {
3705  DEFINE_COMPILER;  DEFINE_COMPILER;
3706  jump_list *found = NULL;  jump_list *found = NULL;
3707  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3708  unsigned int c;  unsigned int c;
3709  int compares;  int compares;
3710  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2658  unsigned int typeoffset; Line 3718  unsigned int typeoffset;
3718  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3719  unsigned int charoffset;  unsigned int charoffset;
3720    
3721  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3722  check_input_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3723    detect_partial_match(common, backtracks);
3724  read_char(common);  read_char(common);
3725    
3726  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2672  if ((*cc++ & XCL_MAP) != 0) Line 3733  if ((*cc++ & XCL_MAP) != 0)
3733      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3734  #endif  #endif
3735    
3736    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3737    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3738    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3739    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3740    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3741    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3742        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3743        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3744        }
3745    
3746  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3747    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2810  typeoffset = 0; Line 3874  typeoffset = 0;
3874  while (*cc != XCL_END)  while (*cc != XCL_END)
3875    {    {
3876    compares--;    compares--;
3877    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3878    jump = NULL;    jump = NULL;
3879    
3880    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 2892  while (*cc != XCL_END) Line 3956  while (*cc != XCL_END)
3956      switch(*cc)      switch(*cc)
3957        {        {
3958        case PT_ANY:        case PT_ANY:
3959        if (list != fallbacks)        if (list != backtracks)
3960          {          {
3961          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
3962            continue;            continue;
# Line 2965  while (*cc != XCL_END) Line 4029  while (*cc != XCL_END)
4029  #endif  #endif
4030    
4031    if (jump != NULL)    if (jump != NULL)
4032      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
4033    }    }
4034    
4035  if (found != NULL)  if (found != NULL)
# Line 2977  if (found != NULL) Line 4041  if (found != NULL)
4041    
4042  #endif  #endif
4043    
4044  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
4045  {  {
4046  DEFINE_COMPILER;  DEFINE_COMPILER;
4047  int length;  int length;
# Line 2996  switch(type) Line 4060  switch(type)
4060    case OP_SOD:    case OP_SOD:
4061    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4062    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4063    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4064    return cc;    return cc;
4065    
4066    case OP_SOM:    case OP_SOM:
4067    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4068    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
4069    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4070    return cc;    return cc;
4071    
4072    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4073    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4074    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4075    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4076    return cc;    return cc;
4077    
4078    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4079    case OP_DIGIT:    case OP_DIGIT:
4080    check_input_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4081    read_char8_type(common);    if (common->digits[0] == -2)
4082    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4083    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4084      /* Flip the starting bit in the negative case. */
4085      if (type == OP_NOT_DIGIT)
4086        common->digits[1] ^= 1;
4087      if (!check_ranges(common, common->digits, backtracks, TRUE))
4088        {
4089        read_char8_type(common);
4090        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4091        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4092        }
4093      if (type == OP_NOT_DIGIT)
4094        common->digits[1] ^= 1;
4095    return cc;    return cc;
4096    
4097    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4098    case OP_WHITESPACE:    case OP_WHITESPACE:
4099    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4100    read_char8_type(common);    read_char8_type(common);
4101    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
4102    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4103    return cc;    return cc;
4104    
4105    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4106    case OP_WORDCHAR:    case OP_WORDCHAR:
4107    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4108    read_char8_type(common);    read_char8_type(common);
4109    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
4110    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4111    return cc;    return cc;
4112    
4113    case OP_ANY:    case OP_ANY:
4114    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4115    read_char(common);    read_char(common);
4116    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4117      {      {
4118      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4119      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4120          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4121        else
4122          jump[1] = check_str_end(common);
4123    
4124      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4125      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4126      JUMPHERE(jump[1]);      if (jump[1] != NULL)
4127          JUMPHERE(jump[1]);
4128      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4129      }      }
4130    else    else
4131      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4132    return cc;    return cc;
4133    
4134    case OP_ALLANY:    case OP_ALLANY:
4135    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4136  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4137    if (common->utf)    if (common->utf)
4138      {      {
# Line 3080  switch(type) Line 4160  switch(type)
4160    return cc;    return cc;
4161    
4162    case OP_ANYBYTE:    case OP_ANYBYTE:
4163    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4164    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));
4165    return cc;    return cc;
4166    
# Line 3093  switch(type) Line 4173  switch(type)
4173    propdata[2] = cc[0];    propdata[2] = cc[0];
4174    propdata[3] = cc[1];    propdata[3] = cc[1];
4175    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4176    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4177    return cc + 2;    return cc + 2;
4178  #endif  #endif
4179  #endif  #endif
4180    
4181    case OP_ANYNL:    case OP_ANYNL:
4182    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4183    read_char(common);    read_char(common);
4184    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
4185    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
4186      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4187        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4188      else
4189        jump[1] = check_str_end(common);
4190    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4191    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4192    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));
4193    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4194    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4195    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4196    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4197    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4198    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3116  switch(type) Line 4200  switch(type)
4200    
4201    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4202    case OP_HSPACE:    case OP_HSPACE:
4203    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4204    read_char(common);    read_char(common);
4205    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4206    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4207    return cc;    return cc;
4208    
4209    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4210    case OP_VSPACE:    case OP_VSPACE:
4211    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4212    read_char(common);    read_char(common);
4213    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4214    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4215    return cc;    return cc;
4216    
4217  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4218    case OP_EXTUNI:    case OP_EXTUNI:
4219    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4220    read_char(common);    read_char(common);
4221    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4222    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4223    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4224      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4225      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4226    
4227    label = LABEL();    label = LABEL();
4228    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);
4229    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4230    read_char(common);    read_char(common);
4231    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4232    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4233    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);
4234    
4235      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4236      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4237      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4238      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4239      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4240      JUMPTO(SLJIT_C_NOT_ZERO, label);
4241    
4242    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4243    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4244      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4245    
4246      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4247        {
4248        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4249        /* Since we successfully read a char above, partial matching must occure. */
4250        check_partial(common, TRUE);
4251        JUMPHERE(jump[0]);
4252        }
4253    return cc;    return cc;
4254  #endif  #endif
4255    
4256    case OP_EODN:    case OP_EODN:
4257      /* Requires rather complex checks. */
4258    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);
4259    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4260      {      {
4261      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4262      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4263      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
4264          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
4265        else
4266          {
4267          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4268          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4269          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4270          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4271          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
4272          add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4273          check_partial(common, TRUE);
4274          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4275          JUMPHERE(jump[1]);
4276          }
4277      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4278      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4279      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4280      }      }
4281    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4282      {      {
4283      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4284      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4285      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
4286      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
4287      }      }
4288    else    else
4289      {      {
# Line 3176  switch(type) Line 4292  switch(type)
4292      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4293      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4294      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4295      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4296      /* Equal. */      /* Equal. */
4297      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4298      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4299      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4300    
4301      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4302      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4303        {        {
4304        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4305        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
4306        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
4307        }        }
4308      else      else
4309        {        {
4310        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4311        read_char(common);        read_char(common);
4312        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
4313        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4314        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4315        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4316        }        }
4317      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
4318      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
4319      }      }
4320    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4321      check_partial(common, FALSE);
4322    return cc;    return cc;
4323    
4324    case OP_EOD:    case OP_EOD:
4325    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4326      check_partial(common, FALSE);
4327    return cc;    return cc;
4328    
4329    case OP_CIRC:    case OP_CIRC:
4330    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4331    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
4332    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
4333    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
4334    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4335    return cc;    return cc;
4336    
4337    case OP_CIRCM:    case OP_CIRCM:
# Line 3221  switch(type) Line 4339  switch(type)
4339    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
4340    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4341    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
4342    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4343    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4344    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4345    
4346    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4347    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4348      {      {
4349      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4350      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4351      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4352      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4353      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4354      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4355      }      }
4356    else    else
4357      {      {
4358      skip_char_back(common);      skip_char_back(common);
4359      read_char(common);      read_char(common);
4360      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4361      }      }
4362    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4363    return cc;    return cc;
# Line 3247  switch(type) Line 4365  switch(type)
4365    case OP_DOLL:    case OP_DOLL:
4366    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4367    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
4368    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4369    
4370    if (!common->endonly)    if (!common->endonly)
4371      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4372    else    else
4373      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      {
4374        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4375        check_partial(common, FALSE);
4376        }
4377    return cc;    return cc;
4378    
4379    case OP_DOLLM:    case OP_DOLLM:
4380    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4381    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4382    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
4383    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4384      check_partial(common, FALSE);
4385    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4386    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4387    
4388    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4389      {      {
4390      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));  
4391      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4392        if (common->mode == JIT_COMPILE)
4393          add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
4394        else
4395          {
4396          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4397          /* STR_PTR = STR_END - IN_UCHARS(1) */
4398          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4399          check_partial(common, TRUE);
4400          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4401          JUMPHERE(jump[1]);
4402          }
4403    
4404      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4405      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4406      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4407      }      }
4408    else    else
4409      {      {
4410      peek_char(common);      peek_char(common);
4411      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4412      }      }
4413    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4414    return cc;    return cc;
# Line 3286  switch(type) Line 4419  switch(type)
4419  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4420    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
4421  #endif  #endif
4422    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
4423      {      {
4424      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
4425      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
4426    
4427      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4428      context.sourcereg = -1;      context.sourcereg = -1;
4429  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4430      context.ucharptr = 0;      context.ucharptr = 0;
4431  #endif  #endif
4432      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4433      }      }
4434    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4435    read_char(common);    read_char(common);
4436  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4437    if (common->utf)    if (common->utf)
4438      {      {
4439      GETCHAR(c, cc);      GETCHAR(c, cc);
4440        }
4441      else
4442    #endif
4443        c = *cc;
4444      if (type == OP_CHAR || !char_has_othercase(common, cc))
4445        {
4446        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
4447        return cc + length;
4448        }
4449      oc = char_othercase(common, c);
4450      bit = c ^ oc;
4451      if (ispowerof2(bit))
4452        {
4453        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4454        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4455        return cc + length;
4456      }      }
   else  
 #endif  
     c = *cc;  
4457    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);
4458    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4459    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);
4460    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4461    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4462    return cc + length;    return cc + length;
4463    
4464    case OP_NOT:    case OP_NOT:
4465    case OP_NOTI:    case OP_NOTI:
4466    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4467    length = 1;    length = 1;
4468  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4469    if (common->utf)    if (common->utf)
# Line 3328  switch(type) Line 4474  switch(type)
4474        {        {
4475        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4476        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4477          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4478        else        else
4479          {          {
4480          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
4481          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4482          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
4483          }          }
4484        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4485        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));
# Line 3358  switch(type) Line 4504  switch(type)
4504      }      }
4505    
4506    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4507      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4508    else    else
4509      {      {
4510      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3366  switch(type) Line 4512  switch(type)
4512      if (ispowerof2(bit))      if (ispowerof2(bit))
4513        {        {
4514        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4515        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4516        }        }
4517      else      else
4518        {        {
4519        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4520        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
4521        }        }
4522      }      }
4523    return cc + 1;    return cc + length;
4524    
4525    case OP_CLASS:    case OP_CLASS:
4526    case OP_NCLASS:    case OP_NCLASS:
4527    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4528    read_char(common);    read_char(common);
4529      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4530        return cc + 32 / sizeof(pcre_uchar);
4531    
4532  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4533    jump[0] = NULL;    jump[0] = NULL;
4534  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3391  switch(type) Line 4540  switch(type)
4540      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4541      if (type == OP_CLASS)      if (type == OP_CLASS)
4542        {        {
4543        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4544        jump[0] = NULL;        jump[0] = NULL;
4545        }        }
4546      }      }
# Line 3401  switch(type) Line 4550  switch(type)
4550    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4551    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4552    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);
4553    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4554  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4555    if (jump[0] != NULL)    if (jump[0] != NULL)
4556      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3410  switch(type) Line 4559  switch(type)
4559    
4560  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4561    case OP_XCLASS:    case OP_XCLASS:
4562    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4563    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4564  #endif  #endif
4565    
4566    case OP_REVERSE:    case OP_REVERSE:
4567    length = GET(cc, 0);    length = GET(cc, 0);
4568    SLJIT_ASSERT(length > 0);    if (length == 0)
4569        return cc + LINK_SIZE;
4570    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4571  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4572    if (common->utf)    if (common->utf)
# Line 3424  switch(type) Line 4574  switch(type)
4574      OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4575      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4576      label = LABEL();      label = LABEL();
4577      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
4578      skip_char_back(common);      skip_char_back(common);
4579      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
4580      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
4581      }      }
4582      else
4583  #endif  #endif
4584    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      {
4585    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4586    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
4587        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
4588        }
4589      check_start_used_ptr(common);
4590    return cc + LINK_SIZE;    return cc + LINK_SIZE;
4591    }    }
4592  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
4593  return cc;  return cc;
4594  }  }
4595    
4596  static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4597  {  {
4598  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4599  /* 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 3492  if (context.length > 0) Line 4645  if (context.length > 0)
4645    {    {
4646    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4647    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
4648    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
4649    
4650    context.sourcereg = -1;    context.sourcereg = -1;
4651  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4652    context.ucharptr = 0;    context.ucharptr = 0;
4653  #endif  #endif
4654    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
4655    return cc;    return cc;
4656    }    }
4657    
4658  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4659  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4660  }  }
4661    
4662  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
4663  {  {
4664  DEFINE_COMPILER;  DEFINE_COMPILER;
4665  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3514  int offset = GET2(cc, 1) << 1; Line 4667  int offset = GET2(cc, 1) << 1;
4667  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4668  if (!common->jscript_compat)  if (!common->jscript_compat)
4669    {    {
4670    if (fallbacks == NULL)    if (backtracks == NULL)
4671      {      {
4672        /* OVECTOR(1) contains the "string begin - 1" constant. */
4673      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4674      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4675      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4676      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4677      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4678      }      }
4679    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4680    }    }
4681  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4682  }  }
4683    
4684  /* Forward definitions. */  /* Forward definitions. */
4685  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4686  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4687    
4688  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4689    do \    do \
4690      { \      { \
4691      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4692      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4693        return error; \        return error; \
4694      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4695      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4696      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4697      parent->top = fallback; \      parent->top = backtrack; \
4698      } \      } \
4699    while (0)    while (0)
4700    
4701  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4702    do \    do \
4703      { \      { \
4704      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4705      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4706        return; \        return; \
4707      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4708      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4709      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4710      parent->top = fallback; \      parent->top = backtrack; \
4711      } \      } \
4712    while (0)    while (0)
4713    
4714  #define FALLBACK_AS(type) ((type*)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4715    
4716  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4717  {  {
4718  DEFINE_COMPILER;  DEFINE_COMPILER;
4719  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
4720  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4721    struct sljit_jump *partial;
4722    struct sljit_jump *nopartial;
4723    
4724  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4725    /* OVECTOR(1) contains the "string begin - 1" constant. */
4726  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4727    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4728    
4729  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4730  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3580  if (common->utf && *cc == OP_REFI) Line 4737  if (common->utf && *cc == OP_REFI)
4737    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
4738    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4739    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
4740    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
4741    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
4742    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4743    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
4744        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
4745      else
4746        {
4747        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
4748        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
4749        check_partial(common, FALSE);
4750        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4751        JUMPHERE(nopartial);
4752        }
4753    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
4754    }    }
4755  else  else
# Line 3592  else Line 4758  else
4758    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
4759    if (withchecks)    if (withchecks)
4760      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
4761    
4762    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4763      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4764      if (common->mode == JIT_COMPILE)
4765        add_jump(compiler, backtracks, partial);
4766    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
4767    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
4768    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4769    
4770      if (common->mode != JIT_COMPILE)
4771        {
4772        nopartial = JUMP(SLJIT_JUMP);
4773        JUMPHERE(partial);
4774        /* TMP2 -= STR_END - STR_PTR */
4775        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
4776        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
4777        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4778        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4779        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
4780        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4781        JUMPHERE(partial);
4782        check_partial(common, FALSE);
4783        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4784        JUMPHERE(nopartial);
4785        }
4786    }    }
4787    
4788  if (jump != NULL)  if (jump != NULL)
4789    {    {
4790    if (emptyfail)    if (emptyfail)
4791      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4792    else    else
4793      JUMPHERE(jump);      JUMPHERE(jump);
4794    }    }
4795  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4796  }  }
4797    
4798  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4799  {  {
4800  DEFINE_COMPILER;  DEFINE_COMPILER;
4801  fallback_common *fallback;  backtrack_common *backtrack;
4802  pcre_uchar type;  pcre_uchar type;
4803  struct sljit_label *label;  struct sljit_label *label;
4804  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3621  pcre_uchar *ccbegin = cc; Line 4807  pcre_uchar *ccbegin = cc;
4807  int min = 0, max = 0;  int min = 0, max = 0;
4808  BOOL minimize;  BOOL minimize;
4809    
4810  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4811    
4812  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4813  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 3673  if (!minimize) Line 4859  if (!minimize)
4859      {      {
4860      allocate_stack(common, 1);      allocate_stack(common, 1);
4861      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4862      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4863      }      }
4864    
4865    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4866      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4867    
4868    label = LABEL();    label = LABEL();
4869    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4870    
4871    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4872      {      {
# Line 3708  if (!minimize) Line 4894  if (!minimize)
4894      }      }
4895    
4896    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4897    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4898    
4899    decrease_call_count(common);    decrease_call_count(common);
4900    return cc;    return cc;
# Line 3726  if (min == 0) Line 4912  if (min == 0)
4912    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4913    }    }
4914  else  else
4915    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4916    
4917  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4918  if (max > 0)  if (max > 0)
4919    add_jump(compiler, &fallback->topfallbacks, 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));
4920    
4921  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4922  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4923    
4924  if (min > 1)  if (min > 1)
# Line 3740  if (min > 1) Line 4926  if (min > 1)
4926    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4927    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4928    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4929    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4930    }    }
4931  else if (max > 0)  else if (max > 0)
4932    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 3753  decrease_call_count(common); Line 4939  decrease_call_count(common);
4939  return cc;  return cc;
4940  }  }
4941    
4942  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4943  {  {
4944  DEFINE_COMPILER;  DEFINE_COMPILER;
4945  fallback_common *fallback;  backtrack_common *backtrack;
4946  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4947  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4948  int start = GET(cc, 1);  int start = GET(cc, 1);
4949    
4950  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4951  while (entry != NULL)  while (entry != NULL)
4952    {    {
4953    if (entry->start == start)    if (entry->start == start)
# Line 3786  if (entry == NULL) Line 4972  if (entry == NULL)
4972      common->entries = entry;      common->entries = entry;
4973    }    }
4974    
4975  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4976  allocate_stack(common, 1);    {
4977  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4978      allocate_stack(common, 2);
4979      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4980      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4981      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4982      }
4983    else if (common->has_set_som || common->mark_ptr != 0)
4984      {
4985      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4986      allocate_stack(common, 1);
4987      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4988      }
4989    
4990  if (entry->entry == NULL)  if (entry->entry == NULL)
4991    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
4992  else  else
4993    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4994  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4995  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
4996  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4997  }  }
4998    
4999  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5000  {  {
5001  DEFINE_COMPILER;  DEFINE_COMPILER;
5002  int framesize;  int framesize;
5003  int localptr;  int private_data_ptr;
5004  fallback_common altfallback;  backtrack_common altbacktrack;
5005  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5006  pcre_uchar opcode;  pcre_uchar opcode;
5007  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5008  jump_list *tmp = NULL;  jump_list *tmp = NULL;
5009  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5010  jump_list **found;  jump_list **found;
5011  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5012    struct sljit_label *save_quitlabel = common->quitlabel;
5013  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5014    jump_list *save_quit = common->quit;
5015    jump_list *save_accept = common->accept;
5016  struct sljit_jump *jump;  struct sljit_jump *jump;
5017  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
5018    
5019  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5020    {    {
# Line 3823  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5022  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5022    bra = *cc;    bra = *cc;
5023    cc++;    cc++;
5024    }    }
5025  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5026  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5027  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5028  fallback->framesize = framesize;  backtrack->framesize = framesize;
5029  fallback->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5030  opcode = *cc;  opcode = *cc;
5031  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5032  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 3836  cc += GET(cc, 1); Line 5035  cc += GET(cc, 1);
5035    
5036  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5037    {    {
5038    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
5039    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5040    free_stack(common, 1);    free_stack(common, 1);
5041    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 3844  if (bra == OP_BRAMINZERO) Line 5043  if (bra == OP_BRAMINZERO)
5043    
5044  if (framesize < 0)  if (framesize < 0)
5045    {    {
5046    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);
5047    allocate_stack(common, 1);    allocate_stack(common, 1);
5048    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5049    }    }
5050  else  else
5051    {    {
5052    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5053    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5054    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));
5055    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5056    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5057    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5058    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5059    }    }
5060    
5061  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5062    common->quitlabel = NULL;
5063    common->quit = NULL;
5064  while (1)  while (1)
5065    {    {
5066    common->acceptlabel = NULL;    common->acceptlabel = NULL;
5067    common->accept = NULL;    common->accept = NULL;
5068    altfallback.top = NULL;    altbacktrack.top = NULL;
5069    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5070    
5071    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5072      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5073    
5074    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5075    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5076    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5077      {      {
5078        common->quitlabel = save_quitlabel;
5079      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5080        common->quit = save_quit;
5081      common->accept = save_accept;      common->accept = save_accept;
5082      return NULL;      return NULL;
5083      }      }
# Line 3884  while (1) Line 5087  while (1)
5087    
5088    /* Reset stack. */    /* Reset stack. */
5089    if (framesize < 0)    if (framesize < 0)
5090      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);
5091    else {    else {
5092      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5093        {        {
5094        /* 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. */
5095        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5096        }        }
5097      else      else
5098        {        {
5099        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);
5100        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5101        }        }
5102    }    }
# Line 3911  while (1) Line 5114  while (1)
5114          {          {
5115          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5116          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
5117          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5118          }          }
5119        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5120        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 3919  while (1) Line 5122  while (1)
5122      else if (framesize >= 0)      else if (framesize >= 0)
5123        {        {
5124        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5125        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5126        }        }
5127      }      }
5128    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5129    
5130    compile_fallbackpath(common, altfallback.top);    compile_backtrackingpath(common, altbacktrack.top);
5131    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5132      {      {
5133        common->quitlabel = save_quitlabel;
5134      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5135        common->quit = save_quit;
5136      common->accept = save_accept;      common->accept = save_accept;
5137      return NULL;      return NULL;
5138      }      }
5139    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5140    
5141    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5142      break;      break;
# Line 3940  while (1) Line 5145  while (1)
5145    cc += GET(cc, 1);    cc += GET(cc, 1);
5146    }    }
5147  /* None of them matched. */  /* None of them matched. */
5148    if (common->quit != NULL)
5149      set_jumps(common->quit, LABEL());
5150    
5151  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5152    {    {
# Line 3966  if (opcode == OP_ASSERT || opcode == OP_ Line 5173  if (opcode == OP_ASSERT || opcode == OP_
5173        }        }
5174      else      else
5175        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5176      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5177      }      }
5178    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5179    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3991  if (opcode == OP_ASSERT || opcode == OP_ Line 5198  if (opcode == OP_ASSERT || opcode == OP_
5198      {      {
5199      if (bra == OP_BRA)      if (bra == OP_BRA)
5200        {        {
5201        /* 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. */
5202        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5203        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5204        }        }
5205      else      else
5206        {        {
5207        /* 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. */
5208        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5209        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5210        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);
5211        }        }
# Line 4006  if (opcode == OP_ASSERT || opcode == OP_ Line 5213  if (opcode == OP_ASSERT || opcode == OP_
5213    
5214    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5215      {      {
5216      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5217      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->matchingpath);
5218      }      }
5219    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5220      {      {
5221      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5222      JUMPHERE(brajump);      JUMPHERE(brajump);
5223      if (framesize >= 0)      if (framesize >= 0)
5224        {        {
5225        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);
5226        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5227        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5228        }        }
5229      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5230      }      }
5231    }    }
5232  else  else
# Line 4045  else Line 5252  else
5252        }        }
5253      else      else
5254        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5255      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5256      }      }
5257    
5258    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5259      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5260    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5261      {      {
5262      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5263      JUMPHERE(brajump);      JUMPHERE(brajump);
5264      }      }
5265    
5266    if (bra != OP_BRA)    if (bra != OP_BRA)
5267      {      {
5268      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5269      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5270      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5271      }      }
5272    }    }
5273    
5274    common->quitlabel = save_quitlabel;
5275  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5276    common->quit = save_quit;
5277  common->accept = save_accept;  common->accept = save_accept;
5278  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5279  }  }
# Line 4079  sljit_w name_entry_size = locals[LOCALS1 Line 5288  sljit_w name_entry_size = locals[LOCALS1
5288  sljit_w no_capture;  sljit_w no_capture;
5289  int i;  int i;
5290    
5291  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
5292    refno >>= 8;
5293  no_capture = locals[1];  no_capture = locals[1];
5294    
5295  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4232  return condition; Line 5442  return condition;
5442                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5443  */  */
5444    
5445  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5446  {  {
5447  DEFINE_COMPILER;  DEFINE_COMPILER;
5448  fallback_common *fallback;  backtrack_common *backtrack;
5449  pcre_uchar opcode;  pcre_uchar opcode;
5450  int localptr = 0;  int private_data_ptr = 0;
5451  int offset = 0;  int offset = 0;
5452  int stacksize;  int stacksize;
5453  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5454  pcre_uchar *hotpath;  pcre_uchar *matchingpath;
5455  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5456  pcre_uchar ket;  pcre_uchar ket;
5457  assert_fallback *assert;  assert_backtrack *assert;
5458  BOOL has_alternatives;  BOOL has_alternatives;
5459  struct sljit_jump *jump;  struct sljit_jump *jump;
5460  struct sljit_jump *skip;  struct sljit_jump *skip;
5461  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
5462  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
5463    
5464  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5465    
5466  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5467    {    {
# Line 4262  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5472  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5472    
5473  opcode = *cc;  opcode = *cc;
5474  ccbegin = cc;  ccbegin = cc;
5475  hotpath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5476    
5477  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)
5478    {    {
5479    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
5480    parent->top = fallback->prev;    parent->top = backtrack->prev;
5481    return bracketend(cc);    return bracketend(cc);
5482    }    }
5483    
# Line 4279  cc += GET(cc, 1); Line 5489  cc += GET(cc, 1);
5489  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5490  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5491    {    {
5492    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5493    if (*hotpath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5494      {      {
5495      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5496      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5497        has_alternatives = FALSE;        has_alternatives = FALSE;
5498      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4301  if (opcode == OP_CBRA || opcode == OP_SC Line 5511  if (opcode == OP_CBRA || opcode == OP_SC
5511    {    {
5512    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5513    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5514    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5515    offset <<= 1;      {
5516    FALLBACK_AS(bracket_fallback)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5517    hotpath += IMM2_SIZE;      offset <<= 1;
5518        }
5519      else
5520        {
5521        offset <<= 1;
5522        private_data_ptr = OVECTOR(offset);
5523        }
5524      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5525      matchingpath += IMM2_SIZE;
5526    }    }
5527  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5528    {    {
5529    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5530    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5531    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5532    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5533    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5534      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5535    }    }
5536    
5537  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4338  if (bra == OP_BRAZERO) Line 5556  if (bra == OP_BRAZERO)
5556    
5557  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5558    {    {
5559    /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */    /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
5560    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5561    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
5562      {      {
# Line 4355  if (bra == OP_BRAMINZERO) Line 5573  if (bra == OP_BRAMINZERO)
5573        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
5574        JUMPHERE(jump);        JUMPHERE(jump);
5575        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5576        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5577          {          {
5578          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5579          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);
5580          }          }
5581        else        else
5582          {          {
5583          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5584          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5585          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5586          }          }
5587        JUMPHERE(skip);        JUMPHERE(skip);
5588        }        }
# Line 4378  if (bra == OP_BRAMINZERO) Line 5596  if (bra == OP_BRAMINZERO)
5596    }    }
5597    
5598  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5599    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5600    
5601  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5602    {    {
5603    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5604    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5605      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5606    }    }
5607    
5608  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
5609  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5610    {    {
5611    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5612      {      {
5613      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5614      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5615        {        {
5616        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5617        allocate_stack(common, 2);        allocate_stack(common, 2);
5618        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5619        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5620        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5621        }        }
5622      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5623        {        {
5624        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);
5625        allocate_stack(common, 1);        allocate_stack(common, 1);
5626        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5627        }        }
5628      else      else
5629        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);
5630      }      }
5631    else    else
5632      {      {
5633      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5634        {        {
5635        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5636        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5637        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5638        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5640        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5641        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5642        }        }
5643      else      else
5644        {        {
5645        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5646        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5647        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5648        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5649        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5650        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);