1/*************************************************
2*      Perl-Compatible Regular Expressions       *
3*************************************************/
4
5/* PCRE is a library of functions to support regular expressions whose syntax
6and semantics are as close as possible to those of the Perl 5 language.
7
8                       Written by Philip Hazel
9           Copyright (c) 1997-2012 University of Cambridge
10
11  The machine code generator part (this module) was written by Zoltan Herczeg
12                      Copyright (c) 2010-2012
13
14-----------------------------------------------------------------------------
15Redistribution and use in source and binary forms, with or without
16modification, are permitted provided that the following conditions are met:
17
18    * Redistributions of source code must retain the above copyright notice,
19      this list of conditions and the following disclaimer.
20
21    * Redistributions in binary form must reproduce the above copyright
22      notice, this list of conditions and the following disclaimer in the
23      documentation and/or other materials provided with the distribution.
24
25    * Neither the name of the University of Cambridge nor the names of its
26      contributors may be used to endorse or promote products derived from
27      this software without specific prior written permission.
28
29THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39POSSIBILITY OF SUCH DAMAGE.
40-----------------------------------------------------------------------------
41*/
42
43#ifdef HAVE_CONFIG_H
44#include "config.h"
45#endif
46
47#include "pcre_internal.h"
48
49#ifdef SUPPORT_JIT
50
51/* All-in-one: Since we use the JIT compiler only from here,
52we just include it. This way we don't need to touch the build
53system files. */
54
55#define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56#define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57#define SLJIT_CONFIG_AUTO 1
58#define SLJIT_CONFIG_STATIC 1
59#define SLJIT_VERBOSE 0
60#define SLJIT_DEBUG 0
61
62#include "sljit/sljitLir.c"
63
64#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65#error Unsupported architecture
66#endif
67
68/* Allocate memory on the stack. Fast, but limited size. */
69#define LOCAL_SPACE_SIZE 32768
70
71#define STACK_GROWTH_RATE 8192
72
73/* Enable to check that the allocation could destroy temporaries. */
74#if defined SLJIT_DEBUG && SLJIT_DEBUG
75#define DESTROY_REGISTERS 1
76#endif
77
78/*
79Short summary about the backtracking mechanism empolyed by the jit code generator:
80
81The code generator follows the recursive nature of the PERL compatible regular
82expressions. The basic blocks of regular expressions are condition checkers
83whose execute different commands depending on the result of the condition check.
84The relationship between the operators can be horizontal (concatenation) and
85vertical (sub-expression) (See struct backtrack_common for more details).
86
87  'ab' - 'a' and 'b' regexps are concatenated
88  'a+' - 'a' is the sub-expression of the '+' operator
89
90The condition checkers are boolean (true/false) checkers. Machine code is generated
91for the checker itself and for the actions depending on the result of the checker.
92The 'true' case is called as the try path (expected path), and the other is called as
93the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94branches on the try path.
95
96 Greedy star operator (*) :
97   Try path: match happens.
98   Backtrack path: match failed.
99 Non-greedy star operator (*?) :
100   Try path: no need to perform a match.
101   Backtrack path: match is required.
102
103The following example shows how the code generated for a capturing bracket
104with two alternatives. Let A, B, C, D are arbirary regular expressions, and
105we have the following regular expression:
106
107   A(B|C)D
108
109The generated code will be the following:
110
111 A try path
112 '(' try path (pushing arguments to the stack)
113 B try path
114 ')' try path (pushing arguments to the stack)
115 D try path
116 return with successful match
117
118 D backtrack path
119 ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120 B backtrack path
121 C expected path
122 jump to D try path
123 C backtrack path
124 A backtrack path
125
126 Notice, that the order of backtrack code paths are the opposite of the fast
127 code paths. In this way the topmost value on the stack is always belong
128 to the current backtrack code path. The backtrack path must check
129 whether there is a next alternative. If so, it needs to jump back to
130 the try path eventually. Otherwise it needs to clear out its own stack
131 frame and continue the execution on the backtrack code paths.
132*/
133
134/*
135Saved stack frames:
136
137Atomic blocks and asserts require reloading the values of local variables
138when the backtrack mechanism performed. Because of OP_RECURSE, the locals
139are not necessarly known in compile time, thus we need a dynamic restore
140mechanism.
141
142The stack frames are stored in a chain list, and have the following format:
143([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
144
145Thus we can restore the locals to a particular point in the stack.
146*/
147
148typedef struct jit_arguments {
149  /* Pointers first. */
150  struct sljit_stack *stack;
151  const pcre_uchar *str;
152  const pcre_uchar *begin;
153  const pcre_uchar *end;
154  int *offsets;
155  pcre_uchar *uchar_ptr;
156  pcre_uchar *mark_ptr;
157  /* Everything else after. */
158  int offsetcount;
159  int calllimit;
160  pcre_uint8 notbol;
161  pcre_uint8 noteol;
162  pcre_uint8 notempty;
163  pcre_uint8 notempty_atstart;
164} jit_arguments;
165
166typedef struct executable_functions {
167  void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168  PUBL(jit_callback) callback;
169  void *userdata;
170  sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171} executable_functions;
172
173typedef struct jump_list {
174  struct sljit_jump *jump;
175  struct jump_list *next;
176} jump_list;
177
178enum stub_types { stack_alloc };
179
180typedef struct stub_list {
181  enum stub_types type;
182  int data;
183  struct sljit_jump *start;
184  struct sljit_label *leave;
185  struct stub_list *next;
186} stub_list;
187
188typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189
190/* The following structure is the key data type for the recursive
191code generator. It is allocated by compile_trypath, and contains
192the aguments for compile_backtrackpath. Must be the first member
193of its descendants. */
194typedef struct backtrack_common {
195  /* Concatenation stack. */
196  struct backtrack_common *prev;
197  jump_list *nextbacktracks;
198  /* Internal stack (for component operators). */
199  struct backtrack_common *top;
200  jump_list *topbacktracks;
201  /* Opcode pointer. */
202  pcre_uchar *cc;
203} backtrack_common;
204
205typedef struct assert_backtrack {
206  backtrack_common common;
207  jump_list *condfailed;
208  /* Less than 0 (-1) if a frame is not needed. */
209  int framesize;
210  /* Points to our private memory word on the stack. */
211  int localptr;
212  /* For iterators. */
213  struct sljit_label *trypath;
214} assert_backtrack;
215
216typedef struct bracket_backtrack {
217  backtrack_common common;
218  /* Where to coninue if an alternative is successfully matched. */
219  struct sljit_label *alttrypath;
220  /* For rmin and rmax iterators. */
221  struct sljit_label *recursivetrypath;
222  /* For greedy ? operator. */
223  struct sljit_label *zerotrypath;
224  /* Contains the branches of a failed condition. */
225  union {
226    /* Both for OP_COND, OP_SCOND. */
227    jump_list *condfailed;
228    assert_backtrack *assert;
229    /* For OP_ONCE. -1 if not needed. */
230    int framesize;
231  } u;
232  /* Points to our private memory word on the stack. */
233  int localptr;
234} bracket_backtrack;
235
236typedef struct bracketpos_backtrack {
237  backtrack_common common;
238  /* Points to our private memory word on the stack. */
239  int localptr;
240  /* Reverting stack is needed. */
241  int framesize;
242  /* Allocated stack size. */
243  int stacksize;
244} bracketpos_backtrack;
245
246typedef struct braminzero_backtrack {
247  backtrack_common common;
248  struct sljit_label *trypath;
249} braminzero_backtrack;
250
251typedef struct iterator_backtrack {
252  backtrack_common common;
253  /* Next iteration. */
254  struct sljit_label *trypath;
255} iterator_backtrack;
256
257typedef struct recurse_entry {
258  struct recurse_entry *next;
259  /* Contains the function entry. */
260  struct sljit_label *entry;
261  /* Collects the calls until the function is not created. */
262  jump_list *calls;
263  /* Points to the starting opcode. */
264  int start;
265} recurse_entry;
266
267typedef struct recurse_backtrack {
268  backtrack_common common;
269} recurse_backtrack;
270
271typedef struct compiler_common {
272  struct sljit_compiler *compiler;
273  pcre_uchar *start;
274
275  /* Opcode local area direct map. */
276  int *localptrs;
277  int cbraptr;
278  /* OVector starting point. Must be divisible by 2. */
279  int ovector_start;
280  /* Last known position of the requested byte. */
281  int req_char_ptr;
282  /* Head of the last recursion. */
283  int recursive_head;
284  /* First inspected character for partial matching. */
285  int start_used_ptr;
286  /* Starting pointer for partial soft matches. */
287  int hit_start;
288  /* End pointer of the first line. */
289  int first_line_end;
290  /* Points to the marked string. */
291  int mark_ptr;
292
293  /* Other  */
294  const pcre_uint8 *fcc;
295  sljit_w lcc;
296  int mode;
297  int nltype;
298  int newline;
299  int bsr_nltype;
300  int endonly;
301  BOOL has_set_som;
302  sljit_w ctypes;
303  sljit_uw name_table;
304  sljit_w name_count;
305  sljit_w name_entry_size;
306
307  /* Labels and jump lists. */
308  struct sljit_label *partialmatchlabel;
309  struct sljit_label *leavelabel;
310  struct sljit_label *acceptlabel;
311  stub_list *stubs;
312  recurse_entry *entries;
313  recurse_entry *currententry;
314  jump_list *partialmatch;
315  jump_list *leave;
316  jump_list *accept;
317  jump_list *calllimit;
318  jump_list *stackalloc;
319  jump_list *revertframes;
320  jump_list *wordboundary;
321  jump_list *anynewline;
322  jump_list *hspace;
323  jump_list *vspace;
324  jump_list *casefulcmp;
325  jump_list *caselesscmp;
326  BOOL jscript_compat;
327#ifdef SUPPORT_UTF
328  BOOL utf;
329#ifdef SUPPORT_UCP
330  BOOL use_ucp;
331#endif
332  jump_list *utfreadchar;
333#ifdef COMPILE_PCRE8
334  jump_list *utfreadtype8;
335#endif
336#endif /* SUPPORT_UTF */
337#ifdef SUPPORT_UCP
338  jump_list *getucd;
339#endif
340} compiler_common;
341
342/* For byte_sequence_compare. */
343
344typedef struct compare_context {
345  int length;
346  int sourcereg;
347#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
348  int ucharptr;
349  union {
350    sljit_i asint;
351    sljit_uh asushort;
352#ifdef COMPILE_PCRE8
353    sljit_ub asbyte;
354    sljit_ub asuchars[4];
355#else
356#ifdef COMPILE_PCRE16
357    sljit_uh asuchars[2];
358#endif
359#endif
360  } c;
361  union {
362    sljit_i asint;
363    sljit_uh asushort;
364#ifdef COMPILE_PCRE8
365    sljit_ub asbyte;
366    sljit_ub asuchars[4];
367#else
368#ifdef COMPILE_PCRE16
369    sljit_uh asuchars[2];
370#endif
371#endif
372  } oc;
373#endif
374} compare_context;
375
376enum {
377  frame_end = 0,
378  frame_setstrbegin = -1,
379  frame_setmark = -2
380};
381
382/* Undefine sljit macros. */
383#undef CMP
384
385/* Used for accessing the elements of the stack. */
386#define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
387
388#define TMP1          SLJIT_TEMPORARY_REG1
389#define TMP2          SLJIT_TEMPORARY_REG3
390#define TMP3          SLJIT_TEMPORARY_EREG2
391#define STR_PTR       SLJIT_SAVED_REG1
392#define STR_END       SLJIT_SAVED_REG2
393#define STACK_TOP     SLJIT_TEMPORARY_REG2
394#define STACK_LIMIT   SLJIT_SAVED_REG3
395#define ARGUMENTS     SLJIT_SAVED_EREG1
396#define CALL_COUNT    SLJIT_SAVED_EREG2
397#define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
398
399/* Locals layout. */
400/* These two locals can be used by the current opcode. */
401#define LOCALS0          (0 * sizeof(sljit_w))
402#define LOCALS1          (1 * sizeof(sljit_w))
403/* Two local variables for possessive quantifiers (char1 cannot use them). */
404#define POSSESSIVE0      (2 * sizeof(sljit_w))
405#define POSSESSIVE1      (3 * sizeof(sljit_w))
406/* Max limit of recursions. */
407#define CALL_LIMIT       (4 * sizeof(sljit_w))
408/* The output vector is stored on the stack, and contains pointers
409to characters. The vector data is divided into two groups: the first
410group contains the start / end character pointers, and the second is
411the start pointers when the end of the capturing group has not yet reached. */
412#define OVECTOR_START    (common->ovector_start)
413#define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
414#define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
415#define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
416
417#ifdef COMPILE_PCRE8
418#define MOV_UCHAR  SLJIT_MOV_UB
419#define MOVU_UCHAR SLJIT_MOVU_UB
420#else
421#ifdef COMPILE_PCRE16
422#define MOV_UCHAR  SLJIT_MOV_UH
423#define MOVU_UCHAR SLJIT_MOVU_UH
424#else
425#error Unsupported compiling mode
426#endif
427#endif
428
429/* Shortcuts. */
430#define DEFINE_COMPILER \
431  struct sljit_compiler *compiler = common->compiler
432#define OP1(op, dst, dstw, src, srcw) \
433  sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
434#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
435  sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
436#define LABEL() \
437  sljit_emit_label(compiler)
438#define JUMP(type) \
439  sljit_emit_jump(compiler, (type))
440#define JUMPTO(type, label) \
441  sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
442#define JUMPHERE(jump) \
443  sljit_set_label((jump), sljit_emit_label(compiler))
444#define CMP(type, src1, src1w, src2, src2w) \
445  sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
446#define CMPTO(type, src1, src1w, src2, src2w, label) \
447  sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
448#define COND_VALUE(op, dst, dstw, type) \
449  sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
450#define GET_LOCAL_BASE(dst, dstw, offset) \
451  sljit_get_local_base(compiler, (dst), (dstw), (offset))
452
453static pcre_uchar* bracketend(pcre_uchar* cc)
454{
455SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
456do cc += GET(cc, 1); while (*cc == OP_ALT);
457SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
458cc += 1 + LINK_SIZE;
459return cc;
460}
461
462/* Functions whose might need modification for all new supported opcodes:
463 next_opcode
464 get_localspace
465 set_localptrs
466 get_framesize
467 init_frame
468 get_localsize
469 copy_locals
470 compile_trypath
471 compile_backtrackpath
472*/
473
474static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
475{
476SLJIT_UNUSED_ARG(common);
477switch(*cc)
478  {
479  case OP_SOD:
480  case OP_SOM:
481  case OP_SET_SOM:
482  case OP_NOT_WORD_BOUNDARY:
483  case OP_WORD_BOUNDARY:
484  case OP_NOT_DIGIT:
485  case OP_DIGIT:
486  case OP_NOT_WHITESPACE:
487  case OP_WHITESPACE:
488  case OP_NOT_WORDCHAR:
489  case OP_WORDCHAR:
490  case OP_ANY:
491  case OP_ALLANY:
492  case OP_ANYNL:
493  case OP_NOT_HSPACE:
494  case OP_HSPACE:
495  case OP_NOT_VSPACE:
496  case OP_VSPACE:
497  case OP_EXTUNI:
498  case OP_EODN:
499  case OP_EOD:
500  case OP_CIRC:
501  case OP_CIRCM:
502  case OP_DOLL:
503  case OP_DOLLM:
504  case OP_TYPESTAR:
505  case OP_TYPEMINSTAR:
506  case OP_TYPEPLUS:
507  case OP_TYPEMINPLUS:
508  case OP_TYPEQUERY:
509  case OP_TYPEMINQUERY:
510  case OP_TYPEPOSSTAR:
511  case OP_TYPEPOSPLUS:
512  case OP_TYPEPOSQUERY:
513  case OP_CRSTAR:
514  case OP_CRMINSTAR:
515  case OP_CRPLUS:
516  case OP_CRMINPLUS:
517  case OP_CRQUERY:
518  case OP_CRMINQUERY:
519  case OP_DEF:
520  case OP_BRAZERO:
521  case OP_BRAMINZERO:
522  case OP_BRAPOSZERO:
523  case OP_COMMIT:
524  case OP_FAIL:
525  case OP_ACCEPT:
526  case OP_ASSERT_ACCEPT:
527  case OP_SKIPZERO:
528  return cc + 1;
529
530  case OP_ANYBYTE:
531#ifdef SUPPORT_UTF
532  if (common->utf) return NULL;
533#endif
534  return cc + 1;
535
536  case OP_CHAR:
537  case OP_CHARI:
538  case OP_NOT:
539  case OP_NOTI:
540  case OP_STAR:
541  case OP_MINSTAR:
542  case OP_PLUS:
543  case OP_MINPLUS:
544  case OP_QUERY:
545  case OP_MINQUERY:
546  case OP_POSSTAR:
547  case OP_POSPLUS:
548  case OP_POSQUERY:
549  case OP_STARI:
550  case OP_MINSTARI:
551  case OP_PLUSI:
552  case OP_MINPLUSI:
553  case OP_QUERYI:
554  case OP_MINQUERYI:
555  case OP_POSSTARI:
556  case OP_POSPLUSI:
557  case OP_POSQUERYI:
558  case OP_NOTSTAR:
559  case OP_NOTMINSTAR:
560  case OP_NOTPLUS:
561  case OP_NOTMINPLUS:
562  case OP_NOTQUERY:
563  case OP_NOTMINQUERY:
564  case OP_NOTPOSSTAR:
565  case OP_NOTPOSPLUS:
566  case OP_NOTPOSQUERY:
567  case OP_NOTSTARI:
568  case OP_NOTMINSTARI:
569  case OP_NOTPLUSI:
570  case OP_NOTMINPLUSI:
571  case OP_NOTQUERYI:
572  case OP_NOTMINQUERYI:
573  case OP_NOTPOSSTARI:
574  case OP_NOTPOSPLUSI:
575  case OP_NOTPOSQUERYI:
576  cc += 2;
577#ifdef SUPPORT_UTF
578  if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
579#endif
580  return cc;
581
582  case OP_UPTO:
583  case OP_MINUPTO:
584  case OP_EXACT:
585  case OP_POSUPTO:
586  case OP_UPTOI:
587  case OP_MINUPTOI:
588  case OP_EXACTI:
589  case OP_POSUPTOI:
590  case OP_NOTUPTO:
591  case OP_NOTMINUPTO:
592  case OP_NOTEXACT:
593  case OP_NOTPOSUPTO:
594  case OP_NOTUPTOI:
595  case OP_NOTMINUPTOI:
596  case OP_NOTEXACTI:
597  case OP_NOTPOSUPTOI:
598  cc += 2 + IMM2_SIZE;
599#ifdef SUPPORT_UTF
600  if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
601#endif
602  return cc;
603
604  case OP_NOTPROP:
605  case OP_PROP:
606  return cc + 1 + 2;
607
608  case OP_TYPEUPTO:
609  case OP_TYPEMINUPTO:
610  case OP_TYPEEXACT:
611  case OP_TYPEPOSUPTO:
612  case OP_REF:
613  case OP_REFI:
614  case OP_CREF:
615  case OP_NCREF:
616  case OP_RREF:
617  case OP_NRREF:
618  case OP_CLOSE:
619  cc += 1 + IMM2_SIZE;
620  return cc;
621
622  case OP_CRRANGE:
623  case OP_CRMINRANGE:
624  return cc + 1 + 2 * IMM2_SIZE;
625
626  case OP_CLASS:
627  case OP_NCLASS:
628  return cc + 1 + 32 / sizeof(pcre_uchar);
629
630#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
631  case OP_XCLASS:
632  return cc + GET(cc, 1);
633#endif
634
635  case OP_RECURSE:
636  case OP_ASSERT:
637  case OP_ASSERT_NOT:
638  case OP_ASSERTBACK:
639  case OP_ASSERTBACK_NOT:
640  case OP_REVERSE:
641  case OP_ONCE:
642  case OP_ONCE_NC:
643  case OP_BRA:
644  case OP_BRAPOS:
645  case OP_COND:
646  case OP_SBRA:
647  case OP_SBRAPOS:
648  case OP_SCOND:
649  case OP_ALT:
650  case OP_KET:
651  case OP_KETRMAX:
652  case OP_KETRMIN:
653  case OP_KETRPOS:
654  return cc + 1 + LINK_SIZE;
655
656  case OP_CBRA:
657  case OP_CBRAPOS:
658  case OP_SCBRA:
659  case OP_SCBRAPOS:
660  return cc + 1 + LINK_SIZE + IMM2_SIZE;
661
662  case OP_MARK:
663  return cc + 1 + 2 + cc[1];
664
665  default:
666  return NULL;
667  }
668}
669
670static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
671{
672int localspace = 0;
673pcre_uchar *alternative;
674/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
675while (cc < ccend)
676  {
677  switch(*cc)
678    {
679    case OP_SET_SOM:
680    common->has_set_som = TRUE;
681    cc += 1;
682    break;
683
684    case OP_ASSERT:
685    case OP_ASSERT_NOT:
686    case OP_ASSERTBACK:
687    case OP_ASSERTBACK_NOT:
688    case OP_ONCE:
689    case OP_ONCE_NC:
690    case OP_BRAPOS:
691    case OP_SBRA:
692    case OP_SBRAPOS:
693    case OP_SCOND:
694    localspace += sizeof(sljit_w);
695    cc += 1 + LINK_SIZE;
696    break;
697
698    case OP_CBRAPOS:
699    case OP_SCBRAPOS:
700    localspace += sizeof(sljit_w);
701    cc += 1 + LINK_SIZE + IMM2_SIZE;
702    break;
703
704    case OP_COND:
705    /* Might be a hidden SCOND. */
706    alternative = cc + GET(cc, 1);
707    if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
708      localspace += sizeof(sljit_w);
709    cc += 1 + LINK_SIZE;
710    break;
711
712    case OP_RECURSE:
713    /* Set its value only once. */
714    if (common->recursive_head == 0)
715      {
716      common->recursive_head = common->ovector_start;
717      common->ovector_start += sizeof(sljit_w);
718      }
719    cc += 1 + LINK_SIZE;
720    break;
721
722    case OP_MARK:
723    if (common->mark_ptr == 0)
724      {
725      common->mark_ptr = common->ovector_start;
726      common->ovector_start += sizeof(sljit_w);
727      }
728    cc += 1 + 2 + cc[1];
729    break;
730
731    default:
732    cc = next_opcode(common, cc);
733    if (cc == NULL)
734      return -1;
735    break;
736    }
737  }
738return localspace;
739}
740
741static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
742{
743pcre_uchar *cc = common->start;
744pcre_uchar *alternative;
745while (cc < ccend)
746  {
747  switch(*cc)
748    {
749    case OP_ASSERT:
750    case OP_ASSERT_NOT:
751    case OP_ASSERTBACK:
752    case OP_ASSERTBACK_NOT:
753    case OP_ONCE:
754    case OP_ONCE_NC:
755    case OP_BRAPOS:
756    case OP_SBRA:
757    case OP_SBRAPOS:
758    case OP_SCOND:
759    common->localptrs[cc - common->start] = localptr;
760    localptr += sizeof(sljit_w);
761    cc += 1 + LINK_SIZE;
762    break;
763
764    case OP_CBRAPOS:
765    case OP_SCBRAPOS:
766    common->localptrs[cc - common->start] = localptr;
767    localptr += sizeof(sljit_w);
768    cc += 1 + LINK_SIZE + IMM2_SIZE;
769    break;
770
771    case OP_COND:
772    /* Might be a hidden SCOND. */
773    alternative = cc + GET(cc, 1);
774    if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
775      {
776      common->localptrs[cc - common->start] = localptr;
777      localptr += sizeof(sljit_w);
778      }
779    cc += 1 + LINK_SIZE;
780    break;
781
782    default:
783    cc = next_opcode(common, cc);
784    SLJIT_ASSERT(cc != NULL);
785    break;
786    }
787  }
788}
789
790/* Returns with -1 if no need for frame. */
791static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
792{
793pcre_uchar *ccend = bracketend(cc);
794int length = 0;
795BOOL possessive = FALSE;
796BOOL setsom_found = recursive;
797BOOL setmark_found = recursive;
798
799if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
800  {
801  length = 3;
802  possessive = TRUE;
803  }
804
805cc = next_opcode(common, cc);
806SLJIT_ASSERT(cc != NULL);
807while (cc < ccend)
808  switch(*cc)
809    {
810    case OP_SET_SOM:
811    SLJIT_ASSERT(common->has_set_som);
812    if (!setsom_found)
813      {
814      length += 2;
815      setsom_found = TRUE;
816      }
817    cc += 1;
818    break;
819
820    case OP_MARK:
821    SLJIT_ASSERT(common->mark_ptr != 0);
822    if (!setmark_found)
823      {
824      length += 2;
825      setmark_found = TRUE;
826      }
827    cc += 1 + 2 + cc[1];
828    break;
829
830    case OP_RECURSE:
831    if (common->has_set_som && !setsom_found)
832      {
833      length += 2;
834      setsom_found = TRUE;
835      }
836    if (common->mark_ptr != 0 && !setmark_found)
837      {
838      length += 2;
839      setmark_found = TRUE;
840      }
841    cc += 1 + LINK_SIZE;
842    break;
843
844    case OP_CBRA:
845    case OP_CBRAPOS:
846    case OP_SCBRA:
847    case OP_SCBRAPOS:
848    length += 3;
849    cc += 1 + LINK_SIZE + IMM2_SIZE;
850    break;
851
852    default:
853    cc = next_opcode(common, cc);
854    SLJIT_ASSERT(cc != NULL);
855    break;
856    }
857
858/* Possessive quantifiers can use a special case. */
859if (SLJIT_UNLIKELY(possessive) && length == 3)
860  return -1;
861
862if (length > 0)
863  return length + 1;
864return -1;
865}
866
867static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
868{
869DEFINE_COMPILER;
870pcre_uchar *ccend = bracketend(cc);
871BOOL setsom_found = recursive;
872BOOL setmark_found = recursive;
873int offset;
874
875/* >= 1 + shortest item size (2) */
876SLJIT_UNUSED_ARG(stacktop);
877SLJIT_ASSERT(stackpos >= stacktop + 2);
878
879stackpos = STACK(stackpos);
880if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
881  cc = next_opcode(common, cc);
882SLJIT_ASSERT(cc != NULL);
883while (cc < ccend)
884  switch(*cc)
885    {
886    case OP_SET_SOM:
887    SLJIT_ASSERT(common->has_set_som);
888    if (!setsom_found)
889      {
890      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
891      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
892      stackpos += (int)sizeof(sljit_w);
893      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
894      stackpos += (int)sizeof(sljit_w);
895      setsom_found = TRUE;
896      }
897    cc += 1;
898    break;
899
900    case OP_MARK:
901    SLJIT_ASSERT(common->mark_ptr != 0);
902    if (!setmark_found)
903      {
904      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
905      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
906      stackpos += (int)sizeof(sljit_w);
907      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
908      stackpos += (int)sizeof(sljit_w);
909      setmark_found = TRUE;
910      }
911    cc += 1 + 2 + cc[1];
912    break;
913
914    case OP_RECURSE:
915    if (common->has_set_som && !setsom_found)
916      {
917      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
918      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
919      stackpos += (int)sizeof(sljit_w);
920      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
921      stackpos += (int)sizeof(sljit_w);
922      setsom_found = TRUE;
923      }
924    if (common->mark_ptr != 0 && !setmark_found)
925      {
926      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
927      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
928      stackpos += (int)sizeof(sljit_w);
929      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
930      stackpos += (int)sizeof(sljit_w);
931      setmark_found = TRUE;
932      }
933    cc += 1 + LINK_SIZE;
934    break;
935
936    case OP_CBRA:
937    case OP_CBRAPOS:
938    case OP_SCBRA:
939    case OP_SCBRAPOS:
940    offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
941    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
942    stackpos += (int)sizeof(sljit_w);
943    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
944    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
945    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
946    stackpos += (int)sizeof(sljit_w);
947    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
948    stackpos += (int)sizeof(sljit_w);
949
950    cc += 1 + LINK_SIZE + IMM2_SIZE;
951    break;
952
953    default:
954    cc = next_opcode(common, cc);
955    SLJIT_ASSERT(cc != NULL);
956    break;
957    }
958
959OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
960SLJIT_ASSERT(stackpos == STACK(stacktop));
961}
962
963static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
964{
965int localsize = 2;
966pcre_uchar *alternative;
967/* Calculate the sum of the local variables. */
968while (cc < ccend)
969  {
970  switch(*cc)
971    {
972    case OP_ASSERT:
973    case OP_ASSERT_NOT:
974    case OP_ASSERTBACK:
975    case OP_ASSERTBACK_NOT:
976    case OP_ONCE:
977    case OP_ONCE_NC:
978    case OP_BRAPOS:
979    case OP_SBRA:
980    case OP_SBRAPOS:
981    case OP_SCOND:
982    localsize++;
983    cc += 1 + LINK_SIZE;
984    break;
985
986    case OP_CBRA:
987    case OP_SCBRA:
988    localsize++;
989    cc += 1 + LINK_SIZE + IMM2_SIZE;
990    break;
991
992    case OP_CBRAPOS:
993    case OP_SCBRAPOS:
994    localsize += 2;
995    cc += 1 + LINK_SIZE + IMM2_SIZE;
996    break;
997
998    case OP_COND:
999    /* Might be a hidden SCOND. */
1000    alternative = cc + GET(cc, 1);
1001    if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1002      localsize++;
1003    cc += 1 + LINK_SIZE;
1004    break;
1005
1006    default:
1007    cc = next_opcode(common, cc);
1008    SLJIT_ASSERT(cc != NULL);
1009    break;
1010    }
1011  }
1012SLJIT_ASSERT(cc == ccend);
1013return localsize;
1014}
1015
1016static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1017  BOOL save, int stackptr, int stacktop)
1018{
1019DEFINE_COMPILER;
1020int srcw[2];
1021int count;
1022BOOL tmp1next = TRUE;
1023BOOL tmp1empty = TRUE;
1024BOOL tmp2empty = TRUE;
1025pcre_uchar *alternative;
1026enum {
1027  start,
1028  loop,
1029  end
1030} status;
1031
1032status = save ? start : loop;
1033stackptr = STACK(stackptr - 2);
1034stacktop = STACK(stacktop - 1);
1035
1036if (!save)
1037  {
1038  stackptr += sizeof(sljit_w);
1039  if (stackptr < stacktop)
1040    {
1041    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1042    stackptr += sizeof(sljit_w);
1043    tmp1empty = FALSE;
1044    }
1045  if (stackptr < stacktop)
1046    {
1047    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1048    stackptr += sizeof(sljit_w);
1049    tmp2empty = FALSE;
1050    }
1051  /* The tmp1next must be TRUE in either way. */
1052  }
1053
1054while (status != end)
1055  {
1056  count = 0;
1057  switch(status)
1058    {
1059    case start:
1060    SLJIT_ASSERT(save && common->recursive_head != 0);
1061    count = 1;
1062    srcw[0] = common->recursive_head;
1063    status = loop;
1064    break;
1065
1066    case loop:
1067    if (cc >= ccend)
1068      {
1069      status = end;
1070      break;
1071      }
1072
1073    switch(*cc)
1074      {
1075      case OP_ASSERT:
1076      case OP_ASSERT_NOT:
1077      case OP_ASSERTBACK:
1078      case OP_ASSERTBACK_NOT:
1079      case OP_ONCE:
1080      case OP_ONCE_NC:
1081      case OP_BRAPOS:
1082      case OP_SBRA:
1083      case OP_SBRAPOS:
1084      case OP_SCOND:
1085      count = 1;
1086      srcw[0] = PRIV_DATA(cc);
1087      SLJIT_ASSERT(srcw[0] != 0);
1088      cc += 1 + LINK_SIZE;
1089      break;
1090
1091      case OP_CBRA:
1092      case OP_SCBRA:
1093      count = 1;
1094      srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1095      cc += 1 + LINK_SIZE + IMM2_SIZE;
1096      break;
1097
1098      case OP_CBRAPOS:
1099      case OP_SCBRAPOS:
1100      count = 2;
1101      srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1102      srcw[0] = PRIV_DATA(cc);
1103      SLJIT_ASSERT(srcw[0] != 0);
1104      cc += 1 + LINK_SIZE + IMM2_SIZE;
1105      break;
1106
1107      case OP_COND:
1108      /* Might be a hidden SCOND. */
1109      alternative = cc + GET(cc, 1);
1110      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1111        {
1112        count = 1;
1113        srcw[0] = PRIV_DATA(cc);
1114        SLJIT_ASSERT(srcw[0] != 0);
1115        }
1116      cc += 1 + LINK_SIZE;
1117      break;
1118
1119      default:
1120      cc = next_opcode(common, cc);
1121      SLJIT_ASSERT(cc != NULL);
1122      break;
1123      }
1124    break;
1125
1126    case end:
1127    SLJIT_ASSERT_STOP();
1128    break;
1129    }
1130
1131  while (count > 0)
1132    {
1133    count--;
1134    if (save)
1135      {
1136      if (tmp1next)
1137        {
1138        if (!tmp1empty)
1139          {
1140          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1141          stackptr += sizeof(sljit_w);
1142          }
1143        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1144        tmp1empty = FALSE;
1145        tmp1next = FALSE;
1146        }
1147      else
1148        {
1149        if (!tmp2empty)
1150          {
1151          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1152          stackptr += sizeof(sljit_w);
1153          }
1154        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1155        tmp2empty = FALSE;
1156        tmp1next = TRUE;
1157        }
1158      }
1159    else
1160      {
1161      if (tmp1next)
1162        {
1163        SLJIT_ASSERT(!tmp1empty);
1164        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
1165        tmp1empty = stackptr >= stacktop;
1166        if (!tmp1empty)
1167          {
1168          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1169          stackptr += sizeof(sljit_w);
1170          }
1171        tmp1next = FALSE;
1172        }
1173      else
1174        {
1175        SLJIT_ASSERT(!tmp2empty);
1176        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
1177        tmp2empty = stackptr >= stacktop;
1178        if (!tmp2empty)
1179          {
1180          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1181          stackptr += sizeof(sljit_w);
1182          }
1183        tmp1next = TRUE;
1184        }
1185      }
1186    }
1187  }
1188
1189if (save)
1190  {
1191  if (tmp1next)
1192    {
1193    if (!tmp1empty)
1194      {
1195      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1196      stackptr += sizeof(sljit_w);
1197      }
1198    if (!tmp2empty)
1199      {
1200      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1201      stackptr += sizeof(sljit_w);
1202      }
1203    }
1204  else
1205    {
1206    if (!tmp2empty)
1207      {
1208      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1209      stackptr += sizeof(sljit_w);
1210      }
1211    if (!tmp1empty)
1212      {
1213      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1214      stackptr += sizeof(sljit_w);
1215      }
1216    }
1217  }
1218SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1219}
1220
1221static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1222{
1223return (value & (value - 1)) == 0;
1224}
1225
1226static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
1227{
1228while (list)
1229  {
1230  /* sljit_set_label is clever enough to do nothing
1231  if either the jump or the label is NULL */
1232  sljit_set_label(list->jump, label);
1233  list = list->next;
1234  }
1235}
1236
1237static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
1238{
1239jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
1240if (list_item)
1241  {
1242  list_item->next = *list;
1243  list_item->jump = jump;
1244  *list = list_item;
1245  }
1246}
1247
1248static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
1249{
1250DEFINE_COMPILER;
1251stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1252
1253if (list_item)
1254  {
1255  list_item->type = type;
1256  list_item->data = data;
1257  list_item->start = start;
1258  list_item->leave = LABEL();
1259  list_item->next = common->stubs;
1260  common->stubs = list_item;
1261  }
1262}
1263
1264static void flush_stubs(compiler_common *common)
1265{
1266DEFINE_COMPILER;
1267stub_list* list_item = common->stubs;
1268
1269while (list_item)
1270  {
1271  JUMPHERE(list_item->start);
1272  switch(list_item->type)
1273    {
1274    case stack_alloc:
1275    add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1276    break;
1277    }
1278  JUMPTO(SLJIT_JUMP, list_item->leave);
1279  list_item = list_item->next;
1280  }
1281common->stubs = NULL;
1282}
1283
1284static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1285{
1286DEFINE_COMPILER;
1287
1288OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1289add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1290}
1291
1292static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1293{
1294/* May destroy all locals and registers except TMP2. */
1295DEFINE_COMPILER;
1296
1297OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
1298#ifdef DESTROY_REGISTERS
1299OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1300OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1301OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1302OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
1303OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
1304#endif
1305add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
1306}
1307
1308static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1309{
1310DEFINE_COMPILER;
1311OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
1312}
1313
1314static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
1315{
1316DEFINE_COMPILER;
1317struct sljit_label *loop;
1318int i;
1319/* At this point we can freely use all temporary registers. */
1320/* TMP1 returns with begin - 1. */
1321OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1322if (length < 8)
1323  {
1324  for (i = 0; i < length; i++)
1325    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
1326  }
1327else
1328  {
1329  GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1330  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1331  loop = LABEL();
1332  OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
1333  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1334  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1335  }
1336}
1337
1338static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1339{
1340DEFINE_COMPILER;
1341struct sljit_label *loop;
1342struct sljit_jump *earlyexit;
1343
1344/* At this point we can freely use all registers. */
1345OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1346OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1347
1348OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1349if (common->mark_ptr != 0)
1350  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1351OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1352if (common->mark_ptr != 0)
1353  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1354OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1355OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1356GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1357/* Unlikely, but possible */
1358earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1359loop = LABEL();
1360OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1361OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1362/* Copy the integer value to the output buffer */
1363#ifdef COMPILE_PCRE16
1364OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1365#endif
1366OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1367OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1368JUMPTO(SLJIT_C_NOT_ZERO, loop);
1369JUMPHERE(earlyexit);
1370
1371/* Calculate the return value, which is the maximum ovector value. */
1372if (topbracket > 1)
1373  {
1374  GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1375  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1376
1377  /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1378  loop = LABEL();
1379  OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1380  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1381  CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1382  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1383  }
1384else
1385  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1386}
1387
1388static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1389{
1390DEFINE_COMPILER;
1391
1392SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1393SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1394
1395OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1396OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1397OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1398CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1399
1400/* Store match begin and end. */
1401OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1402OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1403OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1404OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1405#ifdef COMPILE_PCRE16
1406OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1407#endif
1408OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1409
1410OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1411#ifdef COMPILE_PCRE16
1412OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1413#endif
1414OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1415
1416JUMPTO(SLJIT_JUMP, leave);
1417}
1418
1419static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1420{
1421/* May destroy TMP1. */
1422DEFINE_COMPILER;
1423struct sljit_jump *jump;
1424
1425if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1426  {
1427  /* The value of -1 must be kept for start_used_ptr! */
1428  OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1429  /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1430  is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1431  jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1432  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1433  JUMPHERE(jump);
1434  }
1435else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1436  {
1437  jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1438  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1439  JUMPHERE(jump);
1440  }
1441}
1442
1443static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1444{
1445/* Detects if the character has an othercase. */
1446unsigned int c;
1447
1448#ifdef SUPPORT_UTF
1449if (common->utf)
1450  {
1451  GETCHAR(c, cc);
1452  if (c > 127)
1453    {
1454#ifdef SUPPORT_UCP
1455    return c != UCD_OTHERCASE(c);
1456#else
1457    return FALSE;
1458#endif
1459    }
1460#ifndef COMPILE_PCRE8
1461  return common->fcc[c] != c;
1462#endif
1463  }
1464else
1465#endif
1466  c = *cc;
1467return MAX_255(c) ? common->fcc[c] != c : FALSE;
1468}
1469
1470static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
1471{
1472/* Returns with the othercase. */
1473#ifdef SUPPORT_UTF
1474if (common->utf && c > 127)
1475  {
1476#ifdef SUPPORT_UCP
1477  return UCD_OTHERCASE(c);
1478#else
1479  return c;
1480#endif
1481  }
1482#endif
1483return TABLE_GET(c, common->fcc, c);
1484}
1485
1486static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
1487{
1488/* Detects if the character and its othercase has only 1 bit difference. */
1489unsigned int c, oc, bit;
1490#if defined SUPPORT_UTF && defined COMPILE_PCRE8
1491int n;
1492#endif
1493
1494#ifdef SUPPORT_UTF
1495if (common->utf)
1496  {
1497  GETCHAR(c, cc);
1498  if (c <= 127)
1499    oc = common->fcc[c];
1500  else
1501    {
1502#ifdef SUPPORT_UCP
1503    oc = UCD_OTHERCASE(c);
1504#else
1505    oc = c;
1506#endif
1507    }
1508  }
1509else
1510  {
1511  c = *cc;
1512  oc = TABLE_GET(c, common->fcc, c);
1513  }
1514#else
1515c = *cc;
1516oc = TABLE_GET(c, common->fcc, c);
1517#endif
1518
1519SLJIT_ASSERT(c != oc);
1520
1521bit = c ^ oc;
1522/* Optimized for English alphabet. */
1523if (c <= 127 && bit == 0x20)
1524  return (0 << 8) | 0x20;
1525
1526/* Since c != oc, they must have at least 1 bit difference. */
1527if (!ispowerof2(bit))
1528  return 0;
1529
1530#ifdef COMPILE_PCRE8
1531
1532#ifdef SUPPORT_UTF
1533if (common->utf && c > 127)
1534  {
1535  n = GET_EXTRALEN(*cc);
1536  while ((bit & 0x3f) == 0)
1537    {
1538    n--;
1539    bit >>= 6;
1540    }
1541  return (n << 8) | bit;
1542  }
1543#endif /* SUPPORT_UTF */
1544return (0 << 8) | bit;
1545
1546#else /* COMPILE_PCRE8 */
1547
1548#ifdef COMPILE_PCRE16
1549#ifdef SUPPORT_UTF
1550if (common->utf && c > 65535)
1551  {
1552  if (bit >= (1 << 10))
1553    bit >>= 10;
1554  else
1555    return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1556  }
1557#endif /* SUPPORT_UTF */
1558return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1559#endif /* COMPILE_PCRE16 */
1560
1561#endif /* COMPILE_PCRE8 */
1562}
1563
1564static void check_partial(compiler_common *common, BOOL force)
1565{
1566/* Checks whether a partial matching is occured. Does not modify registers. */
1567DEFINE_COMPILER;
1568struct sljit_jump *jump = NULL;
1569
1570SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1571
1572if (common->mode == JIT_COMPILE)
1573  return;
1574
1575if (!force)
1576  jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1577else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1578  jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1579
1580if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1581  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1582else
1583  {
1584  if (common->partialmatchlabel != NULL)
1585    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1586  else
1587    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1588  }
1589
1590if (jump != NULL)
1591  JUMPHERE(jump);
1592}
1593
1594static struct sljit_jump *check_str_end(compiler_common *common)
1595{
1596/* Does not affect registers. Usually used in a tight spot. */
1597DEFINE_COMPILER;
1598struct sljit_jump *jump;
1599struct sljit_jump *nohit;
1600struct sljit_jump *return_value;
1601
1602if (common->mode == JIT_COMPILE)
1603  return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1604
1605jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1606if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1607  {
1608  nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1609  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1610  JUMPHERE(nohit);
1611  return_value = JUMP(SLJIT_JUMP);
1612  }
1613else
1614  {
1615  return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1616  if (common->partialmatchlabel != NULL)
1617    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1618  else
1619    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1620  }
1621JUMPHERE(jump);
1622return return_value;
1623}
1624
1625static void detect_partial_match(compiler_common *common, jump_list **backtracks)
1626{
1627DEFINE_COMPILER;
1628struct sljit_jump *jump;
1629
1630if (common->mode == JIT_COMPILE)
1631  {
1632  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1633  return;
1634  }
1635
1636/* Partial matching mode. */
1637jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1638add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1639if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1640  {
1641  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1642  add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
1643  }
1644else
1645  {
1646  if (common->partialmatchlabel != NULL)
1647    JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1648  else
1649    add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1650  }
1651JUMPHERE(jump);
1652}
1653
1654static void read_char(compiler_common *common)
1655{
1656/* Reads the character into TMP1, updates STR_PTR.
1657Does not check STR_END. TMP2 Destroyed. */
1658DEFINE_COMPILER;
1659#ifdef SUPPORT_UTF
1660struct sljit_jump *jump;
1661#endif
1662
1663OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1664#ifdef SUPPORT_UTF
1665if (common->utf)
1666  {
1667#ifdef COMPILE_PCRE8
1668  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1669#else
1670#ifdef COMPILE_PCRE16
1671  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1672#endif
1673#endif /* COMPILE_PCRE8 */
1674  add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1675  JUMPHERE(jump);
1676  }
1677#endif
1678OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1679}
1680
1681static void peek_char(compiler_common *common)
1682{
1683/* Reads the character into TMP1, keeps STR_PTR.
1684Does not check STR_END. TMP2 Destroyed. */
1685DEFINE_COMPILER;
1686#ifdef SUPPORT_UTF
1687struct sljit_jump *jump;
1688#endif
1689
1690OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1691#ifdef SUPPORT_UTF
1692if (common->utf)
1693  {
1694#ifdef COMPILE_PCRE8
1695  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1696#else
1697#ifdef COMPILE_PCRE16
1698  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1699#endif
1700#endif /* COMPILE_PCRE8 */
1701  add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1702  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1703  JUMPHERE(jump);
1704  }
1705#endif
1706}
1707
1708static void read_char8_type(compiler_common *common)
1709{
1710/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
1711DEFINE_COMPILER;
1712#if defined SUPPORT_UTF || defined COMPILE_PCRE16
1713struct sljit_jump *jump;
1714#endif
1715
1716#ifdef SUPPORT_UTF
1717if (common->utf)
1718  {
1719  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1720  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1721#ifdef COMPILE_PCRE8
1722  /* This can be an extra read in some situations, but hopefully
1723  it is needed in most cases. */
1724  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1725  jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1726  add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1727  JUMPHERE(jump);
1728#else
1729#ifdef COMPILE_PCRE16
1730  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1731  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1732  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1733  JUMPHERE(jump);
1734  /* Skip low surrogate if necessary. */
1735  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1736  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1737  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1738  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1739  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1740#endif
1741#endif /* COMPILE_PCRE8 */
1742  return;
1743  }
1744#endif
1745OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1746OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1747#ifdef COMPILE_PCRE16
1748/* The ctypes array contains only 256 values. */
1749OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1750jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1751#endif
1752OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1753#ifdef COMPILE_PCRE16
1754JUMPHERE(jump);
1755#endif
1756}
1757
1758static void skip_char_back(compiler_common *common)
1759{
1760/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
1761DEFINE_COMPILER;
1762#if defined SUPPORT_UTF && defined COMPILE_PCRE8
1763struct sljit_label *label;
1764
1765if (common->utf)
1766  {
1767  label = LABEL();
1768  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1769  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1770  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1771  CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1772  return;
1773  }
1774#endif
1775#if defined SUPPORT_UTF && defined COMPILE_PCRE16
1776if (common->utf)
1777  {
1778  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1779  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1780  /* Skip low surrogate if necessary. */
1781  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1782  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1783  COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1784  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1785  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1786  return;
1787  }
1788#endif
1789OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1790}
1791
1792static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
1793{
1794/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
1795DEFINE_COMPILER;
1796
1797if (nltype == NLTYPE_ANY)
1798  {
1799  add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1800  add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
1801  }
1802else if (nltype == NLTYPE_ANYCRLF)
1803  {
1804  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
1805  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1806  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
1807  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1808  add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
1809  }
1810else
1811  {
1812  SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1813  add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
1814  }
1815}
1816
1817#ifdef SUPPORT_UTF
1818
1819#ifdef COMPILE_PCRE8
1820static void do_utfreadchar(compiler_common *common)
1821{
1822/* Fast decoding a UTF-8 character. TMP1 contains the first byte
1823of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
1824DEFINE_COMPILER;
1825struct sljit_jump *jump;
1826
1827sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1828/* Searching for the first zero. */
1829OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
1830jump = JUMP(SLJIT_C_NOT_ZERO);
1831/* Two byte sequence. */
1832OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1833OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1834OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1835OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1836OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1837OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1838OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1839sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1840JUMPHERE(jump);
1841
1842OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
1843jump = JUMP(SLJIT_C_NOT_ZERO);
1844/* Three byte sequence. */
1845OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1846OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1847OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1848OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1849OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1850OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1851OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1852OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1853OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1854OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1855OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1856sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1857JUMPHERE(jump);
1858
1859/* Four byte sequence. */
1860OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1861OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1862OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1863OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1864OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1865OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1866OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1867OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1868OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1869OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1870OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1871OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1872OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1873OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1874OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1875sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1876}
1877
1878static void do_utfreadtype8(compiler_common *common)
1879{
1880/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1881of the character (>= 0xc0). Return value in TMP1. */
1882DEFINE_COMPILER;
1883struct sljit_jump *jump;
1884struct sljit_jump *compare;
1885
1886sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1887
1888OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
1889jump = JUMP(SLJIT_C_NOT_ZERO);
1890/* Two byte sequence. */
1891OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1892OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1893OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1894OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1895OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
1896OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
1897compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1898OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1899sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1900
1901JUMPHERE(compare);
1902OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1903sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1904JUMPHERE(jump);
1905
1906/* We only have types for characters less than 256. */
1907OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
1908OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1909OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1910sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1911}
1912
1913#else /* COMPILE_PCRE8 */
1914
1915#ifdef COMPILE_PCRE16
1916static void do_utfreadchar(compiler_common *common)
1917{
1918/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1919of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1920DEFINE_COMPILER;
1921struct sljit_jump *jump;
1922
1923sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1924jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1925/* Do nothing, only return. */
1926sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1927
1928JUMPHERE(jump);
1929/* Combine two 16 bit characters. */
1930OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1931OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1932OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1933OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1934OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1935OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1936OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1937OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1938sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1939}
1940#endif /* COMPILE_PCRE16 */
1941
1942#endif /* COMPILE_PCRE8 */
1943
1944#endif /* SUPPORT_UTF */
1945
1946#ifdef SUPPORT_UCP
1947
1948/* UCD_BLOCK_SIZE must be 128 (see the assert below). */
1949#define UCD_BLOCK_MASK 127
1950#define UCD_BLOCK_SHIFT 7
1951
1952static void do_getucd(compiler_common *common)
1953{
1954/* Search the UCD record for the character comes in TMP1.
1955Returns chartype in TMP1 and UCD offset in TMP2. */
1956DEFINE_COMPILER;
1957
1958SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
1959
1960sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1961OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1962OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
1963OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1964OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1965OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1966OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1967OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1968OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
1969OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1970sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1971}
1972#endif
1973
1974static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
1975{
1976DEFINE_COMPILER;
1977struct sljit_label *mainloop;
1978struct sljit_label *newlinelabel = NULL;
1979struct sljit_jump *start;
1980struct sljit_jump *end = NULL;
1981struct sljit_jump *nl = NULL;
1982#ifdef SUPPORT_UTF
1983struct sljit_jump *singlechar;
1984#endif
1985jump_list *newline = NULL;
1986BOOL newlinecheck = FALSE;
1987BOOL readuchar = FALSE;
1988
1989if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1990    common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
1991  newlinecheck = TRUE;
1992
1993if (firstline)
1994  {
1995  /* Search for the end of the first line. */
1996  SLJIT_ASSERT(common->first_line_end != 0);
1997  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1998  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
1999
2000  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2001    {
2002    mainloop = LABEL();
2003    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2004    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2005    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2006    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2007    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2008    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2009    OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2010    }
2011  else
2012    {
2013    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2014    mainloop = LABEL();
2015    /* Continual stores does not cause data dependency. */
2016    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2017    read_char(common);
2018    check_newlinechar(common, common->nltype, &newline, TRUE);
2019    CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2020    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2021    set_jumps(newline, LABEL());
2022    }
2023
2024  JUMPHERE(end);
2025  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2026  }
2027
2028start = JUMP(SLJIT_JUMP);
2029
2030if (newlinecheck)
2031  {
2032  newlinelabel = LABEL();
2033  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2034  end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2035  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2036  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2037  COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2038#ifdef COMPILE_PCRE16
2039  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2040#endif
2041  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2042  nl = JUMP(SLJIT_JUMP);
2043  }
2044
2045mainloop = LABEL();
2046
2047/* Increasing the STR_PTR here requires one less jump in the most common case. */
2048#ifdef SUPPORT_UTF
2049if (common->utf) readuchar = TRUE;
2050#endif
2051if (newlinecheck) readuchar = TRUE;
2052
2053if (readuchar)
2054  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2055
2056if (newlinecheck)
2057  CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2058
2059OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2060#if defined SUPPORT_UTF && defined COMPILE_PCRE8
2061if (common->utf)
2062  {
2063  singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2064  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2065  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2066  JUMPHERE(singlechar);
2067  }
2068#endif
2069#if defined SUPPORT_UTF && defined COMPILE_PCRE16
2070if (common->utf)
2071  {
2072  singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2073  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2074  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2075  COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2076  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2077  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2078  JUMPHERE(singlechar);
2079  }
2080#endif
2081JUMPHERE(start);
2082
2083if (newlinecheck)
2084  {
2085  JUMPHERE(end);
2086  JUMPHERE(nl);
2087  }
2088
2089return mainloop;
2090}
2091
2092static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2093{
2094DEFINE_COMPILER;
2095struct sljit_label *start;
2096struct sljit_jump *leave;
2097struct sljit_jump *found;
2098pcre_uchar oc, bit;
2099
2100if (firstline)
2101  {
2102  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2103  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2104  }
2105
2106start = LABEL();
2107leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2108OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2109
2110oc = first_char;
2111if (caseless)
2112  {
2113  oc = TABLE_GET(first_char, common->fcc, first_char);
2114#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2115  if (first_char > 127 && common->utf)
2116    oc = UCD_OTHERCASE(first_char);
2117#endif
2118  }
2119if (first_char == oc)
2120  found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2121else
2122  {
2123  bit = first_char ^ oc;
2124  if (ispowerof2(bit))
2125    {
2126    OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2127    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2128    }
2129  else
2130    {
2131    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
2132    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2133    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
2134    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2135    found = JUMP(SLJIT_C_NOT_ZERO);
2136    }
2137  }
2138
2139OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2140#if defined SUPPORT_UTF && defined COMPILE_PCRE8
2141if (common->utf)
2142  {
2143  CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2144  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2145  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2146  }
2147#endif
2148#if defined SUPPORT_UTF && defined COMPILE_PCRE16
2149if (common->utf)
2150  {
2151  CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2152  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2153  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2154  COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2155  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2156  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2157  }
2158#endif
2159JUMPTO(SLJIT_JUMP, start);
2160JUMPHERE(found);
2161JUMPHERE(leave);
2162
2163if (firstline)
2164  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2165}
2166
2167static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
2168{
2169DEFINE_COMPILER;
2170struct sljit_label *loop;
2171struct sljit_jump *lastchar;
2172struct sljit_jump *firstchar;
2173struct sljit_jump *leave;
2174struct sljit_jump *foundcr = NULL;
2175struct sljit_jump *notfoundnl;
2176jump_list *newline = NULL;
2177
2178if (firstline)
2179  {
2180  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2181  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2182  }
2183
2184if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2185  {
2186  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2187  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2188  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
2189  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2190  firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2191
2192  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2193  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2194  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2195#ifdef COMPILE_PCRE16
2196  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2197#endif
2198  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2199
2200  loop = LABEL();
2201  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2202  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2203  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2204  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2205  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2206  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2207
2208  JUMPHERE(leave);
2209  JUMPHERE(firstchar);
2210  JUMPHERE(lastchar);
2211
2212  if (firstline)
2213    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2214  return;
2215  }
2216
2217OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2218OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
2219firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2220skip_char_back(common);
2221
2222loop = LABEL();
2223read_char(common);
2224lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2225if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2226  foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
2227check_newlinechar(common, common->nltype, &newline, FALSE);
2228set_jumps(newline, loop);
2229
2230if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2231  {
2232  leave = JUMP(SLJIT_JUMP);
2233  JUMPHERE(foundcr);
2234  notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2235  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2236  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2237  COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2238#ifdef COMPILE_PCRE16
2239  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2240#endif
2241  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2242  JUMPHERE(notfoundnl);
2243  JUMPHERE(leave);
2244  }
2245JUMPHERE(lastchar);
2246JUMPHERE(firstchar);
2247
2248if (firstline)
2249  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2250}
2251
2252static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2253{
2254DEFINE_COMPILER;
2255struct sljit_label *start;
2256struct sljit_jump *leave;
2257struct sljit_jump *found;
2258#ifndef COMPILE_PCRE8
2259struct sljit_jump *jump;
2260#endif
2261
2262if (firstline)
2263  {
2264  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2265  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2266  }
2267
2268start = LABEL();
2269leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2270OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2271#ifdef SUPPORT_UTF
2272if (common->utf)
2273  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2274#endif
2275#ifndef COMPILE_PCRE8
2276jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2277OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2278JUMPHERE(jump);
2279#endif
2280OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2281OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2282OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2283OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2284OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2285found = JUMP(SLJIT_C_NOT_ZERO);
2286
2287#ifdef SUPPORT_UTF
2288if (common->utf)
2289  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2290#endif
2291OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2292#if defined SUPPORT_UTF && defined COMPILE_PCRE8
2293if (common->utf)
2294  {
2295  CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2296  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2297  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2298  }
2299#endif
2300#if defined SUPPORT_UTF && defined COMPILE_PCRE16
2301if (common->utf)
2302  {
2303  CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2304  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2305  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2306  COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2307  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2308  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2309  }
2310#endif
2311JUMPTO(SLJIT_JUMP, start);
2312JUMPHERE(found);
2313JUMPHERE(leave);
2314
2315if (firstline)
2316  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2317}
2318
2319static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
2320{
2321DEFINE_COMPILER;
2322struct sljit_label *loop;
2323struct sljit_jump *toolong;
2324struct sljit_jump *alreadyfound;
2325struct sljit_jump *found;
2326struct sljit_jump *foundoc = NULL;
2327struct sljit_jump *notfound;
2328pcre_uchar oc, bit;
2329
2330SLJIT_ASSERT(common->req_char_ptr != 0);
2331OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2332OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2333toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2334alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2335
2336if (has_firstchar)
2337  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2338else
2339  OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2340
2341loop = LABEL();
2342notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2343
2344OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2345oc = req_char;
2346if (caseless)
2347  {
2348  oc = TABLE_GET(req_char, common->fcc, req_char);
2349#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2350  if (req_char > 127 && common->utf)
2351    oc = UCD_OTHERCASE(req_char);
2352#endif
2353  }
2354if (req_char == oc)
2355  found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2356else
2357  {
2358  bit = req_char ^ oc;
2359  if (ispowerof2(bit))
2360    {
2361    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2362    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2363    }
2364  else
2365    {
2366    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2367    foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2368    }
2369  }
2370OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2371JUMPTO(SLJIT_JUMP, loop);
2372
2373JUMPHERE(found);
2374if (foundoc)
2375  JUMPHERE(foundoc);
2376OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2377JUMPHERE(alreadyfound);
2378JUMPHERE(toolong);
2379return notfound;
2380}
2381
2382static void do_revertframes(compiler_common *common)
2383{
2384DEFINE_COMPILER;
2385struct sljit_jump *jump;
2386struct sljit_label *mainloop;
2387
2388sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2389OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2390GET_LOCAL_BASE(TMP3, 0, 0);
2391
2392/* Drop frames until we reach STACK_TOP. */
2393mainloop = LABEL();
2394OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2395jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2396OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2397OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2398OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
2399OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
2400JUMPTO(SLJIT_JUMP, mainloop);
2401
2402JUMPHERE(jump);
2403jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2404/* End of dropping frames. */
2405sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2406
2407JUMPHERE(jump);
2408jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2409/* Set string begin. */
2410OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2411OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2412OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
2413JUMPTO(SLJIT_JUMP, mainloop);
2414
2415JUMPHERE(jump);
2416if (common->mark_ptr != 0)
2417  {
2418  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2419  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2420  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2421  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2422  JUMPTO(SLJIT_JUMP, mainloop);
2423
2424  JUMPHERE(jump);
2425  }
2426
2427/* Unknown command. */
2428OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2429JUMPTO(SLJIT_JUMP, mainloop);
2430}
2431
2432static void check_wordboundary(compiler_common *common)
2433{
2434DEFINE_COMPILER;
2435struct sljit_jump *skipread;
2436#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2437struct sljit_jump *jump;
2438#endif
2439
2440SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2441
2442sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2443/* Get type of the previous char, and put it to LOCALS1. */
2444OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2445OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2446OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2447skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2448skip_char_back(common);
2449check_start_used_ptr(common);
2450read_char(common);
2451
2452/* Testing char type. */
2453#ifdef SUPPORT_UCP
2454if (common->use_ucp)
2455  {
2456  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2457  jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
2458  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2459  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
2460  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2461  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2462  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
2463  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2464  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2465  JUMPHERE(jump);
2466  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
2467  }
2468else
2469#endif
2470  {
2471#ifndef COMPILE_PCRE8
2472  jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2473#elif defined SUPPORT_UTF
2474  /* Here LOCALS1 has already been zeroed. */
2475  jump = NULL;
2476  if (common->utf)
2477    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2478#endif /* COMPILE_PCRE8 */
2479  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2480  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2481  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2482  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2483#ifndef COMPILE_PCRE8
2484  JUMPHERE(jump);
2485#elif defined SUPPORT_UTF
2486  if (jump != NULL)
2487    JUMPHERE(jump);
2488#endif /* COMPILE_PCRE8 */
2489  }
2490JUMPHERE(skipread);
2491
2492OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2493skipread = check_str_end(common);
2494peek_char(common);
2495
2496/* Testing char type. This is a code duplication. */
2497#ifdef SUPPORT_UCP
2498if (common->use_ucp)
2499  {
2500  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2501  jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
2502  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2503  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
2504  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2505  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2506  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
2507  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2508  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2509  JUMPHERE(jump);
2510  }
2511else
2512#endif
2513  {
2514#ifndef COMPILE_PCRE8
2515  /* TMP2 may be destroyed by peek_char. */
2516  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2517  jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2518#elif defined SUPPORT_UTF
2519  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2520  jump = NULL;
2521  if (common->utf)
2522    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2523#endif
2524  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2525  OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2526  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2527#ifndef COMPILE_PCRE8
2528  JUMPHERE(jump);
2529#elif defined SUPPORT_UTF
2530  if (jump != NULL)
2531    JUMPHERE(jump);
2532#endif /* COMPILE_PCRE8 */
2533  }
2534JUMPHERE(skipread);
2535
2536OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2537sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2538}
2539
2540static void check_anynewline(compiler_common *common)
2541{
2542/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2543DEFINE_COMPILER;
2544
2545sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2546
2547OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2548OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
2549COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2550OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
2551#if defined SUPPORT_UTF || defined COMPILE_PCRE16
2552#ifdef COMPILE_PCRE8
2553if (common->utf)
2554  {
2555#endif
2556  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2557  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2558  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
2559#ifdef COMPILE_PCRE8
2560  }
2561#endif
2562#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2563COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2564sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2565}
2566
2567static void check_hspace(compiler_common *common)
2568{
2569/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2570DEFINE_COMPILER;
2571
2572sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2573
2574OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
2575COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2576OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2577COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2578OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
2579#if defined SUPPORT_UTF || defined COMPILE_PCRE16
2580#ifdef COMPILE_PCRE8
2581if (common->utf)
2582  {
2583#endif
2584  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2585  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
2586  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2587  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
2588  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2589  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
2590  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
2591  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2592  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
2593  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2594  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
2595  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2596  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
2597#ifdef COMPILE_PCRE8
2598  }
2599#endif
2600#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2601COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2602
2603sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2604}
2605
2606static void check_vspace(compiler_common *common)
2607{
2608/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2609DEFINE_COMPILER;
2610
2611sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2612
2613OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2614OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
2615COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2616OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
2617#if defined SUPPORT_UTF || defined COMPILE_PCRE16
2618#ifdef COMPILE_PCRE8
2619if (common->utf)
2620  {
2621#endif
2622  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2623  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2624  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
2625#ifdef COMPILE_PCRE8
2626  }
2627#endif
2628#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2629COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2630
2631sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2632}
2633
2634#define CHAR1 STR_END
2635#define CHAR2 STACK_TOP
2636
2637static void do_casefulcmp(compiler_common *common)
2638{
2639DEFINE_COMPILER;
2640struct sljit_jump *jump;
2641struct sljit_label *label;
2642
2643sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2644OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2645OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2646OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2647OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2648OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2649
2650label = LABEL();
2651OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2652OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2653jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2654OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2655JUMPTO(SLJIT_C_NOT_ZERO, label);
2656
2657JUMPHERE(jump);
2658OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2659OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2660OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2661sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2662}
2663
2664#define LCC_TABLE STACK_LIMIT
2665
2666static void do_caselesscmp(compiler_common *common)
2667{
2668DEFINE_COMPILER;
2669struct sljit_jump *jump;
2670struct sljit_label *label;
2671
2672sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2673OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2674
2675OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2676OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2677OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2678OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2679OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2680OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2681
2682label = LABEL();
2683OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2684OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2685#ifndef COMPILE_PCRE8
2686jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2687#endif
2688OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2689#ifndef COMPILE_PCRE8
2690JUMPHERE(jump);
2691jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2692#endif
2693OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2694#ifndef COMPILE_PCRE8
2695JUMPHERE(jump);
2696#endif
2697jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2698OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2699JUMPTO(SLJIT_C_NOT_ZERO, label);
2700
2701JUMPHERE(jump);
2702OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2703OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2704OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2705OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2706sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2707}
2708
2709#undef LCC_TABLE
2710#undef CHAR1
2711#undef CHAR2
2712
2713#if defined SUPPORT_UTF && defined SUPPORT_UCP
2714
2715static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
2716{
2717/* This function would be ineffective to do in JIT level. */
2718int c1, c2;
2719const pcre_uchar *src2 = args->uchar_ptr;
2720const pcre_uchar *end2 = args->end;
2721
2722while (src1 < end1)
2723  {
2724  if (src2 >= end2)
2725    return (pcre_uchar*)1;
2726  GETCHARINC(c1, src1);
2727  GETCHARINC(c2, src2);
2728  if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2729  }
2730return src2;
2731}
2732
2733#endif /* SUPPORT_UTF && SUPPORT_UCP */
2734
2735static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
2736    compare_context* context, jump_list **backtracks)
2737{
2738DEFINE_COMPILER;
2739unsigned int othercasebit = 0;
2740pcre_uchar *othercasechar = NULL;
2741#ifdef SUPPORT_UTF
2742int utflength;
2743#endif
2744
2745if (caseless && char_has_othercase(common, cc))
2746  {
2747  othercasebit = char_get_othercase_bit(common, cc);
2748  SLJIT_ASSERT(othercasebit);
2749  /* Extracting bit difference info. */
2750#ifdef COMPILE_PCRE8
2751  othercasechar = cc + (othercasebit >> 8);
2752  othercasebit &= 0xff;
2753#else
2754#ifdef COMPILE_PCRE16
2755  othercasechar = cc + (othercasebit >> 9);
2756  if ((othercasebit & 0x100) != 0)
2757    othercasebit = (othercasebit & 0xff) << 8;
2758  else
2759    othercasebit &= 0xff;
2760#endif
2761#endif
2762  }
2763
2764if (context->sourcereg == -1)
2765  {
2766#ifdef COMPILE_PCRE8
2767#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2768  if (context->length >= 4)
2769    OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2770  else if (context->length >= 2)
2771    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2772  else
2773#endif
2774    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2775#else
2776#ifdef COMPILE_PCRE16
2777#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2778  if (context->length >= 4)
2779    OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2780  else
2781#endif
2782    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2783#endif
2784#endif /* COMPILE_PCRE8 */
2785  context->sourcereg = TMP2;
2786  }
2787
2788#ifdef SUPPORT_UTF
2789utflength = 1;
2790if (common->utf && HAS_EXTRALEN(*cc))
2791  utflength += GET_EXTRALEN(*cc);
2792
2793do
2794  {
2795#endif
2796
2797  context->length -= IN_UCHARS(1);
2798#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2799
2800  /* Unaligned read is supported. */
2801  if (othercasebit != 0 && othercasechar == cc)
2802    {
2803    context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2804    context->oc.asuchars[context->ucharptr] = othercasebit;
2805    }
2806  else
2807    {
2808    context->c.asuchars[context->ucharptr] = *cc;
2809    context->oc.asuchars[context->ucharptr] = 0;
2810    }
2811  context->ucharptr++;
2812
2813#ifdef COMPILE_PCRE8
2814  if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2815#else
2816  if (context->ucharptr >= 2 || context->length == 0)
2817#endif
2818    {
2819    if (context->length >= 4)
2820      OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2821#ifdef COMPILE_PCRE8
2822    else if (context->length >= 2)
2823      OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2824    else if (context->length >= 1)
2825      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2826#else
2827    else if (context->length >= 2)
2828      OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2829#endif
2830    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2831
2832    switch(context->ucharptr)
2833      {
2834      case 4 / sizeof(pcre_uchar):
2835      if (context->oc.asint != 0)
2836        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
2837      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
2838      break;
2839
2840      case 2 / sizeof(pcre_uchar):
2841      if (context->oc.asushort != 0)
2842        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
2843      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
2844      break;
2845
2846#ifdef COMPILE_PCRE8
2847      case 1:
2848      if (context->oc.asbyte != 0)
2849        OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
2850      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
2851      break;
2852#endif
2853
2854      default:
2855      SLJIT_ASSERT_STOP();
2856      break;
2857      }
2858    context->ucharptr = 0;
2859    }
2860
2861#else
2862
2863  /* Unaligned read is unsupported. */
2864#ifdef COMPILE_PCRE8
2865  if (context->length > 0)
2866    OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2867#else
2868  if (context->length > 0)
2869    OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2870#endif
2871  context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2872
2873  if (othercasebit != 0 && othercasechar == cc)
2874    {
2875    OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2876    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
2877    }
2878  else
2879    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
2880
2881#endif
2882
2883  cc++;
2884#ifdef SUPPORT_UTF
2885  utflength--;
2886  }
2887while (utflength > 0);
2888#endif
2889
2890return cc;
2891}
2892
2893#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2894
2895#define SET_TYPE_OFFSET(value) \
2896  if ((value) != typeoffset) \
2897    { \
2898    if ((value) > typeoffset) \
2899      OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
2900    else \
2901      OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
2902    } \
2903  typeoffset = (value);
2904
2905#define SET_CHAR_OFFSET(value) \
2906  if ((value) != charoffset) \
2907    { \
2908    if ((value) > charoffset) \
2909      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
2910    else \
2911      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
2912    } \
2913  charoffset = (value);
2914
2915static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
2916{
2917DEFINE_COMPILER;
2918jump_list *found = NULL;
2919jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
2920unsigned int c;
2921int compares;
2922struct sljit_jump *jump = NULL;
2923pcre_uchar *ccbegin;
2924#ifdef SUPPORT_UCP
2925BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2926BOOL charsaved = FALSE;
2927int typereg = TMP1, scriptreg = TMP1;
2928unsigned int typeoffset;
2929#endif
2930int invertcmp, numberofcmps;
2931unsigned int charoffset;
2932
2933/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2934detect_partial_match(common, backtracks);
2935read_char(common);
2936
2937if ((*cc++ & XCL_MAP) != 0)
2938  {
2939  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2940#ifndef COMPILE_PCRE8
2941  jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2942#elif defined SUPPORT_UTF
2943  if (common->utf)
2944    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2945#endif
2946
2947  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2948  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2949  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
2950  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2951  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2952  add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2953
2954#ifndef COMPILE_PCRE8
2955  JUMPHERE(jump);
2956#elif defined SUPPORT_UTF
2957  if (common->utf)
2958    JUMPHERE(jump);
2959#endif
2960  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2961#ifdef SUPPORT_UCP
2962  charsaved = TRUE;
2963#endif
2964  cc += 32 / sizeof(pcre_uchar);
2965  }
2966
2967/* Scanning the necessary info. */
2968ccbegin = cc;
2969compares = 0;
2970while (*cc != XCL_END)
2971  {
2972  compares++;
2973  if (*cc == XCL_SINGLE)
2974    {
2975    cc += 2;
2976#ifdef SUPPORT_UTF
2977    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2978#endif
2979#ifdef SUPPORT_UCP
2980    needschar = TRUE;
2981#endif
2982    }
2983  else if (*cc == XCL_RANGE)
2984    {
2985    cc += 2;
2986#ifdef SUPPORT_UTF
2987    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2988#endif
2989    cc++;
2990#ifdef SUPPORT_UTF
2991    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2992#endif
2993#ifdef SUPPORT_UCP
2994    needschar = TRUE;
2995#endif
2996    }
2997#ifdef SUPPORT_UCP
2998  else
2999    {
3000    SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
3001    cc++;
3002    switch(*cc)
3003      {
3004      case PT_ANY:
3005      break;
3006
3007      case PT_LAMP:
3008      case PT_GC:
3009      case PT_PC:
3010      case PT_ALNUM:
3011      needstype = TRUE;
3012      break;
3013
3014      case PT_SC:
3015      needsscript = TRUE;
3016      break;
3017
3018      case PT_SPACE:
3019      case PT_PXSPACE:
3020      case PT_WORD:
3021      needstype = TRUE;
3022      needschar = TRUE;
3023      break;
3024
3025      default:
3026      SLJIT_ASSERT_STOP();
3027      break;
3028      }
3029    cc += 2;
3030    }
3031#endif
3032  }
3033
3034#ifdef SUPPORT_UCP
3035/* Simple register allocation. TMP1 is preferred if possible. */
3036if (needstype || needsscript)
3037  {
3038  if (needschar && !charsaved)
3039    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3040  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3041  if (needschar)
3042    {
3043    if (needstype)
3044      {
3045      OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
3046      typereg = RETURN_ADDR;
3047      }
3048
3049    if (needsscript)
3050      scriptreg = TMP3;
3051    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3052    }
3053  else if (needstype && needsscript)
3054    scriptreg = TMP3;
3055  /* In all other cases only one of them was specified, and that can goes to TMP1. */
3056
3057  if (needsscript)
3058    {
3059    if (scriptreg == TMP1)
3060      {
3061      OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3062      OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3063      }
3064    else
3065      {
3066      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3067      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3068      OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3069      }
3070    }
3071  }
3072#endif
3073
3074/* Generating code. */
3075cc = ccbegin;
3076charoffset = 0;
3077numberofcmps = 0;
3078#ifdef SUPPORT_UCP
3079typeoffset = 0;
3080#endif
3081
3082while (*cc != XCL_END)
3083  {
3084  compares--;
3085  invertcmp = (compares == 0 && list != backtracks);
3086  jump = NULL;
3087
3088  if (*cc == XCL_SINGLE)
3089    {
3090    cc ++;
3091#ifdef SUPPORT_UTF
3092    if (common->utf)
3093      {
3094      GETCHARINC(c, cc);
3095      }
3096    else
3097#endif
3098      c = *cc++;
3099
3100    if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3101      {
3102      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3103      COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3104      numberofcmps++;
3105      }
3106    else if (numberofcmps > 0)
3107      {
3108      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3109      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3110      jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3111      numberofcmps = 0;
3112      }
3113    else
3114      {
3115      jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
3116      numberofcmps = 0;
3117      }
3118    }
3119  else if (*cc == XCL_RANGE)
3120    {
3121    cc ++;
3122#ifdef SUPPORT_UTF
3123    if (common->utf)
3124      {
3125      GETCHARINC(c, cc);
3126      }
3127    else
3128#endif
3129      c = *cc++;
3130    SET_CHAR_OFFSET(c);
3131#ifdef SUPPORT_UTF
3132    if (common->utf)
3133      {
3134      GETCHARINC(c, cc);
3135      }
3136    else
3137#endif
3138      c = *cc++;
3139    if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3140      {
3141      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3142      COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
3143      numberofcmps++;
3144      }
3145    else if (numberofcmps > 0)
3146      {
3147      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3148      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
3149      jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3150      numberofcmps = 0;
3151      }
3152    else
3153      {
3154      jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
3155      numberofcmps = 0;
3156      }
3157    }
3158#ifdef SUPPORT_UCP
3159  else
3160    {
3161    if (*cc == XCL_NOTPROP)
3162      invertcmp ^= 0x1;
3163    cc++;
3164    switch(*cc)
3165      {
3166      case PT_ANY:
3167      if (list != backtracks)
3168        {
3169        if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
3170          continue;
3171        }
3172      else if (cc[-1] == XCL_NOTPROP)
3173        continue;
3174      jump = JUMP(SLJIT_JUMP);
3175      break;
3176
3177      case PT_LAMP:
3178      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
3179      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3180      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
3181      COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3182      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
3183      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3184      jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3185      break;
3186
3187      case PT_GC:
3188      c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3189      SET_TYPE_OFFSET(c);
3190      jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
3191      break;
3192
3193      case PT_PC:
3194      jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
3195      break;
3196
3197      case PT_SC:
3198      jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
3199      break;
3200
3201      case PT_SPACE:
3202      case PT_PXSPACE:
3203      if (*cc == PT_SPACE)
3204        {
3205        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3206        jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
3207        }
3208      SET_CHAR_OFFSET(9);
3209      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
3210      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3211      if (*cc == PT_SPACE)
3212        JUMPHERE(jump);
3213
3214      SET_TYPE_OFFSET(ucp_Zl);
3215      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
3216      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
3217      jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3218      break;
3219
3220      case PT_WORD:
3221      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
3222      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3223      /* ... fall through */
3224
3225      case PT_ALNUM:
3226      SET_TYPE_OFFSET(ucp_Ll);
3227      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3228      COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
3229      SET_TYPE_OFFSET(ucp_Nd);
3230      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3231      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
3232      jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3233      break;
3234      }
3235    cc += 2;
3236    }
3237#endif
3238
3239  if (jump != NULL)
3240    add_jump(compiler, compares > 0 ? list : backtracks, jump);
3241  }
3242
3243if (found != NULL)
3244  set_jumps(found, LABEL());
3245}
3246
3247#undef SET_TYPE_OFFSET
3248#undef SET_CHAR_OFFSET
3249
3250#endif
3251
3252static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3253{
3254DEFINE_COMPILER;
3255int length;
3256unsigned int c, oc, bit;
3257compare_context context;
3258struct sljit_jump *jump[4];
3259#ifdef SUPPORT_UTF
3260struct sljit_label *label;
3261#ifdef SUPPORT_UCP
3262pcre_uchar propdata[5];
3263#endif
3264#endif
3265
3266switch(type)
3267  {
3268  case OP_SOD:
3269  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3270  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3271  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
3272  return cc;
3273
3274  case OP_SOM:
3275  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3276  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
3277  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
3278  return cc;
3279
3280  case OP_NOT_WORD_BOUNDARY:
3281  case OP_WORD_BOUNDARY:
3282  add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3283  add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3284  return cc;
3285
3286  case OP_NOT_DIGIT:
3287  case OP_DIGIT:
3288  detect_partial_match(common, backtracks);
3289  read_char8_type(common);
3290  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3291  add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3292  return cc;
3293
3294  case OP_NOT_WHITESPACE:
3295  case OP_WHITESPACE:
3296  detect_partial_match(common, backtracks);
3297  read_char8_type(common);
3298  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3299  add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3300  return cc;
3301
3302  case OP_NOT_WORDCHAR:
3303  case OP_WORDCHAR:
3304  detect_partial_match(common, backtracks);
3305  read_char8_type(common);
3306  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3307  add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3308  return cc;
3309
3310  case OP_ANY:
3311  detect_partial_match(common, backtracks);
3312  read_char(common);
3313  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3314    {
3315    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3316    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3317      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3318    else
3319      jump[1] = check_str_end(common);
3320
3321    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3322    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3323    if (jump[1] != NULL)
3324      JUMPHERE(jump[1]);
3325    JUMPHERE(jump[0]);
3326    }
3327  else
3328    check_newlinechar(common, common->nltype, backtracks, TRUE);
3329  return cc;
3330
3331  case OP_ALLANY:
3332  detect_partial_match(common, backtracks);
3333#ifdef SUPPORT_UTF
3334  if (common->utf)
3335    {
3336    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3337    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3338#ifdef COMPILE_PCRE8
3339    jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3340    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3341    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3342#else /* COMPILE_PCRE8 */
3343#ifdef COMPILE_PCRE16
3344    jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3345    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3346    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3347    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3348    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3349    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3350#endif /* COMPILE_PCRE16 */
3351#endif /* COMPILE_PCRE8 */
3352    JUMPHERE(jump[0]);
3353    return cc;
3354    }
3355#endif
3356  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3357  return cc;
3358
3359  case OP_ANYBYTE:
3360  detect_partial_match(common, backtracks);
3361  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3362  return cc;
3363
3364#ifdef SUPPORT_UTF
3365#ifdef SUPPORT_UCP
3366  case OP_NOTPROP:
3367  case OP_PROP:
3368  propdata[0] = 0;
3369  propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
3370  propdata[2] = cc[0];
3371  propdata[3] = cc[1];
3372  propdata[4] = XCL_END;
3373  compile_xclass_trypath(common, propdata, backtracks);
3374  return cc + 2;
3375#endif
3376#endif
3377
3378  case OP_ANYNL:
3379  detect_partial_match(common, backtracks);
3380  read_char(common);
3381  jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3382  /* We don't need to handle soft partial matching case. */
3383  if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3384    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3385  else
3386    jump[1] = check_str_end(common);
3387  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3388  jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3389  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3390  jump[3] = JUMP(SLJIT_JUMP);
3391  JUMPHERE(jump[0]);
3392  check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
3393  JUMPHERE(jump[1]);
3394  JUMPHERE(jump[2]);
3395  JUMPHERE(jump[3]);
3396  return cc;
3397
3398  case OP_NOT_HSPACE:
3399  case OP_HSPACE:
3400  detect_partial_match(common, backtracks);
3401  read_char(common);
3402  add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3403  add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3404  return cc;
3405
3406  case OP_NOT_VSPACE:
3407  case OP_VSPACE:
3408  detect_partial_match(common, backtracks);
3409  read_char(common);
3410  add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3411  add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3412  return cc;
3413
3414#ifdef SUPPORT_UCP
3415  case OP_EXTUNI:
3416  detect_partial_match(common, backtracks);
3417  read_char(common);
3418  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3419  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3420  add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
3421
3422  label = LABEL();
3423  jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3424  OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
3425  read_char(common);
3426  add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3427  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3428  CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
3429
3430  OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3431  JUMPHERE(jump[0]);
3432  if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3433    {
3434    jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3435    /* Since we successfully read a char above, partial matching must occure. */
3436    check_partial(common, TRUE);
3437    JUMPHERE(jump[0]);
3438    }
3439  return cc;
3440#endif
3441
3442  case OP_EODN:
3443  /* Requires rather complex checks. */
3444  jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3445  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3446    {
3447    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3448    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3449    if (common->mode == JIT_COMPILE)
3450      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3451    else
3452      {
3453      jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3454      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3455      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3456      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3457      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3458      add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
3459      check_partial(common, TRUE);
3460      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3461      JUMPHERE(jump[1]);
3462      }
3463    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3464    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3465    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3466    }
3467  else if (common->nltype == NLTYPE_FIXED)
3468    {
3469    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3470    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3471    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3472    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3473    }
3474  else
3475    {
3476    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3477    jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3478    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3479    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3480    jump[2] = JUMP(SLJIT_C_GREATER);
3481    add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
3482    /* Equal. */
3483    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3484    jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3485    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3486
3487    JUMPHERE(jump[1]);
3488    if (common->nltype == NLTYPE_ANYCRLF)
3489      {
3490      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3491      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
3492      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3493      }
3494    else
3495      {
3496      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
3497      read_char(common);
3498      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3499      add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3500      add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3501      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3502      }
3503    JUMPHERE(jump[2]);
3504    JUMPHERE(jump[3]);
3505    }
3506  JUMPHERE(jump[0]);
3507  check_partial(common, FALSE);
3508  return cc;
3509
3510  case OP_EOD:
3511  add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3512  check_partial(common, FALSE);
3513  return cc;
3514
3515  case OP_CIRC:
3516  OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3517  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3518  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
3519  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3520  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3521  return cc;
3522
3523  case OP_CIRCM:
3524  OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3525  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3526  jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
3527  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3528  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3529  jump[0] = JUMP(SLJIT_JUMP);
3530  JUMPHERE(jump[1]);
3531
3532  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
3533  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3534    {
3535    OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3536    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3537    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3538    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3539    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3540    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3541    }
3542  else
3543    {
3544    skip_char_back(common);
3545    read_char(common);
3546    check_newlinechar(common, common->nltype, backtracks, FALSE);
3547    }
3548  JUMPHERE(jump[0]);
3549  return cc;
3550
3551  case OP_DOLL:
3552  OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3553  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3554  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3555
3556  if (!common->endonly)
3557    compile_char1_trypath(common, OP_EODN, cc, backtracks);
3558  else
3559    {
3560    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3561    check_partial(common, FALSE);
3562    }
3563  return cc;
3564
3565  case OP_DOLLM:
3566  jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3567  OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3568  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3569  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3570  check_partial(common, FALSE);
3571  jump[0] = JUMP(SLJIT_JUMP);
3572  JUMPHERE(jump[1]);
3573
3574  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3575    {
3576    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3577    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3578    if (common->mode == JIT_COMPILE)
3579      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3580    else
3581      {
3582      jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3583      /* STR_PTR = STR_END - IN_UCHARS(1) */
3584      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3585      check_partial(common, TRUE);
3586      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3587      JUMPHERE(jump[1]);
3588      }
3589
3590    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3591    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3592    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3593    }
3594  else
3595    {
3596    peek_char(common);
3597    check_newlinechar(common, common->nltype, backtracks, FALSE);
3598    }
3599  JUMPHERE(jump[0]);
3600  return cc;
3601
3602  case OP_CHAR:
3603  case OP_CHARI:
3604  length = 1;
3605#ifdef SUPPORT_UTF
3606  if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3607#endif
3608  if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
3609    {
3610    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3611    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3612
3613    context.length = IN_UCHARS(length);
3614    context.sourcereg = -1;
3615#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3616    context.ucharptr = 0;
3617#endif
3618    return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
3619    }
3620  detect_partial_match(common, backtracks);
3621  read_char(common);
3622#ifdef SUPPORT_UTF
3623  if (common->utf)
3624    {
3625    GETCHAR(c, cc);
3626    }
3627  else
3628#endif
3629    c = *cc;
3630  if (type == OP_CHAR || !char_has_othercase(common, cc))
3631    {
3632    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3633    return cc + length;
3634    }
3635  oc = char_othercase(common, c);
3636  bit = c ^ oc;
3637  if (ispowerof2(bit))
3638    {
3639    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3640    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3641    return cc + length;
3642    }
3643  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3644  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3645  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
3646  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3647  add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3648  return cc + length;
3649
3650  case OP_NOT:
3651  case OP_NOTI:
3652  detect_partial_match(common, backtracks);
3653  length = 1;
3654#ifdef SUPPORT_UTF
3655  if (common->utf)
3656    {
3657#ifdef COMPILE_PCRE8
3658    c = *cc;
3659    if (c < 128)
3660      {
3661      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3662      if (type == OP_NOT || !char_has_othercase(common, cc))
3663        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3664      else
3665        {
3666        /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3667        OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3668        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
3669        }
3670      /* Skip the variable-length character. */
3671      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3672      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3673      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3674      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3675      JUMPHERE(jump[0]);
3676      return cc + 1;
3677      }
3678    else
3679#endif /* COMPILE_PCRE8 */
3680      {
3681      GETCHARLEN(c, cc, length);
3682      read_char(common);
3683      }
3684    }
3685  else
3686#endif /* SUPPORT_UTF */
3687    {
3688    read_char(common);
3689    c = *cc;
3690    }
3691
3692  if (type == OP_NOT || !char_has_othercase(common, cc))
3693    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3694  else
3695    {
3696    oc = char_othercase(common, c);
3697    bit = c ^ oc;
3698    if (ispowerof2(bit))
3699      {
3700      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3701      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3702      }
3703    else
3704      {
3705      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3706      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3707      }
3708    }
3709  return cc + length;
3710
3711  case OP_CLASS:
3712  case OP_NCLASS:
3713  detect_partial_match(common, backtracks);
3714  read_char(common);
3715#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3716  jump[0] = NULL;
3717#ifdef COMPILE_PCRE8
3718  /* This check only affects 8 bit mode. In other modes, we
3719  always need to compare the value with 255. */
3720  if (common->utf)
3721#endif /* COMPILE_PCRE8 */
3722    {
3723    jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3724    if (type == OP_CLASS)
3725      {
3726      add_jump(compiler, backtracks, jump[0]);
3727      jump[0] = NULL;
3728      }
3729    }
3730#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3731  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3732  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3733  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3734  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3735  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3736  add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3737#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3738  if (jump[0] != NULL)
3739    JUMPHERE(jump[0]);
3740#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3741  return cc + 32 / sizeof(pcre_uchar);
3742
3743#if defined SUPPORT_UTF || defined COMPILE_PCRE16
3744  case OP_XCLASS:
3745  compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
3746  return cc + GET(cc, 0) - 1;
3747#endif
3748
3749  case OP_REVERSE:
3750  length = GET(cc, 0);
3751  if (length == 0)
3752    return cc + LINK_SIZE;
3753  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3754#ifdef SUPPORT_UTF
3755  if (common->utf)
3756    {
3757    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3758    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3759    label = LABEL();
3760    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
3761    skip_char_back(common);
3762    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3763    JUMPTO(SLJIT_C_NOT_ZERO, label);
3764    }
3765  else
3766#endif
3767    {
3768    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3769    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3770    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3771    }
3772  check_start_used_ptr(common);
3773  return cc + LINK_SIZE;
3774  }
3775SLJIT_ASSERT_STOP();
3776return cc;
3777}
3778
3779static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
3780{
3781/* This function consumes at least one input character. */
3782/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
3783DEFINE_COMPILER;
3784pcre_uchar *ccbegin = cc;
3785compare_context context;
3786int size;
3787
3788context.length = 0;
3789do
3790  {
3791  if (cc >= ccend)
3792    break;
3793
3794  if (*cc == OP_CHAR)
3795    {
3796    size = 1;
3797#ifdef SUPPORT_UTF
3798    if (common->utf && HAS_EXTRALEN(cc[1]))
3799      size += GET_EXTRALEN(cc[1]);
3800#endif
3801    }
3802  else if (*cc == OP_CHARI)
3803    {
3804    size = 1;
3805#ifdef SUPPORT_UTF
3806    if (common->utf)
3807      {
3808      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3809        size = 0;
3810      else if (HAS_EXTRALEN(cc[1]))
3811        size += GET_EXTRALEN(cc[1]);
3812      }
3813    else
3814#endif
3815    if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3816      size = 0;
3817    }
3818  else
3819    size = 0;
3820
3821  cc += 1 + size;
3822  context.length += IN_UCHARS(size);
3823  }
3824while (size > 0 && context.length <= 128);
3825
3826cc = ccbegin;
3827if (context.length > 0)
3828  {
3829  /* We have a fixed-length byte sequence. */
3830  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
3831  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3832
3833  context.sourcereg = -1;
3834#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3835  context.ucharptr = 0;
3836#endif
3837  do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
3838  return cc;
3839  }
3840
3841/* A non-fixed length character will be checked if length == 0. */
3842return compile_char1_trypath(common, *cc, cc + 1, backtracks);
3843}
3844
3845static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3846{
3847DEFINE_COMPILER;
3848int offset = GET2(cc, 1) << 1;
3849
3850OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3851if (!common->jscript_compat)
3852  {
3853  if (backtracks == NULL)
3854    {
3855    /* OVECTOR(1) contains the "string begin - 1" constant. */
3856    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3857    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3858    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3859    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3860    return JUMP(SLJIT_C_NOT_ZERO);
3861    }
3862  add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3863  }
3864return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3865}
3866
3867/* Forward definitions. */
3868static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
3869static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
3870
3871#define PUSH_BACKTRACK(size, ccstart, error) \
3872  do \
3873    { \
3874    backtrack = sljit_alloc_memory(compiler, (size)); \
3875    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3876      return error; \
3877    memset(backtrack, 0, size); \
3878    backtrack->prev = parent->top; \
3879    backtrack->cc = (ccstart); \
3880    parent->top = backtrack; \
3881    } \
3882  while (0)
3883
3884#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
3885  do \
3886    { \
3887    backtrack = sljit_alloc_memory(compiler, (size)); \
3888    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3889      return; \
3890    memset(backtrack, 0, size); \
3891    backtrack->prev = parent->top; \
3892    backtrack->cc = (ccstart); \
3893    parent->top = backtrack; \
3894    } \
3895  while (0)
3896
3897#define BACKTRACK_AS(type) ((type *)backtrack)
3898
3899static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
3900{
3901DEFINE_COMPILER;
3902int offset = GET2(cc, 1) << 1;
3903struct sljit_jump *jump = NULL;
3904struct sljit_jump *partial;
3905struct sljit_jump *nopartial;
3906
3907OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3908/* OVECTOR(1) contains the "string begin - 1" constant. */
3909if (withchecks && !common->jscript_compat)
3910  add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3911
3912#if defined SUPPORT_UTF && defined SUPPORT_UCP
3913if (common->utf && *cc == OP_REFI)
3914  {
3915  SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
3916  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3917  if (withchecks)
3918    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
3919
3920  /* Needed to save important temporary registers. */
3921  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3922  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3923  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
3924  sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3925  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3926  if (common->mode == JIT_COMPILE)
3927    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3928  else
3929    {
3930    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3931    nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3932    check_partial(common, FALSE);
3933    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3934    JUMPHERE(nopartial);
3935    }
3936  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3937  }
3938else
3939#endif /* SUPPORT_UTF && SUPPORT_UCP */
3940  {
3941  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3942  if (withchecks)
3943    jump = JUMP(SLJIT_C_ZERO);
3944
3945  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3946  partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3947  if (common->mode == JIT_COMPILE)
3948    add_jump(compiler, backtracks, partial);
3949
3950  add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3951  add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3952
3953  if (common->mode != JIT_COMPILE)
3954    {
3955    nopartial = JUMP(SLJIT_JUMP);
3956    JUMPHERE(partial);
3957    /* TMP2 -= STR_END - STR_PTR */
3958    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3959    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3960    partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3961    OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3962    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3963    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3964    JUMPHERE(partial);
3965    check_partial(common, FALSE);
3966    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3967    JUMPHERE(nopartial);
3968    }
3969  }
3970
3971if (jump != NULL)
3972  {
3973  if (emptyfail)
3974    add_jump(compiler, backtracks, jump);
3975  else
3976    JUMPHERE(jump);
3977  }
3978return cc + 1 + IMM2_SIZE;
3979}
3980
3981static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
3982{
3983DEFINE_COMPILER;
3984backtrack_common *backtrack;
3985pcre_uchar type;
3986struct sljit_label *label;
3987struct sljit_jump *zerolength;
3988struct sljit_jump *jump = NULL;
3989pcre_uchar *ccbegin = cc;
3990int min = 0, max = 0;
3991BOOL minimize;
3992
3993PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
3994
3995type = cc[1 + IMM2_SIZE];
3996minimize = (type & 0x1) != 0;
3997switch(type)
3998  {
3999  case OP_CRSTAR:
4000  case OP_CRMINSTAR:
4001  min = 0;
4002  max = 0;
4003  cc += 1 + IMM2_SIZE + 1;
4004  break;
4005  case OP_CRPLUS:
4006  case OP_CRMINPLUS:
4007  min = 1;
4008  max = 0;
4009  cc += 1 + IMM2_SIZE + 1;
4010  break;
4011  case OP_CRQUERY:
4012  case OP_CRMINQUERY:
4013  min = 0;
4014  max = 1;
4015  cc += 1 + IMM2_SIZE + 1;
4016  break;
4017  case OP_CRRANGE:
4018  case OP_CRMINRANGE:
4019  min = GET2(cc, 1 + IMM2_SIZE + 1);
4020  max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
4021  cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
4022  break;
4023  default:
4024  SLJIT_ASSERT_STOP();
4025  break;
4026  }
4027
4028if (!minimize)
4029  {
4030  if (min == 0)
4031    {
4032    allocate_stack(common, 2);
4033    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4034    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
4035    /* Temporary release of STR_PTR. */
4036    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4037    zerolength = compile_ref_checks(common, ccbegin, NULL);
4038    /* Restore if not zero length. */
4039    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4040    }
4041  else
4042    {
4043    allocate_stack(common, 1);
4044    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4045    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4046    }
4047
4048  if (min > 1 || max > 1)
4049    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4050
4051  label = LABEL();
4052  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4053
4054  if (min > 1 || max > 1)
4055    {
4056    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
4057    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4058    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
4059    if (min > 1)
4060      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
4061    if (max > 1)
4062      {
4063      jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
4064      allocate_stack(common, 1);
4065      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4066      JUMPTO(SLJIT_JUMP, label);
4067      JUMPHERE(jump);
4068      }
4069    }
4070
4071  if (max == 0)
4072    {
4073    /* Includes min > 1 case as well. */
4074    allocate_stack(common, 1);
4075    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4076    JUMPTO(SLJIT_JUMP, label);
4077    }
4078
4079  JUMPHERE(zerolength);
4080  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4081
4082  decrease_call_count(common);
4083  return cc;
4084  }
4085
4086allocate_stack(common, 2);
4087OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4088if (type != OP_CRMINSTAR)
4089  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
4090
4091if (min == 0)
4092  {
4093  zerolength = compile_ref_checks(common, ccbegin, NULL);
4094  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4095  jump = JUMP(SLJIT_JUMP);
4096  }
4097else
4098  zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4099
4100BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4101if (max > 0)
4102  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4103
4104compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4105OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4106
4107if (min > 1)
4108  {
4109  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4110  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4111  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4112  CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);
4113  }
4114else if (max > 0)
4115  OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
4116
4117if (jump != NULL)
4118  JUMPHERE(jump);
4119JUMPHERE(zerolength);
4120
4121decrease_call_count(common);
4122return cc;
4123}
4124
4125static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4126{
4127DEFINE_COMPILER;
4128backtrack_common *backtrack;
4129recurse_entry *entry = common->entries;
4130recurse_entry *prev = NULL;
4131int start = GET(cc, 1);
4132
4133PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4134while (entry != NULL)
4135  {
4136  if (entry->start == start)
4137    break;
4138  prev = entry;
4139  entry = entry->next;
4140  }
4141
4142if (entry == NULL)
4143  {
4144  entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
4145  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4146    return NULL;
4147  entry->next = NULL;
4148  entry->entry = NULL;
4149  entry->calls = NULL;
4150  entry->start = start;
4151
4152  if (prev != NULL)
4153    prev->next = entry;
4154  else
4155    common->entries = entry;
4156  }
4157
4158if (common->has_set_som && common->mark_ptr != 0)
4159  {
4160  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4161  allocate_stack(common, 2);
4162  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4163  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4164  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4165  }
4166else if (common->has_set_som || common->mark_ptr != 0)
4167  {
4168  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4169  allocate_stack(common, 1);
4170  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4171  }
4172
4173if (entry->entry == NULL)
4174  add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
4175else
4176  JUMPTO(SLJIT_FAST_CALL, entry->entry);
4177/* Leave if the match is failed. */
4178add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
4179return cc + 1 + LINK_SIZE;
4180}
4181
4182static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4183{
4184DEFINE_COMPILER;
4185int framesize;
4186int localptr;
4187backtrack_common altbacktrack;
4188pcre_uchar *ccbegin;
4189pcre_uchar opcode;
4190pcre_uchar bra = OP_BRA;
4191jump_list *tmp = NULL;
4192jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4193jump_list **found;
4194/* Saving previous accept variables. */
4195struct sljit_label *save_leavelabel = common->leavelabel;
4196struct sljit_label *save_acceptlabel = common->acceptlabel;
4197jump_list *save_leave = common->leave;
4198jump_list *save_accept = common->accept;
4199struct sljit_jump *jump;
4200struct sljit_jump *brajump = NULL;
4201
4202if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4203  {
4204  SLJIT_ASSERT(!conditional);
4205  bra = *cc;
4206  cc++;
4207  }
4208localptr = PRIV_DATA(cc);
4209SLJIT_ASSERT(localptr != 0);
4210framesize = get_framesize(common, cc, FALSE);
4211backtrack->framesize = framesize;
4212backtrack->localptr = localptr;
4213opcode = *cc;
4214SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4215found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
4216ccbegin = cc;
4217cc += GET(cc, 1);
4218
4219if (bra == OP_BRAMINZERO)
4220  {
4221  /* This is a braminzero backtrack path. */
4222  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4223  free_stack(common, 1);
4224  brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4225  }
4226
4227if (framesize < 0)
4228  {
4229  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
4230  allocate_stack(common, 1);
4231  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4232  }
4233else
4234  {
4235  allocate_stack(common, framesize + 2);
4236  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4237  OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
4238  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4239  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4240  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4241  init_frame(common, ccbegin, framesize + 1, 2, FALSE);
4242  }
4243
4244memset(&altbacktrack, 0, sizeof(backtrack_common));
4245common->leavelabel = NULL;
4246common->leave = NULL;
4247while (1)
4248  {
4249  common->acceptlabel = NULL;
4250  common->accept = NULL;
4251  altbacktrack.top = NULL;
4252  altbacktrack.topbacktracks = NULL;
4253
4254  if (*ccbegin == OP_ALT)
4255    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4256
4257  altbacktrack.cc = ccbegin;
4258  compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
4259  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4260    {
4261    common->leavelabel = save_leavelabel;
4262    common->acceptlabel = save_acceptlabel;
4263    common->leave = save_leave;
4264    common->accept = save_accept;
4265    return NULL;
4266    }
4267  common->acceptlabel = LABEL();
4268  if (common->accept != NULL)
4269    set_jumps(common->accept, common->acceptlabel);
4270
4271  /* Reset stack. */
4272  if (framesize < 0)
4273    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4274  else {
4275    if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4276      {
4277      /* We don't need to keep the STR_PTR, only the previous localptr. */
4278      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4279      }
4280    else
4281      {
4282      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4283      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4284      }
4285  }
4286
4287  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4288    {
4289    /* We know that STR_PTR was stored on the top of the stack. */
4290    if (conditional)
4291      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4292    else if (bra == OP_BRAZERO)
4293      {
4294      if (framesize < 0)
4295        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4296      else
4297        {
4298        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4299        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
4300        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
4301        }
4302      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4303      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4304      }
4305    else if (framesize >= 0)
4306      {
4307      /* For OP_BRA and OP_BRAMINZERO. */
4308      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4309      }
4310    }
4311  add_jump(compiler, found, JUMP(SLJIT_JUMP));
4312
4313  compile_backtrackpath(common, altbacktrack.top);
4314  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4315    {
4316    common->leavelabel = save_leavelabel;
4317    common->acceptlabel = save_acceptlabel;
4318    common->leave = save_leave;
4319    common->accept = save_accept;
4320    return NULL;
4321    }
4322  set_jumps(altbacktrack.topbacktracks, LABEL());
4323
4324  if (*cc != OP_ALT)
4325    break;
4326
4327  ccbegin = cc;
4328  cc += GET(cc, 1);
4329  }
4330/* None of them matched. */
4331if (common->leave != NULL)
4332  set_jumps(common->leave, LABEL());
4333
4334if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4335  {
4336  /* Assert is failed. */
4337  if (conditional || bra == OP_BRAZERO)
4338    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4339
4340  if (framesize < 0)
4341    {
4342    /* The topmost item should be 0. */
4343    if (bra == OP_BRAZERO)
4344      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4345    else
4346      free_stack(common, 1);
4347    }
4348  else
4349    {
4350    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4351    /* The topmost item should be 0. */
4352    if (bra == OP_BRAZERO)
4353      {
4354      free_stack(common, framesize + 1);
4355      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4356      }
4357    else
4358      free_stack(common, framesize + 2);
4359    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
4360    }
4361  jump = JUMP(SLJIT_JUMP);
4362  if (bra != OP_BRAZERO)
4363    add_jump(compiler, target, jump);
4364
4365  /* Assert is successful. */
4366  set_jumps(tmp, LABEL());
4367  if (framesize < 0)
4368    {
4369    /* We know that STR_PTR was stored on the top of the stack. */
4370    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4371    /* Keep the STR_PTR on the top of the stack. */
4372    if (bra == OP_BRAZERO)
4373      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4374    else if (bra == OP_BRAMINZERO)
4375      {
4376      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4377      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4378      }
4379    }
4380  else
4381    {
4382    if (bra == OP_BRA)
4383      {
4384      /* We don't need to keep the STR_PTR, only the previous localptr. */
4385      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4386      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4387      }
4388    else
4389      {
4390      /* We don't need to keep the STR_PTR, only the previous localptr. */
4391      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
4392      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4393      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4394      }
4395    }
4396
4397  if (bra == OP_BRAZERO)
4398    {
4399    backtrack->trypath = LABEL();
4400    sljit_set_label(jump, backtrack->trypath);
4401    }
4402  else if (bra == OP_BRAMINZERO)
4403    {
4404    JUMPTO(SLJIT_JUMP, backtrack->trypath);
4405    JUMPHERE(brajump);
4406    if (framesize >= 0)
4407      {
4408      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4409      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4410      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4411      }
4412    set_jumps(backtrack->common.topbacktracks, LABEL());
4413    }
4414  }
4415else
4416  {
4417  /* AssertNot is successful. */
4418  if (framesize < 0)
4419    {
4420    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4421    if (bra != OP_BRA)
4422      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4423    else
4424      free_stack(common, 1);
4425    }
4426  else
4427    {
4428    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4429    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4430    /* The topmost item should be 0. */
4431    if (bra != OP_BRA)
4432      {
4433      free_stack(common, framesize + 1);
4434      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4435      }
4436    else
4437      free_stack(common, framesize + 2);
4438    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
4439    }
4440
4441  if (bra == OP_BRAZERO)
4442    backtrack->trypath = LABEL();
4443  else if (bra == OP_BRAMINZERO)
4444    {
4445    JUMPTO(SLJIT_JUMP, backtrack->trypath);
4446    JUMPHERE(brajump);
4447    }
4448
4449  if (bra != OP_BRA)
4450    {
4451    SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
4452    set_jumps(backtrack->common.topbacktracks, LABEL());
4453    backtrack->common.topbacktracks = NULL;
4454    }
4455  }
4456
4457common->leavelabel = save_leavelabel;
4458common->acceptlabel = save_acceptlabel;
4459common->leave = save_leave;
4460common->accept = save_accept;
4461return cc + 1 + LINK_SIZE;
4462}
4463
4464static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4465{
4466int condition = FALSE;
4467pcre_uchar *slotA = name_table;
4468pcre_uchar *slotB;
4469sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4470sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4471sljit_w no_capture;
4472int i;
4473
4474locals += refno & 0xff;
4475refno >>= 8;
4476no_capture = locals[1];
4477
4478for (i = 0; i < name_count; i++)
4479  {
4480  if (GET2(slotA, 0) == refno) break;
4481  slotA += name_entry_size;
4482  }
4483
4484if (i < name_count)
4485  {
4486  /* Found a name for the number - there can be only one; duplicate names
4487  for different numbers are allowed, but not vice versa. First scan down
4488  for duplicates. */
4489
4490  slotB = slotA;
4491  while (slotB > name_table)
4492    {
4493    slotB -= name_entry_size;
4494    if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4495      {
4496      condition = locals[GET2(slotB, 0) << 1] != no_capture;
4497      if (condition) break;
4498      }
4499    else break;
4500    }
4501
4502  /* Scan up for duplicates */
4503  if (!condition)
4504    {
4505    slotB = slotA;
4506    for (i++; i < name_count; i++)
4507      {
4508      slotB += name_entry_size;
4509      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4510        {
4511        condition = locals[GET2(slotB, 0) << 1] != no_capture;
4512        if (condition) break;
4513        }
4514      else break;
4515      }
4516    }
4517  }
4518return condition;
4519}
4520
4521static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4522{
4523int condition = FALSE;
4524pcre_uchar *slotA = name_table;
4525pcre_uchar *slotB;
4526sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4527sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4528sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4529int i;
4530
4531for (i = 0; i < name_count; i++)
4532  {
4533  if (GET2(slotA, 0) == recno) break;
4534  slotA += name_entry_size;
4535  }
4536
4537if (i < name_count)
4538  {
4539  /* Found a name for the number - there can be only one; duplicate
4540  names for different numbers are allowed, but not vice versa. First
4541  scan down for duplicates. */
4542
4543  slotB = slotA;
4544  while (slotB > name_table)
4545    {
4546    slotB -= name_entry_size;
4547    if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4548      {
4549      condition = GET2(slotB, 0) == group_num;
4550      if (condition) break;
4551      }
4552    else break;
4553    }
4554
4555  /* Scan up for duplicates */
4556  if (!condition)
4557    {
4558    slotB = slotA;
4559    for (i++; i < name_count; i++)
4560      {
4561      slotB += name_entry_size;
4562      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4563        {
4564        condition = GET2(slotB, 0) == group_num;
4565        if (condition) break;
4566        }
4567      else break;
4568      }
4569    }
4570  }
4571return condition;
4572}
4573
4574/*
4575  Handling bracketed expressions is probably the most complex part.
4576
4577  Stack layout naming characters:
4578    S - Push the current STR_PTR
4579    0 - Push a 0 (NULL)
4580    A - Push the current STR_PTR. Needed for restoring the STR_PTR
4581        before the next alternative. Not pushed if there are no alternatives.
4582    M - Any values pushed by the current alternative. Can be empty, or anything.
4583    C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
4584    L - Push the previous local (pointed by localptr) to the stack
4585   () - opional values stored on the stack
4586  ()* - optonal, can be stored multiple times
4587
4588  The following list shows the regular expression templates, their PCRE byte codes
4589  and stack layout supported by pcre-sljit.
4590
4591  (?:)                     OP_BRA     | OP_KET                A M
4592  ()                       OP_CBRA    | OP_KET                C M
4593  (?:)+                    OP_BRA     | OP_KETRMAX        0   A M S   ( A M S )*
4594                           OP_SBRA    | OP_KETRMAX        0   L M S   ( L M S )*
4595  (?:)+?                   OP_BRA     | OP_KETRMIN        0   A M S   ( A M S )*
4596                           OP_SBRA    | OP_KETRMIN        0   L M S   ( L M S )*
4597  ()+                      OP_CBRA    | OP_KETRMAX        0   C M S   ( C M S )*
4598                           OP_SCBRA   | OP_KETRMAX        0   C M S   ( C M S )*
4599  ()+?                     OP_CBRA    | OP_KETRMIN        0   C M S   ( C M S )*
4600                           OP_SCBRA   | OP_KETRMIN        0   C M S   ( C M S )*
4601  (?:)?    OP_BRAZERO    | OP_BRA     | OP_KET            S ( A M 0 )
4602  (?:)??   OP_BRAMINZERO | OP_BRA     | OP_KET            S ( A M 0 )
4603  ()?      OP_BRAZERO    | OP_CBRA    | OP_KET            S ( C M 0 )
4604  ()??     OP_BRAMINZERO | OP_CBRA    | OP_KET            S ( C M 0 )
4605  (?:)*    OP_BRAZERO    | OP_BRA     | OP_KETRMAX      S 0 ( A M S )*
4606           OP_BRAZERO    | OP_SBRA    | OP_KETRMAX      S 0 ( L M S )*
4607  (?:)*?   OP_BRAMINZERO | OP_BRA     | OP_KETRMIN      S 0 ( A M S )*
4608           OP_BRAMINZERO | OP_SBRA    | OP_KETRMIN      S 0 ( L M S )*
4609  ()*      OP_BRAZERO    | OP_CBRA    | OP_KETRMAX      S 0 ( C M S )*
4610           OP_BRAZERO    | OP_SCBRA   | OP_KETRMAX      S 0 ( C M S )*
4611  ()*?     OP_BRAMINZERO | OP_CBRA    | OP_KETRMIN      S 0 ( C M S )*
4612           OP_BRAMINZERO | OP_SCBRA   | OP_KETRMIN      S 0 ( C M S )*
4613
4614
4615  Stack layout naming characters:
4616    A - Push the alternative index (starting from 0) on the stack.
4617        Not pushed if there is no alternatives.
4618    M - Any values pushed by the current alternative. Can be empty, or anything.
4619
4620  The next list shows the possible content of a bracket:
4621  (|)     OP_*BRA    | OP_ALT ...         M A
4622  (?()|)  OP_*COND   | OP_ALT             M A
4623  (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4624  (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4625                                          Or nothing, if trace is unnecessary
4626*/
4627
4628static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4629{
4630DEFINE_COMPILER;
4631backtrack_common *backtrack;
4632pcre_uchar opcode;
4633int localptr = 0;
4634int offset = 0;
4635int stacksize;
4636pcre_uchar *ccbegin;
4637pcre_uchar *trypath;
4638pcre_uchar bra = OP_BRA;
4639pcre_uchar ket;
4640assert_backtrack *assert;
4641BOOL has_alternatives;
4642struct sljit_jump *jump;
4643struct sljit_jump *skip;
4644struct sljit_label *rmaxlabel = NULL;
4645struct sljit_jump *braminzerojump = NULL;
4646
4647PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
4648
4649if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4650  {
4651  bra = *cc;
4652  cc++;
4653  opcode = *cc;
4654  }
4655
4656opcode = *cc;
4657ccbegin = cc;
4658trypath = ccbegin + 1 + LINK_SIZE;
4659
4660if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
4661  {
4662  /* Drop this bracket_backtrack. */
4663  parent->top = backtrack->prev;
4664  return bracketend(cc);
4665  }
4666
4667ket = *(bracketend(cc) - 1 - LINK_SIZE);
4668SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4669SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
4670cc += GET(cc, 1);
4671
4672has_alternatives = *cc == OP_ALT;
4673if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4674  {
4675  has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;
4676  if (*trypath == OP_NRREF)
4677    {
4678    stacksize = GET2(trypath, 1);
4679    if (common->currententry == NULL || stacksize == RREF_ANY)
4680      has_alternatives = FALSE;
4681    else if (common->currententry->start == 0)
4682      has_alternatives = stacksize != 0;
4683    else
4684      has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4685    }
4686  }
4687
4688if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4689  opcode = OP_SCOND;
4690if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4691  opcode = OP_ONCE;
4692
4693if (opcode == OP_CBRA || opcode == OP_SCBRA)
4694  {
4695  /* Capturing brackets has a pre-allocated space. */
4696  offset = GET2(ccbegin, 1 + LINK_SIZE);
4697  localptr = OVECTOR_PRIV(offset);
4698  offset <<= 1;
4699  BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
4700  trypath += IMM2_SIZE;
4701  }
4702else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4703  {
4704  /* Other brackets simply allocate the next entry. */
4705  localptr = PRIV_DATA(ccbegin);
4706  SLJIT_ASSERT(localptr != 0);
4707  BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
4708  if (opcode == OP_ONCE)
4709    BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
4710  }
4711
4712/* Instructions before the first alternative. */
4713stacksize = 0;
4714if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
4715  stacksize++;
4716if (bra == OP_BRAZERO)
4717  stacksize++;
4718
4719if (stacksize > 0)
4720  allocate_stack(common, stacksize);
4721
4722stacksize = 0;
4723if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
4724  {
4725  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
4726  stacksize++;
4727  }
4728
4729if (bra == OP_BRAZERO)
4730  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
4731
4732if (bra == OP_BRAMINZERO)
4733  {
4734  /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
4735  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4736  if (ket != OP_KETRMIN)
4737    {
4738    free_stack(common, 1);
4739    braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4740    }
4741  else
4742    {
4743    if (opcode == OP_ONCE || opcode >= OP_SBRA)
4744      {
4745      jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4746      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4747      /* Nothing stored during the first run. */
4748      skip = JUMP(SLJIT_JUMP);
4749      JUMPHERE(jump);
4750      /* Checking zero-length iteration. */
4751      if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
4752        {
4753        /* When we come from outside, localptr contains the previous STR_PTR. */
4754        braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4755        }
4756      else
4757        {
4758        /* Except when the whole stack frame must be saved. */
4759        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4760        braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
4761        }
4762      JUMPHERE(skip);
4763      }
4764    else
4765      {
4766      jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4767      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4768      JUMPHERE(jump);
4769      }
4770    }
4771  }
4772
4773if (ket == OP_KETRMIN)
4774  BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
4775
4776if (ket == OP_KETRMAX)
4777  {
4778  rmaxlabel = LABEL();
4779  if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
4780    BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;
4781  }
4782
4783/* Handling capturing brackets and alternatives. */
4784if (opcode == OP_ONCE)
4785  {
4786  if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
4787    {
4788    /* Neither capturing brackets nor recursions are not found in the block. */
4789    if (ket == OP_KETRMIN)
4790      {
4791      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4792      allocate_stack(common, 2);
4793      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4794      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4795      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4796      }
4797    else if (ket == OP_KETRMAX || has_alternatives)
4798      {
4799      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
4800      allocate_stack(common, 1);
4801      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4802      }
4803    else
4804      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
4805    }
4806  else
4807    {
4808    if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
4809      {
4810      allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
4811      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4812      OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
4813      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4814      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4815      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4816      init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
4817      }
4818    else
4819      {
4820      allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
4821      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4822      OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
4823      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4824      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4825      init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
4826      }
4827    }
4828  }
4829else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4830  {
4831  /* Saving the previous values. */
4832  allocate_stack(common, 3);
4833  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4834  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4835  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4836  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4837  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4838  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4839  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
4840  }
4841else if (opcode == OP_SBRA || opcode == OP_SCOND)
4842  {
4843  /* Saving the previous value. */
4844  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4845  allocate_stack(common, 1);
4846  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4847  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4848  }
4849else if (has_alternatives)
4850  {
4851  /* Pushing the starting string pointer. */
4852  allocate_stack(common, 1);
4853  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4854  }
4855
4856/* Generating code for the first alternative. */
4857if (opcode == OP_COND || opcode == OP_SCOND)
4858  {
4859  if (*trypath == OP_CREF)
4860    {
4861    SLJIT_ASSERT(has_alternatives);
4862    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
4863      CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4864    trypath += 1 + IMM2_SIZE;
4865    }
4866  else if (*trypath == OP_NCREF)
4867    {
4868    SLJIT_ASSERT(has_alternatives);
4869    stacksize = GET2(trypath, 1);
4870    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4871
4872    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4873    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4874    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4875    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
4876    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
4877    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4878    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4879    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4880    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4881
4882    JUMPHERE(jump);
4883    trypath += 1 + IMM2_SIZE;
4884    }
4885  else if (*trypath == OP_RREF || *trypath == OP_NRREF)
4886    {
4887    /* Never has other case. */
4888    BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
4889
4890    stacksize = GET2(trypath, 1);
4891    if (common->currententry == NULL)
4892      stacksize = 0;
4893    else if (stacksize == RREF_ANY)
4894      stacksize = 1;
4895    else if (common->currententry->start == 0)
4896      stacksize = stacksize == 0;
4897    else
4898      stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4899
4900    if (*trypath == OP_RREF || stacksize || common->currententry == NULL)
4901      {
4902      SLJIT_ASSERT(!has_alternatives);
4903      if (stacksize != 0)
4904        trypath += 1 + IMM2_SIZE;
4905      else
4906        {
4907        if (*cc == OP_ALT)
4908          {
4909          trypath = cc + 1 + LINK_SIZE;
4910          cc += GET(cc, 1);
4911          }
4912        else
4913          trypath = cc;
4914        }
4915      }
4916    else
4917      {
4918      SLJIT_ASSERT(has_alternatives);
4919
4920      stacksize = GET2(trypath, 1);
4921      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4922      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4923      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4924      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4925      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4926      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
4927      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4928      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4929      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4930      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4931      trypath += 1 + IMM2_SIZE;
4932      }
4933    }
4934  else
4935    {
4936    SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);
4937    /* Similar code as PUSH_BACKTRACK macro. */
4938    assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
4939    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4940      return NULL;
4941    memset(assert, 0, sizeof(assert_backtrack));
4942    assert->common.cc = trypath;
4943    BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
4944    trypath = compile_assert_trypath(common, trypath, assert, TRUE);
4945    }
4946  }
4947
4948compile_trypath(common, trypath, cc, backtrack);
4949if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4950  return NULL;
4951
4952if (opcode == OP_ONCE)
4953  {
4954  if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
4955    {
4956    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4957    /* TMP2 which is set here used by OP_KETRMAX below. */
4958    if (ket == OP_KETRMAX)
4959      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
4960    else if (ket == OP_KETRMIN)
4961      {
4962      /* Move the STR_PTR to the localptr. */
4963      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
4964      }
4965    }
4966  else
4967    {
4968    stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4969    OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
4970    if (ket == OP_KETRMAX)
4971      {
4972      /* TMP2 which is set here used by OP_KETRMAX below. */
4973      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4974      }
4975    }
4976  }
4977
4978stacksize = 0;
4979if (ket != OP_KET || bra != OP_BRA)
4980  stacksize++;
4981if (has_alternatives && opcode != OP_ONCE)
4982  stacksize++;
4983
4984if (stacksize > 0)
4985  allocate_stack(common, stacksize);
4986
4987stacksize = 0;
4988if (ket != OP_KET)
4989  {
4990  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
4991  stacksize++;
4992  }
4993else if (bra != OP_BRA)
4994  {
4995  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
4996  stacksize++;
4997  }
4998
4999if (has_alternatives)
5000  {
5001  if (opcode != OP_ONCE)
5002    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5003  if (ket != OP_KETRMAX)
5004    BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5005  }
5006
5007/* Must be after the trypath label. */
5008if (offset != 0)
5009  {
5010  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5011  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5012  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5013  }
5014
5015if (ket == OP_KETRMAX)
5016  {
5017  if (opcode == OP_ONCE || opcode >= OP_SBRA)
5018    {
5019    if (has_alternatives)
5020      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5021    /* Checking zero-length iteration. */
5022    if (opcode != OP_ONCE)
5023      {
5024      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
5025      /* Drop STR_PTR for greedy plus quantifier. */
5026      if (bra != OP_BRAZERO)
5027        free_stack(common, 1);
5028      }
5029    else
5030      /* TMP2 must contain the starting STR_PTR. */
5031      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5032    }
5033  else
5034    JUMPTO(SLJIT_JUMP, rmaxlabel);
5035  BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5036  }
5037
5038if (bra == OP_BRAZERO)
5039  BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
5040
5041if (bra == OP_BRAMINZERO)
5042  {
5043  /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5044  JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
5045  if (braminzerojump != NULL)
5046    {
5047    JUMPHERE(braminzerojump);
5048    /* We need to release the end pointer to perform the
5049    backtrack for the zero-length iteration. When
5050    framesize is < 0, OP_ONCE will do the release itself. */
5051    if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5052      {
5053      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5054      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5055      }
5056    else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5057      free_stack(common, 1);
5058    }
5059  /* Continue to the normal backtrack. */
5060  }
5061
5062if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
5063  decrease_call_count(common);
5064
5065/* Skip the other alternatives. */
5066while (*cc == OP_ALT)
5067  cc += GET(cc, 1);
5068cc += 1 + LINK_SIZE;
5069return cc;
5070}
5071
5072static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5073{
5074DEFINE_COMPILER;
5075backtrack_common *backtrack;
5076pcre_uchar opcode;
5077int localptr;
5078int cbraprivptr = 0;
5079int framesize;
5080int stacksize;
5081int offset = 0;
5082BOOL zero = FALSE;
5083pcre_uchar *ccbegin = NULL;
5084int stack;
5085struct sljit_label *loop = NULL;
5086struct jump_list *emptymatch = NULL;
5087
5088PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5089if (*cc == OP_BRAPOSZERO)
5090  {
5091  zero = TRUE;
5092  cc++;
5093  }
5094
5095opcode = *cc;
5096localptr = PRIV_DATA(cc);
5097SLJIT_ASSERT(localptr != 0);
5098BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
5099switch(opcode)
5100  {
5101  case OP_BRAPOS:
5102  case OP_SBRAPOS:
5103  ccbegin = cc + 1 + LINK_SIZE;
5104  break;
5105
5106  case OP_CBRAPOS:
5107  case OP_SCBRAPOS:
5108  offset = GET2(cc, 1 + LINK_SIZE);
5109  cbraprivptr = OVECTOR_PRIV(offset);
5110  offset <<= 1;
5111  ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
5112  break;
5113
5114  default:
5115  SLJIT_ASSERT_STOP();
5116  break;
5117  }
5118
5119framesize = get_framesize(common, cc, FALSE);
5120BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5121if (framesize < 0)
5122  {
5123  stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5124  if (!zero)
5125    stacksize++;
5126  BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5127  allocate_stack(common, stacksize);
5128  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
5129
5130  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5131    {
5132    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5133    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5134    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5135    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5136    }
5137  else
5138    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5139
5140  if (!zero)
5141    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
5142  }
5143else
5144  {
5145  stacksize = framesize + 1;
5146  if (!zero)
5147    stacksize++;
5148  if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5149    stacksize++;
5150  BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5151  allocate_stack(common, stacksize);
5152
5153  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5154  OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
5155  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5156  stack = 0;
5157  if (!zero)
5158    {
5159    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
5160    stack++;
5161    }
5162  if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5163    {
5164    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
5165    stack++;
5166    }
5167  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
5168  init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
5169  }
5170
5171if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5172  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5173
5174loop = LABEL();
5175while (*cc != OP_KETRPOS)
5176  {
5177  backtrack->top = NULL;
5178  backtrack->topbacktracks = NULL;
5179  cc += GET(cc, 1);
5180
5181  compile_trypath(common, ccbegin, cc, backtrack);
5182  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5183    return NULL;
5184
5185  if (framesize < 0)
5186    {
5187    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5188
5189    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5190      {
5191      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
5192      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5193      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5194      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5195      }
5196    else
5197      {
5198      if (opcode == OP_SBRAPOS)
5199        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5200      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5201      }
5202
5203    if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
5204      add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
5205
5206    if (!zero)
5207      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
5208    }
5209  else
5210    {
5211    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5212      {
5213      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
5214      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
5215      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5216      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5217      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5218      }
5219    else
5220      {
5221      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5222      OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
5223      if (opcode == OP_SBRAPOS)
5224        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
5225      OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
5226      }
5227
5228    if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
5229      add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
5230
5231    if (!zero)
5232      {
5233      if (framesize < 0)
5234        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
5235      else
5236        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5237      }
5238    }
5239  JUMPTO(SLJIT_JUMP, loop);
5240  flush_stubs(common);
5241
5242  compile_backtrackpath(common, backtrack->top);
5243  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5244    return NULL;
5245  set_jumps(backtrack->topbacktracks, LABEL());
5246
5247  if (framesize < 0)
5248    {
5249    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5250      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
5251    else
5252      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5253    }
5254  else
5255    {
5256    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5257      {
5258      /* Last alternative. */
5259      if (*cc == OP_KETRPOS)
5260        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5261      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
5262      }
5263    else
5264      {
5265      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5266      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
5267      }
5268    }
5269
5270  if (*cc == OP_KETRPOS)
5271    break;
5272  ccbegin = cc + 1 + LINK_SIZE;
5273  }
5274
5275backtrack->topbacktracks = NULL;
5276if (!zero)
5277  {
5278  if (framesize < 0)
5279    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
5280  else /* TMP2 is set to [localptr] above. */
5281    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
5282  }
5283
5284/* None of them matched. */
5285set_jumps(emptymatch, LABEL());
5286decrease_call_count(common);
5287return cc + 1 + LINK_SIZE;
5288}
5289
5290static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
5291{
5292int class_len;
5293
5294*opcode = *cc;
5295if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
5296  {
5297  cc++;
5298  *type = OP_CHAR;
5299  }
5300else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
5301  {
5302  cc++;
5303  *type = OP_CHARI;
5304  *opcode -= OP_STARI - OP_STAR;
5305  }
5306else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
5307  {
5308  cc++;
5309  *type = OP_NOT;
5310  *opcode -= OP_NOTSTAR - OP_STAR;
5311  }
5312else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
5313  {
5314  cc++;
5315  *type = OP_NOTI;
5316  *opcode -= OP_NOTSTARI - OP_STAR;
5317  }
5318else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
5319  {
5320  cc++;
5321  *opcode -= OP_TYPESTAR - OP_STAR;
5322  *type = 0;
5323  }
5324else
5325  {
5326  SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5327  *type = *opcode;
5328  cc++;
5329  class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5330  *opcode = cc[class_len - 1];
5331  if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5332    {
5333    *opcode -= OP_CRSTAR - OP_STAR;
5334    if (end != NULL)
5335      *end = cc + class_len;
5336    }
5337  else
5338    {
5339    SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
5340    *arg1 = GET2(cc, (class_len + IMM2_SIZE));
5341    *arg2 = GET2(cc, class_len);
5342
5343    if (*arg2 == 0)
5344      {
5345      SLJIT_ASSERT(*arg1 != 0);
5346      *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
5347      }
5348    if (*arg1 == *arg2)
5349      *opcode = OP_EXACT;
5350
5351    if (end != NULL)
5352      *end = cc + class_len + 2 * IMM2_SIZE;
5353    }
5354  return cc;
5355  }
5356
5357if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
5358  {
5359  *arg1 = GET2(cc, 0);
5360  cc += IMM2_SIZE;
5361  }
5362
5363if (*type == 0)
5364  {
5365  *type = *cc;
5366  if (end != NULL)
5367    *end = next_opcode(common, cc);
5368  cc++;
5369  return cc;
5370  }
5371
5372if (end != NULL)
5373  {
5374  *end = cc + 1;
5375#ifdef SUPPORT_UTF
5376  if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
5377#endif
5378  }
5379return cc;
5380}
5381
5382static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5383{
5384DEFINE_COMPILER;
5385backtrack_common *backtrack;
5386pcre_uchar opcode;
5387pcre_uchar type;
5388int arg1 = -1, arg2 = -1;
5389pcre_uchar* end;
5390jump_list *nomatch = NULL;
5391struct sljit_jump *jump = NULL;
5392struct sljit_label *label;
5393
5394PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5395
5396cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
5397
5398switch(opcode)
5399  {
5400  case OP_STAR:
5401  case OP_PLUS:
5402  case OP_UPTO:
5403  case OP_CRRANGE:
5404  if (type == OP_ANYNL || type == OP_EXTUNI)
5405    {
5406    if (opcode == OP_STAR || opcode == OP_UPTO)
5407      {
5408      allocate_stack(common, 2);
5409      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5410      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5411      }
5412    else
5413      {
5414      allocate_stack(common, 1);
5415      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5416      }
5417    if (opcode == OP_UPTO || opcode == OP_CRRANGE)
5418      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5419
5420    label = LABEL();
5421    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5422    if (opcode == OP_UPTO || opcode == OP_CRRANGE)
5423      {
5424      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5425      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5426      if (opcode == OP_CRRANGE && arg2 > 0)
5427        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);
5428      if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))
5429        jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);
5430      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
5431      }
5432
5433    allocate_stack(common, 1);
5434    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5435    JUMPTO(SLJIT_JUMP, label);
5436    if (jump != NULL)
5437      JUMPHERE(jump);
5438    }
5439  else
5440    {
5441    if (opcode == OP_PLUS)
5442      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5443    allocate_stack(common, 2);
5444    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5445    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5446    label = LABEL();
5447    compile_char1_trypath(common, type, cc, &nomatch);
5448    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5449    if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
5450      {
5451      OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5452      JUMPTO(SLJIT_JUMP, label);
5453      }
5454    else
5455      {
5456      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5457      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5458      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5459      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5460      }
5461    set_jumps(nomatch, LABEL());
5462    if (opcode == OP_CRRANGE)
5463      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));
5464    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5465    }
5466  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5467  break;
5468
5469  case OP_MINSTAR:
5470  case OP_MINPLUS:
5471  if (opcode == OP_MINPLUS)
5472    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5473  allocate_stack(common, 1);
5474  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5475  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5476  break;
5477
5478  case OP_MINUPTO:
5479  case OP_CRMINRANGE:
5480  allocate_stack(common, 2);
5481  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5482  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5483  if (opcode == OP_CRMINRANGE)
5484    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5485  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5486  break;
5487
5488  case OP_QUERY:
5489  case OP_MINQUERY:
5490  allocate_stack(common, 1);
5491  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5492  if (opcode == OP_QUERY)
5493    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5494  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5495  break;
5496
5497  case OP_EXACT:
5498  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5499  label = LABEL();
5500  compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5501  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5502  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5503  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
5504  CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5505  break;
5506
5507  case OP_POSSTAR:
5508  case OP_POSPLUS:
5509  case OP_POSUPTO:
5510  if (opcode != OP_POSSTAR)
5511    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5512  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5513  label = LABEL();
5514  compile_char1_trypath(common, type, cc, &nomatch);
5515  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5516  if (opcode != OP_POSUPTO)
5517    {
5518    if (opcode == OP_POSPLUS)
5519      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);
5520    JUMPTO(SLJIT_JUMP, label);
5521    }
5522  else
5523    {
5524    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5525    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5526    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
5527    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5528    }
5529  set_jumps(nomatch, LABEL());
5530  if (opcode == OP_POSPLUS)
5531    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
5532  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5533  break;
5534
5535  case OP_POSQUERY:
5536  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5537  compile_char1_trypath(common, type, cc, &nomatch);
5538  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5539  set_jumps(nomatch, LABEL());
5540  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5541  break;
5542
5543  default:
5544  SLJIT_ASSERT_STOP();
5545  break;
5546  }
5547
5548decrease_call_count(common);
5549return end;
5550}
5551
5552static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5553{
5554DEFINE_COMPILER;
5555backtrack_common *backtrack;
5556
5557PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5558
5559if (*cc == OP_FAIL)
5560  {
5561  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5562  return cc + 1;
5563  }
5564
5565if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
5566  {
5567  /* No need to check notempty conditions. */
5568  if (common->acceptlabel == NULL)
5569    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
5570  else
5571    JUMPTO(SLJIT_JUMP, common->acceptlabel);
5572  return cc + 1;
5573  }
5574
5575if (common->acceptlabel == NULL)
5576  add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
5577else
5578  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
5579OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5580OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
5581add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5582OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
5583if (common->acceptlabel == NULL)
5584  add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5585else
5586  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);
5587OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
5588if (common->acceptlabel == NULL)
5589  add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
5590else
5591  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
5592add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5593return cc + 1;
5594}
5595
5596static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)
5597{
5598DEFINE_COMPILER;
5599int offset = GET2(cc, 1);
5600
5601/* Data will be discarded anyway... */
5602if (common->currententry != NULL)
5603  return cc + 1 + IMM2_SIZE;
5604
5605OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
5606offset <<= 1;
5607OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5608OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5609return cc + 1 + IMM2_SIZE;
5610}
5611
5612static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
5613{
5614DEFINE_COMPILER;
5615backtrack_common *backtrack;
5616
5617while (cc < ccend)
5618  {
5619  switch(*cc)
5620    {
5621    case OP_SOD:
5622    case OP_SOM:
5623    case OP_NOT_WORD_BOUNDARY:
5624    case OP_WORD_BOUNDARY:
5625    case OP_NOT_DIGIT:
5626    case OP_DIGIT:
5627    case OP_NOT_WHITESPACE:
5628    case OP_WHITESPACE:
5629    case OP_NOT_WORDCHAR:
5630    case OP_WORDCHAR:
5631    case OP_ANY:
5632    case OP_ALLANY:
5633    case OP_ANYBYTE:
5634    case OP_NOTPROP:
5635    case OP_PROP:
5636    case OP_ANYNL:
5637    case OP_NOT_HSPACE:
5638    case OP_HSPACE:
5639    case OP_NOT_VSPACE:
5640    case OP_VSPACE:
5641    case OP_EXTUNI:
5642    case OP_EODN:
5643    case OP_EOD:
5644    case OP_CIRC:
5645    case OP_CIRCM:
5646    case OP_DOLL:
5647    case OP_DOLLM:
5648    case OP_NOT:
5649    case OP_NOTI:
5650    case OP_REVERSE:
5651    cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5652    break;
5653
5654    case OP_SET_SOM:
5655    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5656    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5657    allocate_stack(common, 1);
5658    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
5659    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5660    cc++;
5661    break;
5662
5663    case OP_CHAR:
5664    case OP_CHARI:
5665    if (common->mode == JIT_COMPILE)
5666      cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5667    else
5668      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5669    break;
5670
5671    case OP_STAR:
5672    case OP_MINSTAR:
5673    case OP_PLUS:
5674    case OP_MINPLUS:
5675    case OP_QUERY:
5676    case OP_MINQUERY:
5677    case OP_UPTO:
5678    case OP_MINUPTO:
5679    case OP_EXACT:
5680    case OP_POSSTAR:
5681    case OP_POSPLUS:
5682    case OP_POSQUERY:
5683    case OP_POSUPTO:
5684    case OP_STARI:
5685    case OP_MINSTARI:
5686    case OP_PLUSI:
5687    case OP_MINPLUSI:
5688    case OP_QUERYI:
5689    case OP_MINQUERYI:
5690    case OP_UPTOI:
5691    case OP_MINUPTOI:
5692    case OP_EXACTI:
5693    case OP_POSSTARI:
5694    case OP_POSPLUSI:
5695    case OP_POSQUERYI:
5696    case OP_POSUPTOI:
5697    case OP_NOTSTAR:
5698    case OP_NOTMINSTAR:
5699    case OP_NOTPLUS:
5700    case OP_NOTMINPLUS:
5701    case OP_NOTQUERY:
5702    case OP_NOTMINQUERY:
5703    case OP_NOTUPTO:
5704    case OP_NOTMINUPTO:
5705    case OP_NOTEXACT:
5706    case OP_NOTPOSSTAR:
5707    case OP_NOTPOSPLUS:
5708    case OP_NOTPOSQUERY:
5709    case OP_NOTPOSUPTO:
5710    case OP_NOTSTARI:
5711    case OP_NOTMINSTARI:
5712    case OP_NOTPLUSI:
5713    case OP_NOTMINPLUSI:
5714    case OP_NOTQUERYI:
5715    case OP_NOTMINQUERYI:
5716    case OP_NOTUPTOI:
5717    case OP_NOTMINUPTOI:
5718    case OP_NOTEXACTI:
5719    case OP_NOTPOSSTARI:
5720    case OP_NOTPOSPLUSI:
5721    case OP_NOTPOSQUERYI:
5722    case OP_NOTPOSUPTOI:
5723    case OP_TYPESTAR:
5724    case OP_TYPEMINSTAR:
5725    case OP_TYPEPLUS:
5726    case OP_TYPEMINPLUS:
5727    case OP_TYPEQUERY:
5728    case OP_TYPEMINQUERY:
5729    case OP_TYPEUPTO:
5730    case OP_TYPEMINUPTO:
5731    case OP_TYPEEXACT:
5732    case OP_TYPEPOSSTAR:
5733    case OP_TYPEPOSPLUS:
5734    case OP_TYPEPOSQUERY:
5735    case OP_TYPEPOSUPTO:
5736    cc = compile_iterator_trypath(common, cc, parent);
5737    break;
5738
5739    case OP_CLASS:
5740    case OP_NCLASS:
5741    if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
5742      cc = compile_iterator_trypath(common, cc, parent);
5743    else
5744      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5745    break;
5746
5747#if defined SUPPORT_UTF || defined COMPILE_PCRE16
5748    case OP_XCLASS:
5749    if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
5750      cc = compile_iterator_trypath(common, cc, parent);
5751    else
5752      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5753    break;
5754#endif
5755
5756    case OP_REF:
5757    case OP_REFI:
5758    if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5759      cc = compile_ref_iterator_trypath(common, cc, parent);
5760    else
5761      cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
5762    break;
5763
5764    case OP_RECURSE:
5765    cc = compile_recurse_trypath(common, cc, parent);
5766    break;
5767
5768    case OP_ASSERT:
5769    case OP_ASSERT_NOT:
5770    case OP_ASSERTBACK:
5771    case OP_ASSERTBACK_NOT:
5772    PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
5773    cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
5774    break;
5775
5776    case OP_BRAMINZERO:
5777    PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
5778    cc = bracketend(cc + 1);
5779    if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
5780      {
5781      allocate_stack(common, 1);
5782      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5783      }
5784    else
5785      {
5786      allocate_stack(common, 2);
5787      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5788      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
5789      }
5790    BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();
5791    if (cc[1] > OP_ASSERTBACK_NOT)
5792      decrease_call_count(common);
5793    break;
5794
5795    case OP_ONCE:
5796    case OP_ONCE_NC:
5797    case OP_BRA:
5798    case OP_CBRA:
5799    case OP_COND:
5800    case OP_SBRA:
5801    case OP_SCBRA:
5802    case OP_SCOND:
5803    cc = compile_bracket_trypath(common, cc, parent);
5804    break;
5805
5806    case OP_BRAZERO:
5807    if (cc[1] > OP_ASSERTBACK_NOT)
5808      cc = compile_bracket_trypath(common, cc, parent);
5809    else
5810      {
5811      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
5812      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
5813      }
5814    break;
5815
5816    case OP_BRAPOS:
5817    case OP_CBRAPOS:
5818    case OP_SBRAPOS:
5819    case OP_SCBRAPOS:
5820    case OP_BRAPOSZERO:
5821    cc = compile_bracketpos_trypath(common, cc, parent);
5822    break;
5823
5824    case OP_MARK:
5825    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5826    SLJIT_ASSERT(common->mark_ptr != 0);
5827    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5828    allocate_stack(common, 1);
5829    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5830    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5831    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5832    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5833    OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5834    cc += 1 + 2 + cc[1];
5835    break;
5836
5837    case OP_COMMIT:
5838    PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5839    cc += 1;
5840    break;
5841
5842    case OP_FAIL:
5843    case OP_ACCEPT:
5844    case OP_ASSERT_ACCEPT:
5845    cc = compile_fail_accept_trypath(common, cc, parent);
5846    break;
5847
5848    case OP_CLOSE:
5849    cc = compile_close_trypath(common, cc);
5850    break;
5851
5852    case OP_SKIPZERO:
5853    cc = bracketend(cc + 1);
5854    break;
5855
5856    default:
5857    SLJIT_ASSERT_STOP();
5858    return;
5859    }
5860  if (cc == NULL)
5861    return;
5862  }
5863SLJIT_ASSERT(cc == ccend);
5864}
5865
5866#undef PUSH_BACKTRACK
5867#undef PUSH_BACKTRACK_NOVALUE
5868#undef BACKTRACK_AS
5869
5870#define COMPILE_BACKTRACKPATH(current) \
5871  do \
5872    { \
5873    compile_backtrackpath(common, (current)); \
5874    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
5875      return; \
5876    } \
5877  while (0)
5878
5879#define CURRENT_AS(type) ((type *)current)
5880
5881static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
5882{
5883DEFINE_COMPILER;
5884pcre_uchar *cc = current->cc;
5885pcre_uchar opcode;
5886pcre_uchar type;
5887int arg1 = -1, arg2 = -1;
5888struct sljit_label *label = NULL;
5889struct sljit_jump *jump = NULL;
5890jump_list *jumplist = NULL;
5891
5892cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
5893
5894switch(opcode)
5895  {
5896  case OP_STAR:
5897  case OP_PLUS:
5898  case OP_UPTO:
5899  case OP_CRRANGE:
5900  if (type == OP_ANYNL || type == OP_EXTUNI)
5901    {
5902    set_jumps(current->topbacktracks, LABEL());
5903    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5904    free_stack(common, 1);
5905    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
5906    }
5907  else
5908    {
5909    if (opcode <= OP_PLUS || opcode == OP_UPTO)
5910      arg2 = 0;
5911    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5912    jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
5913    OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1);
5914    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5915    skip_char_back(common);
5916    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5917    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5918    if (opcode == OP_CRRANGE)
5919      set_jumps(current->topbacktracks, LABEL());
5920    JUMPHERE(jump);
5921    free_stack(common, 2);
5922    if (opcode == OP_PLUS)
5923      set_jumps(current->topbacktracks, LABEL());
5924    }
5925  break;
5926
5927  case OP_MINSTAR:
5928  case OP_MINPLUS:
5929  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5930  compile_char1_trypath(common, type, cc, &jumplist);
5931  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5932  JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5933  set_jumps(jumplist, LABEL());
5934  free_stack(common, 1);
5935  if (opcode == OP_MINPLUS)
5936    set_jumps(current->topbacktracks, LABEL());
5937  break;
5938
5939  case OP_MINUPTO:
5940  case OP_CRMINRANGE:
5941  if (opcode == OP_CRMINRANGE)
5942    {
5943    label = LABEL();
5944    set_jumps(current->topbacktracks, label);
5945    }
5946  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5947  compile_char1_trypath(common, type, cc, &jumplist);
5948
5949  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5950  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5951  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5952  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5953
5954  if (opcode == OP_CRMINRANGE)
5955    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
5956
5957  if (opcode == OP_CRMINRANGE && arg1 == 0)
5958    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5959  else
5960    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);
5961
5962  set_jumps(jumplist, LABEL());
5963  free_stack(common, 2);
5964  break;
5965
5966  case OP_QUERY:
5967  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5968  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5969  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
5970  jump = JUMP(SLJIT_JUMP);
5971  set_jumps(current->topbacktracks, LABEL());
5972  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5973  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5974  JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5975  JUMPHERE(jump);
5976  free_stack(common, 1);
5977  break;
5978
5979  case OP_MINQUERY:
5980  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5981  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5982  jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
5983  compile_char1_trypath(common, type, cc, &jumplist);
5984  JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5985  set_jumps(jumplist, LABEL());
5986  JUMPHERE(jump);
5987  free_stack(common, 1);
5988  break;
5989
5990  case OP_EXACT:
5991  case OP_POSPLUS:
5992  set_jumps(current->topbacktracks, LABEL());
5993  break;
5994
5995  case OP_POSSTAR:
5996  case OP_POSQUERY:
5997  case OP_POSUPTO:
5998  break;
5999
6000  default:
6001  SLJIT_ASSERT_STOP();
6002  break;
6003  }
6004}
6005
6006static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
6007{
6008DEFINE_COMPILER;
6009pcre_uchar *cc = current->cc;
6010pcre_uchar type;
6011
6012type = cc[1 + IMM2_SIZE];
6013if ((type & 0x1) == 0)
6014  {
6015  set_jumps(current->topbacktracks, LABEL());
6016  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6017  free_stack(common, 1);
6018  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
6019  return;
6020  }
6021
6022OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6023CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
6024set_jumps(current->topbacktracks, LABEL());
6025free_stack(common, 2);
6026}
6027
6028static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)
6029{
6030DEFINE_COMPILER;
6031
6032set_jumps(current->topbacktracks, LABEL());
6033
6034if (common->has_set_som && common->mark_ptr != 0)
6035  {
6036  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6037  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6038  free_stack(common, 2);
6039  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6040  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6041  }
6042else if (common->has_set_som || common->mark_ptr != 0)
6043  {
6044  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6045  free_stack(common, 1);
6046  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6047  }
6048}
6049
6050static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)
6051{
6052DEFINE_COMPILER;
6053pcre_uchar *cc = current->cc;
6054pcre_uchar bra = OP_BRA;
6055struct sljit_jump *brajump = NULL;
6056
6057SLJIT_ASSERT(*cc != OP_BRAMINZERO);
6058if (*cc == OP_BRAZERO)
6059  {
6060  bra = *cc;
6061  cc++;
6062  }
6063
6064if (bra == OP_BRAZERO)
6065  {
6066  SLJIT_ASSERT(current->topbacktracks == NULL);
6067  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6068  }
6069
6070if (CURRENT_AS(assert_backtrack)->framesize < 0)
6071  {
6072  set_jumps(current->topbacktracks, LABEL());
6073
6074  if (bra == OP_BRAZERO)
6075    {
6076    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6077    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
6078    free_stack(common, 1);
6079    }
6080  return;
6081  }
6082
6083if (bra == OP_BRAZERO)
6084  {
6085  if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6086    {
6087    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6088    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
6089    free_stack(common, 1);
6090    return;
6091    }
6092  free_stack(common, 1);
6093  brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6094  }
6095
6096if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
6097  {
6098  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);
6099  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6100  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
6101
6102  set_jumps(current->topbacktracks, LABEL());
6103  }
6104else
6105  set_jumps(current->topbacktracks, LABEL());
6106
6107if (bra == OP_BRAZERO)
6108  {
6109  /* We know there is enough place on the stack. */
6110  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
6111  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6112  JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);
6113  JUMPHERE(brajump);
6114  }
6115}
6116
6117static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)
6118{
6119DEFINE_COMPILER;
6120int opcode;
6121int offset = 0;
6122int localptr = CURRENT_AS(bracket_backtrack)->localptr;
6123int stacksize;
6124int count;
6125pcre_uchar *cc = current->cc;
6126pcre_uchar *ccbegin;
6127pcre_uchar *ccprev;
6128jump_list *jumplist = NULL;
6129jump_list *jumplistitem = NULL;
6130pcre_uchar bra = OP_BRA;
6131pcre_uchar ket;
6132assert_backtrack *assert;
6133BOOL has_alternatives;
6134struct sljit_jump *brazero = NULL;
6135struct sljit_jump *once = NULL;
6136struct sljit_jump *cond = NULL;
6137struct sljit_label *rminlabel = NULL;
6138
6139if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
6140  {
6141  bra = *cc;
6142  cc++;
6143  }
6144
6145opcode = *cc;
6146ccbegin = cc;
6147ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
6148cc += GET(cc, 1);
6149has_alternatives = *cc == OP_ALT;
6150if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6151  has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
6152if (opcode == OP_CBRA || opcode == OP_SCBRA)
6153  offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
6154if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
6155  opcode = OP_SCOND;
6156if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
6157  opcode = OP_ONCE;
6158
6159if (ket == OP_KETRMAX)
6160  {
6161  if (bra == OP_BRAZERO)
6162    {
6163    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6164    free_stack(common, 1);
6165    brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0);
6166    }
6167  }
6168else if (ket == OP_KETRMIN)
6169  {
6170  if (bra != OP_BRAMINZERO)
6171    {
6172    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6173    if (opcode >= OP_SBRA || opcode == OP_ONCE)
6174      {
6175      /* Checking zero-length iteration. */
6176      if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
6177        CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6178      else
6179        {
6180        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6181        CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);
6182        }
6183      if (opcode != OP_ONCE)
6184        free_stack(common, 1);
6185      }
6186    else
6187      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6188    }
6189  rminlabel = LABEL();
6190  }
6191else if (bra == OP_BRAZERO)
6192  {
6193  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6194  free_stack(common, 1);
6195  brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
6196  }
6197
6198if (SLJIT_UNLIKELY(opcode == OP_ONCE))
6199  {
6200  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6201    {
6202    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6203    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6204    }
6205  once = JUMP(SLJIT_JUMP);
6206  }
6207else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6208  {
6209  if (has_alternatives)
6210    {
6211    /* Always exactly one alternative. */
6212    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6213    free_stack(common, 1);
6214
6215    jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
6216    if (SLJIT_UNLIKELY(!jumplistitem))
6217      return;
6218    jumplist = jumplistitem;
6219    jumplistitem->next = NULL;
6220    jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
6221    }
6222  }
6223else if (*cc == OP_ALT)
6224  {
6225  /* Build a jump list. Get the last successfully matched branch index. */
6226  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6227  free_stack(common, 1);
6228  count = 1;
6229  do
6230    {
6231    /* Append as the last item. */
6232    if (jumplist != NULL)
6233      {
6234      jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
6235      jumplistitem = jumplistitem->next;
6236      }
6237    else
6238      {
6239      jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
6240      jumplist = jumplistitem;
6241      }
6242
6243    if (SLJIT_UNLIKELY(!jumplistitem))
6244      return;
6245
6246    jumplistitem->next = NULL;
6247    jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
6248    cc += GET(cc, 1);
6249    }
6250  while (*cc == OP_ALT);
6251
6252  cc = ccbegin + GET(ccbegin, 1);
6253  }
6254
6255COMPILE_BACKTRACKPATH(current->top);
6256if (current->topbacktracks)
6257  set_jumps(current->topbacktracks, LABEL());
6258
6259if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6260  {
6261  /* Conditional block always has at most one alternative. */
6262  if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
6263    {
6264    SLJIT_ASSERT(has_alternatives);
6265    assert = CURRENT_AS(bracket_backtrack)->u.assert;
6266    if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
6267      {
6268      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
6269      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6270      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
6271      }
6272    cond = JUMP(SLJIT_JUMP);
6273    set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
6274    }
6275  else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
6276    {
6277    SLJIT_ASSERT(has_alternatives);
6278    cond = JUMP(SLJIT_JUMP);
6279    set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
6280    }
6281  else
6282    SLJIT_ASSERT(!has_alternatives);
6283  }
6284
6285if (has_alternatives)
6286  {
6287  count = 1;
6288  do
6289    {
6290    current->top = NULL;
6291    current->topbacktracks = NULL;
6292    current->nextbacktracks = NULL;
6293    if (*cc == OP_ALT)
6294      {
6295      ccprev = cc + 1 + LINK_SIZE;
6296      cc += GET(cc, 1);
6297      if (opcode != OP_COND && opcode != OP_SCOND)
6298        {
6299        if (localptr != 0 && opcode != OP_ONCE)
6300          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6301        else
6302          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6303        }
6304      compile_trypath(common, ccprev, cc, current);
6305      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6306        return;
6307      }
6308
6309    /* Instructions after the current alternative is succesfully matched. */
6310    /* There is a similar code in compile_bracket_trypath. */
6311    if (opcode == OP_ONCE)
6312      {
6313      if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
6314        {
6315        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6316        /* TMP2 which is set here used by OP_KETRMAX below. */
6317        if (ket == OP_KETRMAX)
6318          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6319        else if (ket == OP_KETRMIN)
6320          {
6321          /* Move the STR_PTR to the localptr. */
6322          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
6323          }
6324        }
6325      else
6326        {
6327        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
6328        if (ket == OP_KETRMAX)
6329          {
6330          /* TMP2 which is set here used by OP_KETRMAX below. */
6331          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6332          }
6333        }
6334      }
6335
6336    stacksize = 0;
6337    if (opcode != OP_ONCE)
6338      stacksize++;
6339    if (ket != OP_KET || bra != OP_BRA)
6340      stacksize++;
6341
6342    if (stacksize > 0) {
6343      if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6344        allocate_stack(common, stacksize);
6345      else
6346        {
6347        /* We know we have place at least for one item on the top of the stack. */
6348        SLJIT_ASSERT(stacksize == 1);
6349        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
6350        }
6351    }
6352
6353    stacksize = 0;
6354    if (ket != OP_KET || bra != OP_BRA)
6355      {
6356      if (ket != OP_KET)
6357        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6358      else
6359        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6360      stacksize++;
6361      }
6362
6363    if (opcode != OP_ONCE)
6364      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
6365
6366    if (offset != 0)
6367      {
6368      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6369      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6370      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
6371      }
6372
6373    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);
6374
6375    if (opcode != OP_ONCE)
6376      {
6377      SLJIT_ASSERT(jumplist);
6378      JUMPHERE(jumplist->jump);
6379      jumplist = jumplist->next;
6380      }
6381
6382    COMPILE_BACKTRACKPATH(current->top);
6383    if (current->topbacktracks)
6384      set_jumps(current->topbacktracks, LABEL());
6385    SLJIT_ASSERT(!current->nextbacktracks);
6386    }
6387  while (*cc == OP_ALT);
6388  SLJIT_ASSERT(!jumplist);
6389
6390  if (cond != NULL)
6391    {
6392    SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
6393    assert = CURRENT_AS(bracket_backtrack)->u.assert;
6394    if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
6395
6396      {
6397      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
6398      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6399      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
6400      }
6401    JUMPHERE(cond);
6402    }
6403
6404  /* Free the STR_PTR. */
6405  if (localptr == 0)
6406    free_stack(common, 1);
6407  }
6408
6409if (offset != 0)
6410  {
6411  /* Using both tmp register is better for instruction scheduling. */
6412  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6413  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6414  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6415  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
6416  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
6417  free_stack(common, 3);
6418  }
6419else if (opcode == OP_SBRA || opcode == OP_SCOND)
6420  {
6421  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));
6422  free_stack(common, 1);
6423  }
6424else if (opcode == OP_ONCE)
6425  {
6426  cc = ccbegin + GET(ccbegin, 1);
6427  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6428    {
6429    /* Reset head and drop saved frame. */
6430    stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
6431    free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize);
6432    }
6433  else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
6434    {
6435    /* The STR_PTR must be released. */
6436    free_stack(common, 1);
6437    }
6438
6439  JUMPHERE(once);
6440  /* Restore previous localptr */
6441  if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6442    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
6443  else if (ket == OP_KETRMIN)
6444    {
6445    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6446    /* See the comment below. */
6447    free_stack(common, 2);
6448    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
6449    }
6450  }
6451
6452if (ket == OP_KETRMAX)
6453  {
6454  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6455  if (bra != OP_BRAZERO)
6456    free_stack(common, 1);
6457  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6458  if (bra == OP_BRAZERO)
6459    {
6460    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6461    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
6462    JUMPHERE(brazero);
6463    free_stack(common, 1);
6464    }
6465  }
6466else if (ket == OP_KETRMIN)
6467  {
6468  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6469
6470  /* OP_ONCE removes everything in case of a backtrack, so we don't
6471  need to explicitly release the STR_PTR. The extra release would
6472  affect badly the free_stack(2) above. */
6473  if (opcode != OP_ONCE)
6474    free_stack(common, 1);
6475  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);
6476  if (opcode == OP_ONCE)
6477    free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
6478  else if (bra == OP_BRAMINZERO)
6479    free_stack(common, 1);
6480  }
6481else if (bra == OP_BRAZERO)
6482  {
6483  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6484  JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
6485  JUMPHERE(brazero);
6486  }
6487}
6488
6489static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)
6490{
6491DEFINE_COMPILER;
6492int offset;
6493struct sljit_jump *jump;
6494
6495if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
6496  {
6497  if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
6498    {
6499    offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
6500    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6501    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6502    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6503    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
6504    }
6505  set_jumps(current->topbacktracks, LABEL());
6506  free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
6507  return;
6508  }
6509
6510OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);
6511add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6512
6513if (current->topbacktracks)
6514  {
6515  jump = JUMP(SLJIT_JUMP);
6516  set_jumps(current->topbacktracks, LABEL());
6517  /* Drop the stack frame. */
6518  free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
6519  JUMPHERE(jump);
6520  }
6521OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
6522}
6523
6524static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)
6525{
6526assert_backtrack backtrack;
6527
6528current->top = NULL;
6529current->topbacktracks = NULL;
6530current->nextbacktracks = NULL;
6531if (current->cc[1] > OP_ASSERTBACK_NOT)
6532  {
6533  /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */
6534  compile_bracket_trypath(common, current->cc, current);
6535  compile_bracket_backtrackpath(common, current->top);
6536  }
6537else
6538  {
6539  memset(&backtrack, 0, sizeof(backtrack));
6540  backtrack.common.cc = current->cc;
6541  backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;
6542  /* Manual call of compile_assert_trypath. */
6543  compile_assert_trypath(common, current->cc, &backtrack, FALSE);
6544  }
6545SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
6546}
6547
6548static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)
6549{
6550DEFINE_COMPILER;
6551
6552while (current)
6553  {
6554  if (current->nextbacktracks != NULL)
6555    set_jumps(current->nextbacktracks, LABEL());
6556  switch(*current->cc)
6557    {
6558    case OP_SET_SOM:
6559    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6560    free_stack(common, 1);
6561    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0);
6562    break;
6563
6564    case OP_STAR:
6565    case OP_MINSTAR:
6566    case OP_PLUS:
6567    case OP_MINPLUS:
6568    case OP_QUERY:
6569    case OP_MINQUERY:
6570    case OP_UPTO:
6571    case OP_MINUPTO:
6572    case OP_EXACT:
6573    case OP_POSSTAR:
6574    case OP_POSPLUS:
6575    case OP_POSQUERY:
6576    case OP_POSUPTO:
6577    case OP_STARI:
6578    case OP_MINSTARI:
6579    case OP_PLUSI:
6580    case OP_MINPLUSI:
6581    case OP_QUERYI:
6582    case OP_MINQUERYI:
6583    case OP_UPTOI:
6584    case OP_MINUPTOI:
6585    case OP_EXACTI:
6586    case OP_POSSTARI:
6587    case OP_POSPLUSI:
6588    case OP_POSQUERYI:
6589    case OP_POSUPTOI:
6590    case OP_NOTSTAR:
6591    case OP_NOTMINSTAR:
6592    case OP_NOTPLUS:
6593    case OP_NOTMINPLUS:
6594    case OP_NOTQUERY:
6595    case OP_NOTMINQUERY:
6596    case OP_NOTUPTO:
6597    case OP_NOTMINUPTO:
6598    case OP_NOTEXACT:
6599    case OP_NOTPOSSTAR:
6600    case OP_NOTPOSPLUS:
6601    case OP_NOTPOSQUERY:
6602    case OP_NOTPOSUPTO:
6603    case OP_NOTSTARI:
6604    case OP_NOTMINSTARI:
6605    case OP_NOTPLUSI:
6606    case OP_NOTMINPLUSI:
6607    case OP_NOTQUERYI:
6608    case OP_NOTMINQUERYI:
6609    case OP_NOTUPTOI:
6610    case OP_NOTMINUPTOI:
6611    case OP_NOTEXACTI:
6612    case OP_NOTPOSSTARI:
6613    case OP_NOTPOSPLUSI:
6614    case OP_NOTPOSQUERYI:
6615    case OP_NOTPOSUPTOI:
6616    case OP_TYPESTAR:
6617    case OP_TYPEMINSTAR:
6618    case OP_TYPEPLUS:
6619    case OP_TYPEMINPLUS:
6620    case OP_TYPEQUERY:
6621    case OP_TYPEMINQUERY:
6622    case OP_TYPEUPTO:
6623    case OP_TYPEMINUPTO:
6624    case OP_TYPEEXACT:
6625    case OP_TYPEPOSSTAR:
6626    case OP_TYPEPOSPLUS:
6627    case OP_TYPEPOSQUERY:
6628    case OP_TYPEPOSUPTO:
6629    case OP_CLASS:
6630    case OP_NCLASS:
6631#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6632    case OP_XCLASS:
6633#endif
6634    compile_iterator_backtrackpath(common, current);
6635    break;
6636
6637    case OP_REF:
6638    case OP_REFI:
6639    compile_ref_iterator_backtrackpath(common, current);
6640    break;
6641
6642    case OP_RECURSE:
6643    compile_recurse_backtrackpath(common, current);
6644    break;
6645
6646    case OP_ASSERT:
6647    case OP_ASSERT_NOT:
6648    case OP_ASSERTBACK:
6649    case OP_ASSERTBACK_NOT:
6650    compile_assert_backtrackpath(common, current);
6651    break;
6652
6653    case OP_ONCE:
6654    case OP_ONCE_NC:
6655    case OP_BRA:
6656    case OP_CBRA:
6657    case OP_COND:
6658    case OP_SBRA:
6659    case OP_SCBRA:
6660    case OP_SCOND:
6661    compile_bracket_backtrackpath(common, current);
6662    break;
6663
6664    case OP_BRAZERO:
6665    if (current->cc[1] > OP_ASSERTBACK_NOT)
6666      compile_bracket_backtrackpath(common, current);
6667    else
6668      compile_assert_backtrackpath(common, current);
6669    break;
6670
6671    case OP_BRAPOS:
6672    case OP_CBRAPOS:
6673    case OP_SBRAPOS:
6674    case OP_SCBRAPOS:
6675    case OP_BRAPOSZERO:
6676    compile_bracketpos_backtrackpath(common, current);
6677    break;
6678
6679    case OP_BRAMINZERO:
6680    compile_braminzero_backtrackpath(common, current);
6681    break;
6682
6683    case OP_MARK:
6684    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6685    free_stack(common, 1);
6686    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6687    break;
6688
6689    case OP_COMMIT:
6690    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6691    if (common->leavelabel == NULL)
6692      add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
6693    else
6694      JUMPTO(SLJIT_JUMP, common->leavelabel);
6695    break;
6696
6697    case OP_FAIL:
6698    case OP_ACCEPT:
6699    case OP_ASSERT_ACCEPT:
6700    set_jumps(current->topbacktracks, LABEL());
6701    break;
6702
6703    default:
6704    SLJIT_ASSERT_STOP();
6705    break;
6706    }
6707  current = current->prev;
6708  }
6709}
6710
6711static SLJIT_INLINE void compile_recurse(compiler_common *common)
6712{
6713DEFINE_COMPILER;
6714pcre_uchar *cc = common->start + common->currententry->start;
6715pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6716pcre_uchar *ccend = bracketend(cc);
6717int localsize = get_localsize(common, ccbegin, ccend);
6718int framesize = get_framesize(common, cc, TRUE);
6719int alternativesize;
6720BOOL needsframe;
6721backtrack_common altbacktrack;
6722struct sljit_label *save_leavelabel = common->leavelabel;
6723jump_list *save_leave = common->leave;
6724struct sljit_jump *jump;
6725
6726SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
6727needsframe = framesize >= 0;
6728if (!needsframe)
6729  framesize = 0;
6730alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6731
6732SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6733common->currententry->entry = LABEL();
6734set_jumps(common->currententry->calls, common->currententry->entry);
6735
6736sljit_emit_fast_enter(compiler, TMP2, 0);
6737allocate_stack(common, localsize + framesize + alternativesize);
6738OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
6739copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6740OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
6741if (needsframe)
6742  init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
6743
6744if (alternativesize > 0)
6745  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6746
6747memset(&altbacktrack, 0, sizeof(backtrack_common));
6748common->leavelabel = NULL;
6749common->acceptlabel = NULL;
6750common->leave = NULL;
6751common->accept = NULL;
6752altbacktrack.cc = ccbegin;
6753cc += GET(cc, 1);
6754while (1)
6755  {
6756  altbacktrack.top = NULL;
6757  altbacktrack.topbacktracks = NULL;
6758
6759  if (altbacktrack.cc != ccbegin)
6760    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6761
6762  compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);
6763  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6764    {
6765    common->leavelabel = save_leavelabel;
6766    common->leave = save_leave;
6767    return;
6768    }
6769
6770  add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6771
6772  compile_backtrackpath(common, altbacktrack.top);
6773  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6774    {
6775    common->leavelabel = save_leavelabel;
6776    common->leave = save_leave;
6777    return;
6778    }
6779  set_jumps(altbacktrack.topbacktracks, LABEL());
6780
6781  if (*cc != OP_ALT)
6782    break;
6783
6784  altbacktrack.cc = cc + 1 + LINK_SIZE;
6785  cc += GET(cc, 1);
6786  }
6787/* None of them matched. */
6788if (common->leave != NULL)
6789  set_jumps(common->leave, LABEL());
6790
6791OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6792jump = JUMP(SLJIT_JUMP);
6793
6794set_jumps(common->accept, LABEL());
6795OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
6796if (needsframe)
6797  {
6798  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6799  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6800  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6801  }
6802OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6803
6804JUMPHERE(jump);
6805copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);
6806free_stack(common, localsize + framesize + alternativesize);
6807OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6808OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6809OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
6810sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6811
6812common->leavelabel = save_leavelabel;
6813common->leave = save_leave;
6814}
6815
6816#undef COMPILE_BACKTRACKPATH
6817#undef CURRENT_AS
6818
6819void
6820PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6821{
6822struct sljit_compiler *compiler;
6823backtrack_common rootbacktrack;
6824compiler_common common_data;
6825compiler_common *common = &common_data;
6826const pcre_uint8 *tables = re->tables;
6827pcre_study_data *study;
6828int localsize;
6829pcre_uchar *ccend;
6830executable_functions *functions;
6831void *executable_func;
6832sljit_uw executable_size;
6833struct sljit_label *mainloop = NULL;
6834struct sljit_label *empty_match_found;
6835struct sljit_label *empty_match_backtrack;
6836struct sljit_jump *jump;
6837struct sljit_jump *reqbyte_notfound = NULL;
6838struct sljit_jump *empty_match;
6839
6840SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
6841study = extra->study_data;
6842
6843if (!tables)
6844  tables = PRIV(default_tables);
6845
6846memset(&rootbacktrack, 0, sizeof(backtrack_common));
6847memset(common, 0, sizeof(compiler_common));
6848rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6849
6850common->start = rootbacktrack.cc;
6851common->fcc = tables + fcc_offset;
6852common->lcc = (sljit_w)(tables + lcc_offset);
6853common->mode = mode;
6854common->nltype = NLTYPE_FIXED;
6855switch(re->options & PCRE_NEWLINE_BITS)
6856  {
6857  case 0:
6858  /* Compile-time default */
6859  switch (NEWLINE)
6860    {
6861    case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6862    case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6863    default: common->newline = NEWLINE; break;
6864    }
6865  break;
6866  case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
6867  case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
6868  case PCRE_NEWLINE_CR+
6869       PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
6870  case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6871  case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6872  default: return;
6873  }
6874if ((re->options & PCRE_BSR_ANYCRLF) != 0)
6875  common->bsr_nltype = NLTYPE_ANYCRLF;
6876else if ((re->options & PCRE_BSR_UNICODE) != 0)
6877  common->bsr_nltype = NLTYPE_ANY;
6878else
6879  {
6880#ifdef BSR_ANYCRLF
6881  common->bsr_nltype = NLTYPE_ANYCRLF;
6882#else
6883  common->bsr_nltype = NLTYPE_ANY;
6884#endif
6885  }
6886common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6887common->ctypes = (sljit_w)(tables + ctypes_offset);
6888common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6889common->name_count = re->name_count;
6890common->name_entry_size = re->name_entry_size;
6891common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6892#ifdef SUPPORT_UTF
6893/* PCRE_UTF16 has the same value as PCRE_UTF8. */
6894common->utf = (re->options & PCRE_UTF8) != 0;
6895#ifdef SUPPORT_UCP
6896common->use_ucp = (re->options & PCRE_UCP) != 0;
6897#endif
6898#endif /* SUPPORT_UTF */
6899ccend = bracketend(rootbacktrack.cc);
6900
6901/* Calculate the local space size on the stack. */
6902common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6903
6904SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6905localsize = get_localspace(common, rootbacktrack.cc, ccend);
6906if (localsize < 0)
6907  return;
6908
6909/* Checking flags and updating ovector_start. */
6910if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
6911  {
6912  common->req_char_ptr = common->ovector_start;
6913  common->ovector_start += sizeof(sljit_w);
6914  }
6915if (mode != JIT_COMPILE)
6916  {
6917  common->start_used_ptr = common->ovector_start;
6918  common->ovector_start += sizeof(sljit_w);
6919  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6920    {
6921    common->hit_start = common->ovector_start;
6922    common->ovector_start += sizeof(sljit_w);
6923    }
6924  }
6925if ((re->options & PCRE_FIRSTLINE) != 0)
6926  {
6927  common->first_line_end = common->ovector_start;
6928  common->ovector_start += sizeof(sljit_w);
6929  }
6930
6931/* Aligning ovector to even number of sljit words. */
6932if ((common->ovector_start & sizeof(sljit_w)) != 0)
6933  common->ovector_start += sizeof(sljit_w);
6934
6935SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6936common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6937localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6938if (localsize > SLJIT_MAX_LOCAL_SIZE)
6939  return;
6940common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
6941if (!common->localptrs)
6942  return;
6943memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
6944set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
6945
6946compiler = sljit_create_compiler();
6947if (!compiler)
6948  {
6949  SLJIT_FREE(common->localptrs);
6950  return;
6951  }
6952common->compiler = compiler;
6953
6954/* Main pcre_jit_exec entry. */
6955sljit_emit_enter(compiler, 1, 5, 5, localsize);
6956
6957/* Register init. */
6958reset_ovector(common, (re->top_bracket + 1) * 2);
6959if (common->req_char_ptr != 0)
6960  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);
6961
6962OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6963OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6964OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6965OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6966OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6967OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
6968OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
6969OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6970OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6971
6972if (mode == JIT_PARTIAL_SOFT_COMPILE)
6973  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6974
6975/* Main part of the matching */
6976if ((re->options & PCRE_ANCHORED) == 0)
6977  {
6978  mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6979  /* Forward search if possible. */
6980  if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
6981    {
6982    if ((re->flags & PCRE_FIRSTSET) != 0)
6983      fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6984    else if ((re->flags & PCRE_STARTLINE) != 0)
6985      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6986    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6987      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6988    }
6989  }
6990if (common->req_char_ptr != 0)
6991  reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6992
6993/* Store the current STR_PTR in OVECTOR(0). */
6994OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6995/* Copy the limit of allowed recursions. */
6996OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6997if (common->mark_ptr != 0)
6998  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
6999/* Copy the beginning of the string. */
7000if (mode == JIT_PARTIAL_SOFT_COMPILE)
7001  {
7002  jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
7003  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7004  JUMPHERE(jump);
7005  }
7006else if (mode == JIT_PARTIAL_HARD_COMPILE)
7007  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7008
7009compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7010if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7011  {
7012  sljit_free_compiler(compiler);
7013  SLJIT_FREE(common->localptrs);
7014  return;
7015  }
7016
7017empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
7018empty_match_found = LABEL();
7019
7020common->acceptlabel = LABEL();
7021if (common->accept != NULL)
7022  set_jumps(common->accept, common->acceptlabel);
7023
7024/* This means we have a match. Update the ovector. */
7025copy_ovector(common, re->top_bracket + 1);
7026common->leavelabel = LABEL();
7027if (common->leave != NULL)
7028  set_jumps(common->leave, common->leavelabel);
7029sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7030
7031if (mode != JIT_COMPILE)
7032  {
7033  common->partialmatchlabel = LABEL();
7034  set_jumps(common->partialmatch, common->partialmatchlabel);
7035  return_with_partial_match(common, common->leavelabel);
7036  }
7037
7038empty_match_backtrack = LABEL();
7039compile_backtrackpath(common, rootbacktrack.top);
7040if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7041  {
7042  sljit_free_compiler(compiler);
7043  SLJIT_FREE(common->localptrs);
7044  return;
7045  }
7046
7047SLJIT_ASSERT(rootbacktrack.prev == NULL);
7048
7049if (mode == JIT_PARTIAL_SOFT_COMPILE)
7050  {
7051  /* Update hit_start only in the first time. */
7052  jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
7053  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
7054  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
7055  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
7056  JUMPHERE(jump);
7057  }
7058
7059/* Check we have remaining characters. */
7060OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
7061
7062if ((re->options & PCRE_ANCHORED) == 0)
7063  {
7064  if ((re->options & PCRE_FIRSTLINE) == 0)
7065    {
7066    if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
7067      {
7068      OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7069      CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
7070      }
7071    else
7072      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
7073    }
7074  else
7075    {
7076    SLJIT_ASSERT(common->first_line_end != 0);
7077    if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
7078      {
7079      OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7080      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
7081      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
7082      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
7083      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
7084      JUMPTO(SLJIT_C_ZERO, mainloop);
7085      }
7086    else
7087      CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);
7088    }
7089  }
7090
7091/* No more remaining characters. */
7092if (reqbyte_notfound != NULL)
7093  JUMPHERE(reqbyte_notfound);
7094
7095if (mode == JIT_PARTIAL_SOFT_COMPILE)
7096  CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7097
7098OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7099JUMPTO(SLJIT_JUMP, common->leavelabel);
7100
7101flush_stubs(common);
7102
7103JUMPHERE(empty_match);
7104OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7105OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
7106CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);
7107OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
7108CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
7109OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
7110CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
7111JUMPTO(SLJIT_JUMP, empty_match_backtrack);
7112
7113common->currententry = common->entries;
7114while (common->currententry != NULL)
7115  {
7116  /* Might add new entries. */
7117  compile_recurse(common);
7118  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7119    {
7120    sljit_free_compiler(compiler);
7121    SLJIT_FREE(common->localptrs);
7122    return;
7123    }
7124  flush_stubs(common);
7125  common->currententry = common->currententry->next;
7126  }
7127
7128/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
7129/* This is a (really) rare case. */
7130set_jumps(common->stackalloc, LABEL());
7131/* RETURN_ADDR is not a saved register. */
7132sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
7133OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
7134OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7135OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
7136OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
7137OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
7138
7139sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
7140jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
7141OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7142OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
7143OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
7144OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
7145OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
7146sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
7147
7148/* Allocation failed. */
7149JUMPHERE(jump);
7150/* We break the return address cache here, but this is a really rare case. */
7151OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
7152JUMPTO(SLJIT_JUMP, common->leavelabel);
7153
7154/* Call limit reached. */
7155set_jumps(common->calllimit, LABEL());
7156OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7157JUMPTO(SLJIT_JUMP, common->leavelabel);
7158
7159if (common->revertframes != NULL)
7160  {
7161  set_jumps(common->revertframes, LABEL());
7162  do_revertframes(common);
7163  }
7164if (common->wordboundary != NULL)
7165  {
7166  set_jumps(common->wordboundary, LABEL());
7167  check_wordboundary(common);
7168  }
7169if (common->anynewline != NULL)
7170  {
7171  set_jumps(common->anynewline, LABEL());
7172  check_anynewline(common);
7173  }
7174if (common->hspace != NULL)
7175  {
7176  set_jumps(common->hspace, LABEL());
7177  check_hspace(common);
7178  }
7179if (common->vspace != NULL)
7180  {
7181  set_jumps(common->vspace, LABEL());
7182  check_vspace(common);
7183  }
7184if (common->casefulcmp != NULL)
7185  {
7186  set_jumps(common->casefulcmp, LABEL());
7187  do_casefulcmp(common);
7188  }
7189if (common->caselesscmp != NULL)
7190  {
7191  set_jumps(common->caselesscmp, LABEL());
7192  do_caselesscmp(common);
7193  }
7194#ifdef SUPPORT_UTF
7195if (common->utfreadchar != NULL)
7196  {
7197  set_jumps(common->utfreadchar, LABEL());
7198  do_utfreadchar(common);
7199  }
7200#ifdef COMPILE_PCRE8
7201if (common->utfreadtype8 != NULL)
7202  {
7203  set_jumps(common->utfreadtype8, LABEL());
7204  do_utfreadtype8(common);
7205  }
7206#endif
7207#endif /* COMPILE_PCRE8 */
7208#ifdef SUPPORT_UCP
7209if (common->getucd != NULL)
7210  {
7211  set_jumps(common->getucd, LABEL());
7212  do_getucd(common);
7213  }
7214#endif
7215
7216SLJIT_FREE(common->localptrs);
7217executable_func = sljit_generate_code(compiler);
7218executable_size = sljit_get_generated_code_size(compiler);
7219sljit_free_compiler(compiler);
7220if (executable_func == NULL)
7221  return;
7222
7223/* Reuse the function descriptor if possible. */
7224if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
7225  functions = (executable_functions *)extra->executable_jit;
7226else
7227  {
7228  functions = SLJIT_MALLOC(sizeof(executable_functions));
7229  if (functions == NULL)
7230    {
7231    /* This case is highly unlikely since we just recently
7232    freed a lot of memory. Although not impossible. */
7233    sljit_free_code(executable_func);
7234    return;
7235    }
7236  memset(functions, 0, sizeof(executable_functions));
7237  extra->executable_jit = functions;
7238  extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
7239  }
7240
7241functions->executable_funcs[mode] = executable_func;
7242functions->executable_sizes[mode] = executable_size;
7243}
7244
7245static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
7246{
7247union {
7248   void* executable_func;
7249   jit_function call_executable_func;
7250} convert_executable_func;
7251pcre_uint8 local_area[LOCAL_SPACE_SIZE];
7252struct sljit_stack local_stack;
7253
7254local_stack.top = (sljit_w)&local_area;
7255local_stack.base = local_stack.top;
7256local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
7257local_stack.max_limit = local_stack.limit;
7258arguments->stack = &local_stack;
7259convert_executable_func.executable_func = executable_func;
7260return convert_executable_func.call_executable_func(arguments);
7261}
7262
7263int
7264PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
7265  int length, int start_offset, int options, int *offsets, int offsetcount)
7266{
7267executable_functions *functions = (executable_functions *)extra_data->executable_jit;
7268union {
7269   void* executable_func;
7270   jit_function call_executable_func;
7271} convert_executable_func;
7272jit_arguments arguments;
7273int maxoffsetcount;
7274int retval;
7275int mode = JIT_COMPILE;
7276
7277if ((options & PCRE_PARTIAL_HARD) != 0)
7278  mode = JIT_PARTIAL_HARD_COMPILE;
7279else if ((options & PCRE_PARTIAL_SOFT) != 0)
7280  mode = JIT_PARTIAL_SOFT_COMPILE;
7281
7282if (functions->executable_funcs[mode] == NULL)
7283  return PCRE_ERROR_NULL;
7284
7285/* Sanity checks should be handled by pcre_exec. */
7286arguments.stack = NULL;
7287arguments.str = subject + start_offset;
7288arguments.begin = subject;
7289arguments.end = subject + length;
7290arguments.mark_ptr = NULL;
7291/* JIT decreases this value less frequently than the interpreter. */
7292arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
7293arguments.notbol = (options & PCRE_NOTBOL) != 0;
7294arguments.noteol = (options & PCRE_NOTEOL) != 0;
7295arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
7296arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
7297arguments.offsets = offsets;
7298
7299/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
7300the output vector for storing captured strings, with the remainder used as
7301workspace. We don't need the workspace here. For compatibility, we limit the
7302number of captured strings in the same way as pcre_exec(), so that the user
7303gets the same result with and without JIT. */
7304
7305if (offsetcount != 2)
7306  offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
7307maxoffsetcount = (re->top_bracket + 1) * 2;
7308if (offsetcount > maxoffsetcount)
7309  offsetcount = maxoffsetcount;
7310arguments.offsetcount = offsetcount;
7311
7312if (functions->callback)
7313  arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7314else
7315  arguments.stack = (struct sljit_stack *)functions->userdata;
7316
7317if (arguments.stack == NULL)
7318  retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7319else
7320  {
7321  convert_executable_func.executable_func = functions->executable_funcs[mode];
7322  retval = convert_executable_func.call_executable_func(&arguments);
7323  }
7324
7325if (retval * 2 > offsetcount)
7326  retval = 0;
7327if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
7328  *(extra_data->mark) = arguments.mark_ptr;
7329
7330return retval;
7331}
7332
7333void
7334PRIV(jit_free)(void *executable_funcs)
7335{
7336int i;
7337executable_functions *functions = (executable_functions *)executable_funcs;
7338for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7339  {
7340  if (functions->executable_funcs[i] != NULL)
7341    sljit_free_code(functions->executable_funcs[i]);
7342  }
7343SLJIT_FREE(functions);
7344}
7345
7346int
7347PRIV(jit_get_size)(void *executable_funcs)
7348{
7349int i;
7350sljit_uw size = 0;
7351sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
7352for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7353  size += executable_sizes[i];
7354return (int)size;
7355}
7356
7357const char*
7358PRIV(jit_get_target)(void)
7359{
7360return sljit_get_platform_name();
7361}
7362
7363#ifdef COMPILE_PCRE8
7364PCRE_EXP_DECL pcre_jit_stack *
7365pcre_jit_stack_alloc(int startsize, int maxsize)
7366#else
7367PCRE_EXP_DECL pcre16_jit_stack *
7368pcre16_jit_stack_alloc(int startsize, int maxsize)
7369#endif
7370{
7371if (startsize < 1 || maxsize < 1)
7372  return NULL;
7373if (startsize > maxsize)
7374  startsize = maxsize;
7375startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
7376maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
7377return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
7378}
7379
7380#ifdef COMPILE_PCRE8
7381PCRE_EXP_DECL void
7382pcre_jit_stack_free(pcre_jit_stack *stack)
7383#else
7384PCRE_EXP_DECL void
7385pcre16_jit_stack_free(pcre16_jit_stack *stack)
7386#endif
7387{
7388sljit_free_stack((struct sljit_stack *)stack);
7389}
7390
7391#ifdef COMPILE_PCRE8
7392PCRE_EXP_DECL void
7393pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
7394#else
7395PCRE_EXP_DECL void
7396pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7397#endif
7398{
7399executable_functions *functions;
7400if (extra != NULL &&
7401    (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
7402    extra->executable_jit != NULL)
7403  {
7404  functions = (executable_functions *)extra->executable_jit;
7405  functions->callback = callback;
7406  functions->userdata = userdata;
7407  }
7408}
7409
7410#else  /* SUPPORT_JIT */
7411
7412/* These are dummy functions to avoid linking errors when JIT support is not
7413being compiled. */
7414
7415#ifdef COMPILE_PCRE8
7416PCRE_EXP_DECL pcre_jit_stack *
7417pcre_jit_stack_alloc(int startsize, int maxsize)
7418#else
7419PCRE_EXP_DECL pcre16_jit_stack *
7420pcre16_jit_stack_alloc(int startsize, int maxsize)
7421#endif
7422{
7423(void)startsize;
7424(void)maxsize;
7425return NULL;
7426}
7427
7428#ifdef COMPILE_PCRE8
7429PCRE_EXP_DECL void
7430pcre_jit_stack_free(pcre_jit_stack *stack)
7431#else
7432PCRE_EXP_DECL void
7433pcre16_jit_stack_free(pcre16_jit_stack *stack)
7434#endif
7435{
7436(void)stack;
7437}
7438
7439#ifdef COMPILE_PCRE8
7440PCRE_EXP_DECL void
7441pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
7442#else
7443PCRE_EXP_DECL void
7444pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7445#endif
7446{
7447(void)extra;
7448(void)callback;
7449(void)userdata;
7450}
7451
7452#endif
7453
7454/* End of pcre_jit_compile.c */
7455