new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / external / pcre2-10.32 / src / pcre2_jit_compile.c
1 /*************************************************
2 *      Perl-Compatible Regular Expressions       *
3 *************************************************/
4
5 /* PCRE is a library of functions to support regular expressions whose syntax
6 and semantics are as close as possible to those of the Perl 5 language.
7
8                        Written by Philip Hazel
9      Original API code Copyright (c) 1997-2012 University of Cambridge
10           New API code Copyright (c) 2016-2018 University of Cambridge
11
12 -----------------------------------------------------------------------------
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions are met:
15
16     * Redistributions of source code must retain the above copyright notice,
17       this list of conditions and the following disclaimer.
18
19     * Redistributions in binary form must reproduce the above copyright
20       notice, this list of conditions and the following disclaimer in the
21       documentation and/or other materials provided with the distribution.
22
23     * Neither the name of the University of Cambridge nor the names of its
24       contributors may be used to endorse or promote products derived from
25       this software without specific prior written permission.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 POSSIBILITY OF SUCH DAMAGE.
38 -----------------------------------------------------------------------------
39 */
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44
45 #include "pcre2_internal.h"
46
47 #ifdef SUPPORT_JIT
48
49 /* All-in-one: Since we use the JIT compiler only from here,
50 we just include it. This way we don't need to touch the build
51 system files. */
52
53 #define SLJIT_CONFIG_AUTO 1
54 #define SLJIT_CONFIG_STATIC 1
55 #define SLJIT_VERBOSE 0
56
57 #ifdef PCRE2_DEBUG
58 #define SLJIT_DEBUG 1
59 #else
60 #define SLJIT_DEBUG 0
61 #endif
62
63 #define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)
64 #define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)
65
66 static void * pcre2_jit_malloc(size_t size, void *allocator_data)
67 {
68 pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
69 return allocator->malloc(size, allocator->memory_data);
70 }
71
72 static void pcre2_jit_free(void *ptr, void *allocator_data)
73 {
74 pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
75 allocator->free(ptr, allocator->memory_data);
76 }
77
78 #include "sljit/sljitLir.c"
79
80 #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
81 #error Unsupported architecture
82 #endif
83
84 /* Defines for debugging purposes. */
85
86 /* 1 - Use unoptimized capturing brackets.
87    2 - Enable capture_last_ptr (includes option 1). */
88 /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
89
90 /* 1 - Always have a control head. */
91 /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
92
93 /* Allocate memory for the regex stack on the real machine stack.
94 Fast, but limited size. */
95 #define MACHINE_STACK_SIZE 32768
96
97 /* Growth rate for stack allocated by the OS. Should be the multiply
98 of page size. */
99 #define STACK_GROWTH_RATE 8192
100
101 /* Enable to check that the allocation could destroy temporaries. */
102 #if defined SLJIT_DEBUG && SLJIT_DEBUG
103 #define DESTROY_REGISTERS 1
104 #endif
105
106 /*
107 Short summary about the backtracking mechanism empolyed by the jit code generator:
108
109 The code generator follows the recursive nature of the PERL compatible regular
110 expressions. The basic blocks of regular expressions are condition checkers
111 whose execute different commands depending on the result of the condition check.
112 The relationship between the operators can be horizontal (concatenation) and
113 vertical (sub-expression) (See struct backtrack_common for more details).
114
115   'ab' - 'a' and 'b' regexps are concatenated
116   'a+' - 'a' is the sub-expression of the '+' operator
117
118 The condition checkers are boolean (true/false) checkers. Machine code is generated
119 for the checker itself and for the actions depending on the result of the checker.
120 The 'true' case is called as the matching path (expected path), and the other is called as
121 the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
122 branches on the matching path.
123
124  Greedy star operator (*) :
125    Matching path: match happens.
126    Backtrack path: match failed.
127  Non-greedy star operator (*?) :
128    Matching path: no need to perform a match.
129    Backtrack path: match is required.
130
131 The following example shows how the code generated for a capturing bracket
132 with two alternatives. Let A, B, C, D are arbirary regular expressions, and
133 we have the following regular expression:
134
135    A(B|C)D
136
137 The generated code will be the following:
138
139  A matching path
140  '(' matching path (pushing arguments to the stack)
141  B matching path
142  ')' matching path (pushing arguments to the stack)
143  D matching path
144  return with successful match
145
146  D backtrack path
147  ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
148  B backtrack path
149  C expected path
150  jump to D matching path
151  C backtrack path
152  A backtrack path
153
154  Notice, that the order of backtrack code paths are the opposite of the fast
155  code paths. In this way the topmost value on the stack is always belong
156  to the current backtrack code path. The backtrack path must check
157  whether there is a next alternative. If so, it needs to jump back to
158  the matching path eventually. Otherwise it needs to clear out its own stack
159  frame and continue the execution on the backtrack code paths.
160 */
161
162 /*
163 Saved stack frames:
164
165 Atomic blocks and asserts require reloading the values of private data
166 when the backtrack mechanism performed. Because of OP_RECURSE, the data
167 are not necessarly known in compile time, thus we need a dynamic restore
168 mechanism.
169
170 The stack frames are stored in a chain list, and have the following format:
171 ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
172
173 Thus we can restore the private data to a particular point in the stack.
174 */
175
176 typedef struct jit_arguments {
177   /* Pointers first. */
178   struct sljit_stack *stack;
179   PCRE2_SPTR str;
180   PCRE2_SPTR begin;
181   PCRE2_SPTR end;
182   pcre2_match_data *match_data;
183   PCRE2_SPTR startchar_ptr;
184   PCRE2_UCHAR *mark_ptr;
185   int (*callout)(pcre2_callout_block *, void *);
186   void *callout_data;
187   /* Everything else after. */
188   sljit_uw offset_limit;
189   sljit_u32 limit_match;
190   sljit_u32 oveccount;
191   sljit_u32 options;
192 } jit_arguments;
193
194 #define JIT_NUMBER_OF_COMPILE_MODES 3
195
196 typedef struct executable_functions {
197   void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
198   void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
199   sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
200   sljit_u32 top_bracket;
201   sljit_u32 limit_match;
202 } executable_functions;
203
204 typedef struct jump_list {
205   struct sljit_jump *jump;
206   struct jump_list *next;
207 } jump_list;
208
209 typedef struct stub_list {
210   struct sljit_jump *start;
211   struct sljit_label *quit;
212   struct stub_list *next;
213 } stub_list;
214
215 typedef struct label_addr_list {
216   struct sljit_label *label;
217   sljit_uw *update_addr;
218   struct label_addr_list *next;
219 } label_addr_list;
220
221 enum frame_types {
222   no_frame = -1,
223   no_stack = -2
224 };
225
226 enum control_types {
227   type_mark = 0,
228   type_then_trap = 1
229 };
230
231 typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
232
233 /* The following structure is the key data type for the recursive
234 code generator. It is allocated by compile_matchingpath, and contains
235 the arguments for compile_backtrackingpath. Must be the first member
236 of its descendants. */
237 typedef struct backtrack_common {
238   /* Concatenation stack. */
239   struct backtrack_common *prev;
240   jump_list *nextbacktracks;
241   /* Internal stack (for component operators). */
242   struct backtrack_common *top;
243   jump_list *topbacktracks;
244   /* Opcode pointer. */
245   PCRE2_SPTR cc;
246 } backtrack_common;
247
248 typedef struct assert_backtrack {
249   backtrack_common common;
250   jump_list *condfailed;
251   /* Less than 0 if a frame is not needed. */
252   int framesize;
253   /* Points to our private memory word on the stack. */
254   int private_data_ptr;
255   /* For iterators. */
256   struct sljit_label *matchingpath;
257 } assert_backtrack;
258
259 typedef struct bracket_backtrack {
260   backtrack_common common;
261   /* Where to coninue if an alternative is successfully matched. */
262   struct sljit_label *alternative_matchingpath;
263   /* For rmin and rmax iterators. */
264   struct sljit_label *recursive_matchingpath;
265   /* For greedy ? operator. */
266   struct sljit_label *zero_matchingpath;
267   /* Contains the branches of a failed condition. */
268   union {
269     /* Both for OP_COND, OP_SCOND. */
270     jump_list *condfailed;
271     assert_backtrack *assert;
272     /* For OP_ONCE. Less than 0 if not needed. */
273     int framesize;
274   } u;
275   /* Points to our private memory word on the stack. */
276   int private_data_ptr;
277 } bracket_backtrack;
278
279 typedef struct bracketpos_backtrack {
280   backtrack_common common;
281   /* Points to our private memory word on the stack. */
282   int private_data_ptr;
283   /* Reverting stack is needed. */
284   int framesize;
285   /* Allocated stack size. */
286   int stacksize;
287 } bracketpos_backtrack;
288
289 typedef struct braminzero_backtrack {
290   backtrack_common common;
291   struct sljit_label *matchingpath;
292 } braminzero_backtrack;
293
294 typedef struct char_iterator_backtrack {
295   backtrack_common common;
296   /* Next iteration. */
297   struct sljit_label *matchingpath;
298   union {
299     jump_list *backtracks;
300     struct {
301       unsigned int othercasebit;
302       PCRE2_UCHAR chr;
303       BOOL enabled;
304     } charpos;
305   } u;
306 } char_iterator_backtrack;
307
308 typedef struct ref_iterator_backtrack {
309   backtrack_common common;
310   /* Next iteration. */
311   struct sljit_label *matchingpath;
312 } ref_iterator_backtrack;
313
314 typedef struct recurse_entry {
315   struct recurse_entry *next;
316   /* Contains the function entry label. */
317   struct sljit_label *entry_label;
318   /* Contains the function entry label. */
319   struct sljit_label *backtrack_label;
320   /* Collects the entry calls until the function is not created. */
321   jump_list *entry_calls;
322   /* Collects the backtrack calls until the function is not created. */
323   jump_list *backtrack_calls;
324   /* Points to the starting opcode. */
325   sljit_sw start;
326 } recurse_entry;
327
328 typedef struct recurse_backtrack {
329   backtrack_common common;
330   /* Return to the matching path. */
331   struct sljit_label *matchingpath;
332   /* Recursive pattern. */
333   recurse_entry *entry;
334   /* Pattern is inlined. */
335   BOOL inlined_pattern;
336 } recurse_backtrack;
337
338 #define OP_THEN_TRAP OP_TABLE_LENGTH
339
340 typedef struct then_trap_backtrack {
341   backtrack_common common;
342   /* If then_trap is not NULL, this structure contains the real
343   then_trap for the backtracking path. */
344   struct then_trap_backtrack *then_trap;
345   /* Points to the starting opcode. */
346   sljit_sw start;
347   /* Exit point for the then opcodes of this alternative. */
348   jump_list *quit;
349   /* Frame size of the current alternative. */
350   int framesize;
351 } then_trap_backtrack;
352
353 #define MAX_N_CHARS 12
354 #define MAX_DIFF_CHARS 5
355
356 typedef struct fast_forward_char_data {
357   /* Number of characters in the chars array, 255 for any character. */
358   sljit_u8 count;
359   /* Number of last UTF-8 characters in the chars array. */
360   sljit_u8 last_count;
361   /* Available characters in the current position. */
362   PCRE2_UCHAR chars[MAX_DIFF_CHARS];
363 } fast_forward_char_data;
364
365 #define MAX_CLASS_RANGE_SIZE 4
366 #define MAX_CLASS_CHARS_SIZE 3
367
368 typedef struct compiler_common {
369   /* The sljit ceneric compiler. */
370   struct sljit_compiler *compiler;
371   /* Compiled regular expression. */
372   pcre2_real_code *re;
373   /* First byte code. */
374   PCRE2_SPTR start;
375   /* Maps private data offset to each opcode. */
376   sljit_s32 *private_data_ptrs;
377   /* Chain list of read-only data ptrs. */
378   void *read_only_data_head;
379   /* Tells whether the capturing bracket is optimized. */
380   sljit_u8 *optimized_cbracket;
381   /* Tells whether the starting offset is a target of then. */
382   sljit_u8 *then_offsets;
383   /* Current position where a THEN must jump. */
384   then_trap_backtrack *then_trap;
385   /* Starting offset of private data for capturing brackets. */
386   sljit_s32 cbra_ptr;
387   /* Output vector starting point. Must be divisible by 2. */
388   sljit_s32 ovector_start;
389   /* Points to the starting character of the current match. */
390   sljit_s32 start_ptr;
391   /* Last known position of the requested byte. */
392   sljit_s32 req_char_ptr;
393   /* Head of the last recursion. */
394   sljit_s32 recursive_head_ptr;
395   /* First inspected character for partial matching.
396      (Needed for avoiding zero length partial matches.) */
397   sljit_s32 start_used_ptr;
398   /* Starting pointer for partial soft matches. */
399   sljit_s32 hit_start;
400   /* Pointer of the match end position. */
401   sljit_s32 match_end_ptr;
402   /* Points to the marked string. */
403   sljit_s32 mark_ptr;
404   /* Recursive control verb management chain. */
405   sljit_s32 control_head_ptr;
406   /* Points to the last matched capture block index. */
407   sljit_s32 capture_last_ptr;
408   /* Fast forward skipping byte code pointer. */
409   PCRE2_SPTR fast_forward_bc_ptr;
410   /* Locals used by fast fail optimization. */
411   sljit_s32 fast_fail_start_ptr;
412   sljit_s32 fast_fail_end_ptr;
413
414   /* Flipped and lower case tables. */
415   const sljit_u8 *fcc;
416   sljit_sw lcc;
417   /* Mode can be PCRE2_JIT_COMPLETE and others. */
418   int mode;
419   /* TRUE, when minlength is greater than 0. */
420   BOOL might_be_empty;
421   /* \K is found in the pattern. */
422   BOOL has_set_som;
423   /* (*SKIP:arg) is found in the pattern. */
424   BOOL has_skip_arg;
425   /* (*THEN) is found in the pattern. */
426   BOOL has_then;
427   /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
428   BOOL has_skip_in_assert_back;
429   /* Quit is redirected by recurse, negative assertion, or positive assertion in conditional block. */
430   BOOL local_quit_available;
431   /* Currently in a positive assertion. */
432   BOOL in_positive_assertion;
433   /* Newline control. */
434   int nltype;
435   sljit_u32 nlmax;
436   sljit_u32 nlmin;
437   int newline;
438   int bsr_nltype;
439   sljit_u32 bsr_nlmax;
440   sljit_u32 bsr_nlmin;
441   /* Dollar endonly. */
442   int endonly;
443   /* Tables. */
444   sljit_sw ctypes;
445   /* Named capturing brackets. */
446   PCRE2_SPTR name_table;
447   sljit_sw name_count;
448   sljit_sw name_entry_size;
449
450   /* Labels and jump lists. */
451   struct sljit_label *partialmatchlabel;
452   struct sljit_label *quit_label;
453   struct sljit_label *abort_label;
454   struct sljit_label *accept_label;
455   struct sljit_label *ff_newline_shortcut;
456   stub_list *stubs;
457   label_addr_list *label_addrs;
458   recurse_entry *entries;
459   recurse_entry *currententry;
460   jump_list *partialmatch;
461   jump_list *quit;
462   jump_list *positive_assertion_quit;
463   jump_list *abort;
464   jump_list *failed_match;
465   jump_list *accept;
466   jump_list *calllimit;
467   jump_list *stackalloc;
468   jump_list *revertframes;
469   jump_list *wordboundary;
470   jump_list *anynewline;
471   jump_list *hspace;
472   jump_list *vspace;
473   jump_list *casefulcmp;
474   jump_list *caselesscmp;
475   jump_list *reset_match;
476   BOOL unset_backref;
477   BOOL alt_circumflex;
478 #ifdef SUPPORT_UNICODE
479   BOOL utf;
480   BOOL use_ucp;
481   jump_list *getucd;
482 #if PCRE2_CODE_UNIT_WIDTH == 8
483   jump_list *utfreadchar;
484   jump_list *utfreadchar16;
485   jump_list *utfreadtype8;
486 #endif
487 #endif /* SUPPORT_UNICODE */
488 } compiler_common;
489
490 /* For byte_sequence_compare. */
491
492 typedef struct compare_context {
493   int length;
494   int sourcereg;
495 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
496   int ucharptr;
497   union {
498     sljit_s32 asint;
499     sljit_u16 asushort;
500 #if PCRE2_CODE_UNIT_WIDTH == 8
501     sljit_u8 asbyte;
502     sljit_u8 asuchars[4];
503 #elif PCRE2_CODE_UNIT_WIDTH == 16
504     sljit_u16 asuchars[2];
505 #elif PCRE2_CODE_UNIT_WIDTH == 32
506     sljit_u32 asuchars[1];
507 #endif
508   } c;
509   union {
510     sljit_s32 asint;
511     sljit_u16 asushort;
512 #if PCRE2_CODE_UNIT_WIDTH == 8
513     sljit_u8 asbyte;
514     sljit_u8 asuchars[4];
515 #elif PCRE2_CODE_UNIT_WIDTH == 16
516     sljit_u16 asuchars[2];
517 #elif PCRE2_CODE_UNIT_WIDTH == 32
518     sljit_u32 asuchars[1];
519 #endif
520   } oc;
521 #endif
522 } compare_context;
523
524 /* Undefine sljit macros. */
525 #undef CMP
526
527 /* Used for accessing the elements of the stack. */
528 #define STACK(i)      ((i) * (int)sizeof(sljit_sw))
529
530 #ifdef SLJIT_PREF_SHIFT_REG
531 #if SLJIT_PREF_SHIFT_REG == SLJIT_R2
532 /* Nothing. */
533 #elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
534 #define SHIFT_REG_IS_R3
535 #else
536 #error "Unsupported shift register"
537 #endif
538 #endif
539
540 #define TMP1          SLJIT_R0
541 #ifdef SHIFT_REG_IS_R3
542 #define TMP2          SLJIT_R3
543 #define TMP3          SLJIT_R2
544 #else
545 #define TMP2          SLJIT_R2
546 #define TMP3          SLJIT_R3
547 #endif
548 #define STR_PTR       SLJIT_R1
549 #define STR_END       SLJIT_S0
550 #define STACK_TOP     SLJIT_S1
551 #define STACK_LIMIT   SLJIT_S2
552 #define COUNT_MATCH   SLJIT_S3
553 #define ARGUMENTS     SLJIT_S4
554 #define RETURN_ADDR   SLJIT_R4
555
556 /* Local space layout. */
557 /* These two locals can be used by the current opcode. */
558 #define LOCALS0          (0 * sizeof(sljit_sw))
559 #define LOCALS1          (1 * sizeof(sljit_sw))
560 /* Two local variables for possessive quantifiers (char1 cannot use them). */
561 #define POSSESSIVE0      (2 * sizeof(sljit_sw))
562 #define POSSESSIVE1      (3 * sizeof(sljit_sw))
563 /* Max limit of recursions. */
564 #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
565 /* The output vector is stored on the stack, and contains pointers
566 to characters. The vector data is divided into two groups: the first
567 group contains the start / end character pointers, and the second is
568 the start pointers when the end of the capturing group has not yet reached. */
569 #define OVECTOR_START    (common->ovector_start)
570 #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
571 #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
572 #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
573
574 #if PCRE2_CODE_UNIT_WIDTH == 8
575 #define MOV_UCHAR  SLJIT_MOV_U8
576 #define IN_UCHARS(x) (x)
577 #elif PCRE2_CODE_UNIT_WIDTH == 16
578 #define MOV_UCHAR  SLJIT_MOV_U16
579 #define UCHAR_SHIFT (1)
580 #define IN_UCHARS(x) ((x) * 2)
581 #elif PCRE2_CODE_UNIT_WIDTH == 32
582 #define MOV_UCHAR  SLJIT_MOV_U32
583 #define UCHAR_SHIFT (2)
584 #define IN_UCHARS(x) ((x) * 4)
585 #else
586 #error Unsupported compiling mode
587 #endif
588
589 /* Shortcuts. */
590 #define DEFINE_COMPILER \
591   struct sljit_compiler *compiler = common->compiler
592 #define OP1(op, dst, dstw, src, srcw) \
593   sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
594 #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
595   sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
596 #define LABEL() \
597   sljit_emit_label(compiler)
598 #define JUMP(type) \
599   sljit_emit_jump(compiler, (type))
600 #define JUMPTO(type, label) \
601   sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
602 #define JUMPHERE(jump) \
603   sljit_set_label((jump), sljit_emit_label(compiler))
604 #define SET_LABEL(jump, label) \
605   sljit_set_label((jump), (label))
606 #define CMP(type, src1, src1w, src2, src2w) \
607   sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
608 #define CMPTO(type, src1, src1w, src2, src2w, label) \
609   sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
610 #define OP_FLAGS(op, dst, dstw, type) \
611   sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type))
612 #define CMOV(type, dst_reg, src, srcw) \
613   sljit_emit_cmov(compiler, (type), (dst_reg), (src), (srcw))
614 #define GET_LOCAL_BASE(dst, dstw, offset) \
615   sljit_get_local_base(compiler, (dst), (dstw), (offset))
616
617 #define READ_CHAR_MAX 0x7fffffff
618
619 #define INVALID_UTF_CHAR 888
620
621 static PCRE2_SPTR bracketend(PCRE2_SPTR cc)
622 {
623 SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
624 do cc += GET(cc, 1); while (*cc == OP_ALT);
625 SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
626 cc += 1 + LINK_SIZE;
627 return cc;
628 }
629
630 static int no_alternatives(PCRE2_SPTR cc)
631 {
632 int count = 0;
633 SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
634 do
635   {
636   cc += GET(cc, 1);
637   count++;
638   }
639 while (*cc == OP_ALT);
640 SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
641 return count;
642 }
643
644 /* Functions whose might need modification for all new supported opcodes:
645  next_opcode
646  check_opcode_types
647  set_private_data_ptrs
648  get_framesize
649  init_frame
650  get_recurse_data_length
651  copy_recurse_data
652  compile_matchingpath
653  compile_backtrackingpath
654 */
655
656 static PCRE2_SPTR next_opcode(compiler_common *common, PCRE2_SPTR cc)
657 {
658 SLJIT_UNUSED_ARG(common);
659 switch(*cc)
660   {
661   case OP_SOD:
662   case OP_SOM:
663   case OP_SET_SOM:
664   case OP_NOT_WORD_BOUNDARY:
665   case OP_WORD_BOUNDARY:
666   case OP_NOT_DIGIT:
667   case OP_DIGIT:
668   case OP_NOT_WHITESPACE:
669   case OP_WHITESPACE:
670   case OP_NOT_WORDCHAR:
671   case OP_WORDCHAR:
672   case OP_ANY:
673   case OP_ALLANY:
674   case OP_NOTPROP:
675   case OP_PROP:
676   case OP_ANYNL:
677   case OP_NOT_HSPACE:
678   case OP_HSPACE:
679   case OP_NOT_VSPACE:
680   case OP_VSPACE:
681   case OP_EXTUNI:
682   case OP_EODN:
683   case OP_EOD:
684   case OP_CIRC:
685   case OP_CIRCM:
686   case OP_DOLL:
687   case OP_DOLLM:
688   case OP_CRSTAR:
689   case OP_CRMINSTAR:
690   case OP_CRPLUS:
691   case OP_CRMINPLUS:
692   case OP_CRQUERY:
693   case OP_CRMINQUERY:
694   case OP_CRRANGE:
695   case OP_CRMINRANGE:
696   case OP_CRPOSSTAR:
697   case OP_CRPOSPLUS:
698   case OP_CRPOSQUERY:
699   case OP_CRPOSRANGE:
700   case OP_CLASS:
701   case OP_NCLASS:
702   case OP_REF:
703   case OP_REFI:
704   case OP_DNREF:
705   case OP_DNREFI:
706   case OP_RECURSE:
707   case OP_CALLOUT:
708   case OP_ALT:
709   case OP_KET:
710   case OP_KETRMAX:
711   case OP_KETRMIN:
712   case OP_KETRPOS:
713   case OP_REVERSE:
714   case OP_ASSERT:
715   case OP_ASSERT_NOT:
716   case OP_ASSERTBACK:
717   case OP_ASSERTBACK_NOT:
718   case OP_ONCE:
719   case OP_BRA:
720   case OP_BRAPOS:
721   case OP_CBRA:
722   case OP_CBRAPOS:
723   case OP_COND:
724   case OP_SBRA:
725   case OP_SBRAPOS:
726   case OP_SCBRA:
727   case OP_SCBRAPOS:
728   case OP_SCOND:
729   case OP_CREF:
730   case OP_DNCREF:
731   case OP_RREF:
732   case OP_DNRREF:
733   case OP_FALSE:
734   case OP_TRUE:
735   case OP_BRAZERO:
736   case OP_BRAMINZERO:
737   case OP_BRAPOSZERO:
738   case OP_PRUNE:
739   case OP_SKIP:
740   case OP_THEN:
741   case OP_COMMIT:
742   case OP_FAIL:
743   case OP_ACCEPT:
744   case OP_ASSERT_ACCEPT:
745   case OP_CLOSE:
746   case OP_SKIPZERO:
747   return cc + PRIV(OP_lengths)[*cc];
748
749   case OP_CHAR:
750   case OP_CHARI:
751   case OP_NOT:
752   case OP_NOTI:
753   case OP_STAR:
754   case OP_MINSTAR:
755   case OP_PLUS:
756   case OP_MINPLUS:
757   case OP_QUERY:
758   case OP_MINQUERY:
759   case OP_UPTO:
760   case OP_MINUPTO:
761   case OP_EXACT:
762   case OP_POSSTAR:
763   case OP_POSPLUS:
764   case OP_POSQUERY:
765   case OP_POSUPTO:
766   case OP_STARI:
767   case OP_MINSTARI:
768   case OP_PLUSI:
769   case OP_MINPLUSI:
770   case OP_QUERYI:
771   case OP_MINQUERYI:
772   case OP_UPTOI:
773   case OP_MINUPTOI:
774   case OP_EXACTI:
775   case OP_POSSTARI:
776   case OP_POSPLUSI:
777   case OP_POSQUERYI:
778   case OP_POSUPTOI:
779   case OP_NOTSTAR:
780   case OP_NOTMINSTAR:
781   case OP_NOTPLUS:
782   case OP_NOTMINPLUS:
783   case OP_NOTQUERY:
784   case OP_NOTMINQUERY:
785   case OP_NOTUPTO:
786   case OP_NOTMINUPTO:
787   case OP_NOTEXACT:
788   case OP_NOTPOSSTAR:
789   case OP_NOTPOSPLUS:
790   case OP_NOTPOSQUERY:
791   case OP_NOTPOSUPTO:
792   case OP_NOTSTARI:
793   case OP_NOTMINSTARI:
794   case OP_NOTPLUSI:
795   case OP_NOTMINPLUSI:
796   case OP_NOTQUERYI:
797   case OP_NOTMINQUERYI:
798   case OP_NOTUPTOI:
799   case OP_NOTMINUPTOI:
800   case OP_NOTEXACTI:
801   case OP_NOTPOSSTARI:
802   case OP_NOTPOSPLUSI:
803   case OP_NOTPOSQUERYI:
804   case OP_NOTPOSUPTOI:
805   cc += PRIV(OP_lengths)[*cc];
806 #ifdef SUPPORT_UNICODE
807   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
808 #endif
809   return cc;
810
811   /* Special cases. */
812   case OP_TYPESTAR:
813   case OP_TYPEMINSTAR:
814   case OP_TYPEPLUS:
815   case OP_TYPEMINPLUS:
816   case OP_TYPEQUERY:
817   case OP_TYPEMINQUERY:
818   case OP_TYPEUPTO:
819   case OP_TYPEMINUPTO:
820   case OP_TYPEEXACT:
821   case OP_TYPEPOSSTAR:
822   case OP_TYPEPOSPLUS:
823   case OP_TYPEPOSQUERY:
824   case OP_TYPEPOSUPTO:
825   return cc + PRIV(OP_lengths)[*cc] - 1;
826
827   case OP_ANYBYTE:
828 #ifdef SUPPORT_UNICODE
829   if (common->utf) return NULL;
830 #endif
831   return cc + 1;
832
833   case OP_CALLOUT_STR:
834   return cc + GET(cc, 1 + 2*LINK_SIZE);
835
836 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
837   case OP_XCLASS:
838   return cc + GET(cc, 1);
839 #endif
840
841   case OP_MARK:
842   case OP_COMMIT_ARG:
843   case OP_PRUNE_ARG:
844   case OP_SKIP_ARG:
845   case OP_THEN_ARG:
846   return cc + 1 + 2 + cc[1];
847
848   default:
849   /* All opcodes are supported now! */
850   SLJIT_UNREACHABLE();
851   return NULL;
852   }
853 }
854
855 static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend)
856 {
857 int count;
858 PCRE2_SPTR slot;
859 PCRE2_SPTR assert_back_end = cc - 1;
860
861 /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
862 while (cc < ccend)
863   {
864   switch(*cc)
865     {
866     case OP_SET_SOM:
867     common->has_set_som = TRUE;
868     common->might_be_empty = TRUE;
869     cc += 1;
870     break;
871
872     case OP_REF:
873     case OP_REFI:
874     common->optimized_cbracket[GET2(cc, 1)] = 0;
875     cc += 1 + IMM2_SIZE;
876     break;
877
878     case OP_CBRAPOS:
879     case OP_SCBRAPOS:
880     common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
881     cc += 1 + LINK_SIZE + IMM2_SIZE;
882     break;
883
884     case OP_COND:
885     case OP_SCOND:
886     /* Only AUTO_CALLOUT can insert this opcode. We do
887        not intend to support this case. */
888     if (cc[1 + LINK_SIZE] == OP_CALLOUT || cc[1 + LINK_SIZE] == OP_CALLOUT_STR)
889       return FALSE;
890     cc += 1 + LINK_SIZE;
891     break;
892
893     case OP_CREF:
894     common->optimized_cbracket[GET2(cc, 1)] = 0;
895     cc += 1 + IMM2_SIZE;
896     break;
897
898     case OP_DNREF:
899     case OP_DNREFI:
900     case OP_DNCREF:
901     count = GET2(cc, 1 + IMM2_SIZE);
902     slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
903     while (count-- > 0)
904       {
905       common->optimized_cbracket[GET2(slot, 0)] = 0;
906       slot += common->name_entry_size;
907       }
908     cc += 1 + 2 * IMM2_SIZE;
909     break;
910
911     case OP_RECURSE:
912     /* Set its value only once. */
913     if (common->recursive_head_ptr == 0)
914       {
915       common->recursive_head_ptr = common->ovector_start;
916       common->ovector_start += sizeof(sljit_sw);
917       }
918     cc += 1 + LINK_SIZE;
919     break;
920
921     case OP_CALLOUT:
922     case OP_CALLOUT_STR:
923     if (common->capture_last_ptr == 0)
924       {
925       common->capture_last_ptr = common->ovector_start;
926       common->ovector_start += sizeof(sljit_sw);
927       }
928     cc += (*cc == OP_CALLOUT) ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2*LINK_SIZE);
929     break;
930
931     case OP_ASSERTBACK:
932     slot = bracketend(cc);
933     if (slot > assert_back_end)
934       assert_back_end = slot;
935     cc += 1 + LINK_SIZE;
936     break;
937
938     case OP_THEN_ARG:
939     common->has_then = TRUE;
940     common->control_head_ptr = 1;
941     /* Fall through. */
942
943     case OP_COMMIT_ARG:
944     case OP_PRUNE_ARG:
945     case OP_MARK:
946     if (common->mark_ptr == 0)
947       {
948       common->mark_ptr = common->ovector_start;
949       common->ovector_start += sizeof(sljit_sw);
950       }
951     cc += 1 + 2 + cc[1];
952     break;
953
954     case OP_THEN:
955     common->has_then = TRUE;
956     common->control_head_ptr = 1;
957     cc += 1;
958     break;
959
960     case OP_SKIP:
961     if (cc < assert_back_end)
962       common->has_skip_in_assert_back = TRUE;
963     cc += 1;
964     break;
965
966     case OP_SKIP_ARG:
967     common->control_head_ptr = 1;
968     common->has_skip_arg = TRUE;
969     if (cc < assert_back_end)
970       common->has_skip_in_assert_back = TRUE;
971     cc += 1 + 2 + cc[1];
972     break;
973
974     default:
975     cc = next_opcode(common, cc);
976     if (cc == NULL)
977       return FALSE;
978     break;
979     }
980   }
981 return TRUE;
982 }
983
984 static BOOL is_accelerated_repeat(PCRE2_SPTR cc)
985 {
986 switch(*cc)
987   {
988   case OP_TYPESTAR:
989   case OP_TYPEMINSTAR:
990   case OP_TYPEPLUS:
991   case OP_TYPEMINPLUS:
992   case OP_TYPEPOSSTAR:
993   case OP_TYPEPOSPLUS:
994   return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI);
995
996   case OP_STAR:
997   case OP_MINSTAR:
998   case OP_PLUS:
999   case OP_MINPLUS:
1000   case OP_POSSTAR:
1001   case OP_POSPLUS:
1002
1003   case OP_STARI:
1004   case OP_MINSTARI:
1005   case OP_PLUSI:
1006   case OP_MINPLUSI:
1007   case OP_POSSTARI:
1008   case OP_POSPLUSI:
1009
1010   case OP_NOTSTAR:
1011   case OP_NOTMINSTAR:
1012   case OP_NOTPLUS:
1013   case OP_NOTMINPLUS:
1014   case OP_NOTPOSSTAR:
1015   case OP_NOTPOSPLUS:
1016
1017   case OP_NOTSTARI:
1018   case OP_NOTMINSTARI:
1019   case OP_NOTPLUSI:
1020   case OP_NOTMINPLUSI:
1021   case OP_NOTPOSSTARI:
1022   case OP_NOTPOSPLUSI:
1023   return TRUE;
1024
1025   case OP_CLASS:
1026   case OP_NCLASS:
1027 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
1028   case OP_XCLASS:
1029   cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(PCRE2_UCHAR)));
1030 #else
1031   cc += (1 + (32 / sizeof(PCRE2_UCHAR)));
1032 #endif
1033
1034   switch(*cc)
1035     {
1036     case OP_CRSTAR:
1037     case OP_CRMINSTAR:
1038     case OP_CRPLUS:
1039     case OP_CRMINPLUS:
1040     case OP_CRPOSSTAR:
1041     case OP_CRPOSPLUS:
1042     return TRUE;
1043     }
1044   break;
1045   }
1046 return FALSE;
1047 }
1048
1049 static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start)
1050 {
1051 PCRE2_SPTR cc = common->start;
1052 PCRE2_SPTR end;
1053
1054 /* Skip not repeated brackets. */
1055 while (TRUE)
1056   {
1057   switch(*cc)
1058     {
1059     case OP_SOD:
1060     case OP_SOM:
1061     case OP_SET_SOM:
1062     case OP_NOT_WORD_BOUNDARY:
1063     case OP_WORD_BOUNDARY:
1064     case OP_EODN:
1065     case OP_EOD:
1066     case OP_CIRC:
1067     case OP_CIRCM:
1068     case OP_DOLL:
1069     case OP_DOLLM:
1070     /* Zero width assertions. */
1071     cc++;
1072     continue;
1073     }
1074
1075   if (*cc != OP_BRA && *cc != OP_CBRA)
1076     break;
1077
1078   end = cc + GET(cc, 1);
1079   if (*end != OP_KET || PRIVATE_DATA(end) != 0)
1080     return FALSE;
1081   if (*cc == OP_CBRA)
1082     {
1083     if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1084       return FALSE;
1085     cc += IMM2_SIZE;
1086     }
1087   cc += 1 + LINK_SIZE;
1088   }
1089
1090 if (is_accelerated_repeat(cc))
1091   {
1092   common->fast_forward_bc_ptr = cc;
1093   common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
1094   *private_data_start += sizeof(sljit_sw);
1095   return TRUE;
1096   }
1097 return FALSE;
1098 }
1099
1100 static SLJIT_INLINE void detect_fast_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth)
1101 {
1102   PCRE2_SPTR next_alt;
1103
1104   SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA);
1105
1106   if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1107     return;
1108
1109   next_alt = bracketend(cc) - (1 + LINK_SIZE);
1110   if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0)
1111     return;
1112
1113   do
1114     {
1115     next_alt = cc + GET(cc, 1);
1116
1117     cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
1118
1119     while (TRUE)
1120       {
1121       switch(*cc)
1122         {
1123         case OP_SOD:
1124         case OP_SOM:
1125         case OP_SET_SOM:
1126         case OP_NOT_WORD_BOUNDARY:
1127         case OP_WORD_BOUNDARY:
1128         case OP_EODN:
1129         case OP_EOD:
1130         case OP_CIRC:
1131         case OP_CIRCM:
1132         case OP_DOLL:
1133         case OP_DOLLM:
1134         /* Zero width assertions. */
1135         cc++;
1136         continue;
1137         }
1138       break;
1139       }
1140
1141     if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA))
1142       detect_fast_fail(common, cc, private_data_start, depth - 1);
1143
1144     if (is_accelerated_repeat(cc))
1145       {
1146       common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
1147
1148       if (common->fast_fail_start_ptr == 0)
1149         common->fast_fail_start_ptr = *private_data_start;
1150
1151       *private_data_start += sizeof(sljit_sw);
1152       common->fast_fail_end_ptr = *private_data_start;
1153
1154       if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
1155         return;
1156       }
1157
1158     cc = next_alt;
1159     }
1160   while (*cc == OP_ALT);
1161 }
1162
1163 static int get_class_iterator_size(PCRE2_SPTR cc)
1164 {
1165 sljit_u32 min;
1166 sljit_u32 max;
1167 switch(*cc)
1168   {
1169   case OP_CRSTAR:
1170   case OP_CRPLUS:
1171   return 2;
1172
1173   case OP_CRMINSTAR:
1174   case OP_CRMINPLUS:
1175   case OP_CRQUERY:
1176   case OP_CRMINQUERY:
1177   return 1;
1178
1179   case OP_CRRANGE:
1180   case OP_CRMINRANGE:
1181   min = GET2(cc, 1);
1182   max = GET2(cc, 1 + IMM2_SIZE);
1183   if (max == 0)
1184     return (*cc == OP_CRRANGE) ? 2 : 1;
1185   max -= min;
1186   if (max > 2)
1187     max = 2;
1188   return max;
1189
1190   default:
1191   return 0;
1192   }
1193 }
1194
1195 static BOOL detect_repeat(compiler_common *common, PCRE2_SPTR begin)
1196 {
1197 PCRE2_SPTR end = bracketend(begin);
1198 PCRE2_SPTR next;
1199 PCRE2_SPTR next_end;
1200 PCRE2_SPTR max_end;
1201 PCRE2_UCHAR type;
1202 sljit_sw length = end - begin;
1203 sljit_s32 min, max, i;
1204
1205 /* Detect fixed iterations first. */
1206 if (end[-(1 + LINK_SIZE)] != OP_KET)
1207   return FALSE;
1208
1209 /* Already detected repeat. */
1210 if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
1211   return TRUE;
1212
1213 next = end;
1214 min = 1;
1215 while (1)
1216   {
1217   if (*next != *begin)
1218     break;
1219   next_end = bracketend(next);
1220   if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
1221     break;
1222   next = next_end;
1223   min++;
1224   }
1225
1226 if (min == 2)
1227   return FALSE;
1228
1229 max = 0;
1230 max_end = next;
1231 if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
1232   {
1233   type = *next;
1234   while (1)
1235     {
1236     if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
1237       break;
1238     next_end = bracketend(next + 2 + LINK_SIZE);
1239     if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
1240       break;
1241     next = next_end;
1242     max++;
1243     }
1244
1245   if (next[0] == type && next[1] == *begin && max >= 1)
1246     {
1247     next_end = bracketend(next + 1);
1248     if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
1249       {
1250       for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
1251         if (*next_end != OP_KET)
1252           break;
1253
1254       if (i == max)
1255         {
1256         common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
1257         common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
1258         /* +2 the original and the last. */
1259         common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
1260         if (min == 1)
1261           return TRUE;
1262         min--;
1263         max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
1264         }
1265       }
1266     }
1267   }
1268
1269 if (min >= 3)
1270   {
1271   common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
1272   common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
1273   common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
1274   return TRUE;
1275   }
1276
1277 return FALSE;
1278 }
1279
1280 #define CASE_ITERATOR_PRIVATE_DATA_1 \
1281     case OP_MINSTAR: \
1282     case OP_MINPLUS: \
1283     case OP_QUERY: \
1284     case OP_MINQUERY: \
1285     case OP_MINSTARI: \
1286     case OP_MINPLUSI: \
1287     case OP_QUERYI: \
1288     case OP_MINQUERYI: \
1289     case OP_NOTMINSTAR: \
1290     case OP_NOTMINPLUS: \
1291     case OP_NOTQUERY: \
1292     case OP_NOTMINQUERY: \
1293     case OP_NOTMINSTARI: \
1294     case OP_NOTMINPLUSI: \
1295     case OP_NOTQUERYI: \
1296     case OP_NOTMINQUERYI:
1297
1298 #define CASE_ITERATOR_PRIVATE_DATA_2A \
1299     case OP_STAR: \
1300     case OP_PLUS: \
1301     case OP_STARI: \
1302     case OP_PLUSI: \
1303     case OP_NOTSTAR: \
1304     case OP_NOTPLUS: \
1305     case OP_NOTSTARI: \
1306     case OP_NOTPLUSI:
1307
1308 #define CASE_ITERATOR_PRIVATE_DATA_2B \
1309     case OP_UPTO: \
1310     case OP_MINUPTO: \
1311     case OP_UPTOI: \
1312     case OP_MINUPTOI: \
1313     case OP_NOTUPTO: \
1314     case OP_NOTMINUPTO: \
1315     case OP_NOTUPTOI: \
1316     case OP_NOTMINUPTOI:
1317
1318 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1319     case OP_TYPEMINSTAR: \
1320     case OP_TYPEMINPLUS: \
1321     case OP_TYPEQUERY: \
1322     case OP_TYPEMINQUERY:
1323
1324 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1325     case OP_TYPESTAR: \
1326     case OP_TYPEPLUS:
1327
1328 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1329     case OP_TYPEUPTO: \
1330     case OP_TYPEMINUPTO:
1331
1332 static void set_private_data_ptrs(compiler_common *common, int *private_data_start, PCRE2_SPTR ccend)
1333 {
1334 PCRE2_SPTR cc = common->start;
1335 PCRE2_SPTR alternative;
1336 PCRE2_SPTR end = NULL;
1337 int private_data_ptr = *private_data_start;
1338 int space, size, bracketlen;
1339 BOOL repeat_check = TRUE;
1340
1341 while (cc < ccend)
1342   {
1343   space = 0;
1344   size = 0;
1345   bracketlen = 0;
1346   if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1347     break;
1348
1349   if (repeat_check && (*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
1350     {
1351     if (detect_repeat(common, cc))
1352       {
1353       /* These brackets are converted to repeats, so no global
1354       based single character repeat is allowed. */
1355       if (cc >= end)
1356         end = bracketend(cc);
1357       }
1358     }
1359   repeat_check = TRUE;
1360
1361   switch(*cc)
1362     {
1363     case OP_KET:
1364     if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1365       {
1366       common->private_data_ptrs[cc - common->start] = private_data_ptr;
1367       private_data_ptr += sizeof(sljit_sw);
1368       cc += common->private_data_ptrs[cc + 1 - common->start];
1369       }
1370     cc += 1 + LINK_SIZE;
1371     break;
1372
1373     case OP_ASSERT:
1374     case OP_ASSERT_NOT:
1375     case OP_ASSERTBACK:
1376     case OP_ASSERTBACK_NOT:
1377     case OP_ONCE:
1378     case OP_BRAPOS:
1379     case OP_SBRA:
1380     case OP_SBRAPOS:
1381     case OP_SCOND:
1382     common->private_data_ptrs[cc - common->start] = private_data_ptr;
1383     private_data_ptr += sizeof(sljit_sw);
1384     bracketlen = 1 + LINK_SIZE;
1385     break;
1386
1387     case OP_CBRAPOS:
1388     case OP_SCBRAPOS:
1389     common->private_data_ptrs[cc - common->start] = private_data_ptr;
1390     private_data_ptr += sizeof(sljit_sw);
1391     bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1392     break;
1393
1394     case OP_COND:
1395     /* Might be a hidden SCOND. */
1396     alternative = cc + GET(cc, 1);
1397     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1398       {
1399       common->private_data_ptrs[cc - common->start] = private_data_ptr;
1400       private_data_ptr += sizeof(sljit_sw);
1401       }
1402     bracketlen = 1 + LINK_SIZE;
1403     break;
1404
1405     case OP_BRA:
1406     bracketlen = 1 + LINK_SIZE;
1407     break;
1408
1409     case OP_CBRA:
1410     case OP_SCBRA:
1411     bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1412     break;
1413
1414     case OP_BRAZERO:
1415     case OP_BRAMINZERO:
1416     case OP_BRAPOSZERO:
1417     repeat_check = FALSE;
1418     size = 1;
1419     break;
1420
1421     CASE_ITERATOR_PRIVATE_DATA_1
1422     space = 1;
1423     size = -2;
1424     break;
1425
1426     CASE_ITERATOR_PRIVATE_DATA_2A
1427     space = 2;
1428     size = -2;
1429     break;
1430
1431     CASE_ITERATOR_PRIVATE_DATA_2B
1432     space = 2;
1433     size = -(2 + IMM2_SIZE);
1434     break;
1435
1436     CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1437     space = 1;
1438     size = 1;
1439     break;
1440
1441     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1442     if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1443       space = 2;
1444     size = 1;
1445     break;
1446
1447     case OP_TYPEUPTO:
1448     if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1449       space = 2;
1450     size = 1 + IMM2_SIZE;
1451     break;
1452
1453     case OP_TYPEMINUPTO:
1454     space = 2;
1455     size = 1 + IMM2_SIZE;
1456     break;
1457
1458     case OP_CLASS:
1459     case OP_NCLASS:
1460     space = get_class_iterator_size(cc + size);
1461     size = 1 + 32 / sizeof(PCRE2_UCHAR);
1462     break;
1463
1464 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
1465     case OP_XCLASS:
1466     space = get_class_iterator_size(cc + size);
1467     size = GET(cc, 1);
1468     break;
1469 #endif
1470
1471     default:
1472     cc = next_opcode(common, cc);
1473     SLJIT_ASSERT(cc != NULL);
1474     break;
1475     }
1476
1477   /* Character iterators, which are not inside a repeated bracket,
1478      gets a private slot instead of allocating it on the stack. */
1479   if (space > 0 && cc >= end)
1480     {
1481     common->private_data_ptrs[cc - common->start] = private_data_ptr;
1482     private_data_ptr += sizeof(sljit_sw) * space;
1483     }
1484
1485   if (size != 0)
1486     {
1487     if (size < 0)
1488       {
1489       cc += -size;
1490 #ifdef SUPPORT_UNICODE
1491       if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1492 #endif
1493       }
1494     else
1495       cc += size;
1496     }
1497
1498   if (bracketlen > 0)
1499     {
1500     if (cc >= end)
1501       {
1502       end = bracketend(cc);
1503       if (end[-1 - LINK_SIZE] == OP_KET)
1504         end = NULL;
1505       }
1506     cc += bracketlen;
1507     }
1508   }
1509 *private_data_start = private_data_ptr;
1510 }
1511
1512 /* Returns with a frame_types (always < 0) if no need for frame. */
1513 static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head)
1514 {
1515 int length = 0;
1516 int possessive = 0;
1517 BOOL stack_restore = FALSE;
1518 BOOL setsom_found = recursive;
1519 BOOL setmark_found = recursive;
1520 /* The last capture is a local variable even for recursions. */
1521 BOOL capture_last_found = FALSE;
1522
1523 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1524 SLJIT_ASSERT(common->control_head_ptr != 0);
1525 *needs_control_head = TRUE;
1526 #else
1527 *needs_control_head = FALSE;
1528 #endif
1529
1530 if (ccend == NULL)
1531   {
1532   ccend = bracketend(cc) - (1 + LINK_SIZE);
1533   if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1534     {
1535     possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1536     /* This is correct regardless of common->capture_last_ptr. */
1537     capture_last_found = TRUE;
1538     }
1539   cc = next_opcode(common, cc);
1540   }
1541
1542 SLJIT_ASSERT(cc != NULL);
1543 while (cc < ccend)
1544   switch(*cc)
1545     {
1546     case OP_SET_SOM:
1547     SLJIT_ASSERT(common->has_set_som);
1548     stack_restore = TRUE;
1549     if (!setsom_found)
1550       {
1551       length += 2;
1552       setsom_found = TRUE;
1553       }
1554     cc += 1;
1555     break;
1556
1557     case OP_MARK:
1558     case OP_COMMIT_ARG:
1559     case OP_PRUNE_ARG:
1560     case OP_THEN_ARG:
1561     SLJIT_ASSERT(common->mark_ptr != 0);
1562     stack_restore = TRUE;
1563     if (!setmark_found)
1564       {
1565       length += 2;
1566       setmark_found = TRUE;
1567       }
1568     if (common->control_head_ptr != 0)
1569       *needs_control_head = TRUE;
1570     cc += 1 + 2 + cc[1];
1571     break;
1572
1573     case OP_RECURSE:
1574     stack_restore = TRUE;
1575     if (common->has_set_som && !setsom_found)
1576       {
1577       length += 2;
1578       setsom_found = TRUE;
1579       }
1580     if (common->mark_ptr != 0 && !setmark_found)
1581       {
1582       length += 2;
1583       setmark_found = TRUE;
1584       }
1585     if (common->capture_last_ptr != 0 && !capture_last_found)
1586       {
1587       length += 2;
1588       capture_last_found = TRUE;
1589       }
1590     cc += 1 + LINK_SIZE;
1591     break;
1592
1593     case OP_CBRA:
1594     case OP_CBRAPOS:
1595     case OP_SCBRA:
1596     case OP_SCBRAPOS:
1597     stack_restore = TRUE;
1598     if (common->capture_last_ptr != 0 && !capture_last_found)
1599       {
1600       length += 2;
1601       capture_last_found = TRUE;
1602       }
1603     length += 3;
1604     cc += 1 + LINK_SIZE + IMM2_SIZE;
1605     break;
1606
1607     case OP_THEN:
1608     stack_restore = TRUE;
1609     if (common->control_head_ptr != 0)
1610       *needs_control_head = TRUE;
1611     cc ++;
1612     break;
1613
1614     default:
1615     stack_restore = TRUE;
1616     /* Fall through. */
1617
1618     case OP_NOT_WORD_BOUNDARY:
1619     case OP_WORD_BOUNDARY:
1620     case OP_NOT_DIGIT:
1621     case OP_DIGIT:
1622     case OP_NOT_WHITESPACE:
1623     case OP_WHITESPACE:
1624     case OP_NOT_WORDCHAR:
1625     case OP_WORDCHAR:
1626     case OP_ANY:
1627     case OP_ALLANY:
1628     case OP_ANYBYTE:
1629     case OP_NOTPROP:
1630     case OP_PROP:
1631     case OP_ANYNL:
1632     case OP_NOT_HSPACE:
1633     case OP_HSPACE:
1634     case OP_NOT_VSPACE:
1635     case OP_VSPACE:
1636     case OP_EXTUNI:
1637     case OP_EODN:
1638     case OP_EOD:
1639     case OP_CIRC:
1640     case OP_CIRCM:
1641     case OP_DOLL:
1642     case OP_DOLLM:
1643     case OP_CHAR:
1644     case OP_CHARI:
1645     case OP_NOT:
1646     case OP_NOTI:
1647
1648     case OP_EXACT:
1649     case OP_POSSTAR:
1650     case OP_POSPLUS:
1651     case OP_POSQUERY:
1652     case OP_POSUPTO:
1653
1654     case OP_EXACTI:
1655     case OP_POSSTARI:
1656     case OP_POSPLUSI:
1657     case OP_POSQUERYI:
1658     case OP_POSUPTOI:
1659
1660     case OP_NOTEXACT:
1661     case OP_NOTPOSSTAR:
1662     case OP_NOTPOSPLUS:
1663     case OP_NOTPOSQUERY:
1664     case OP_NOTPOSUPTO:
1665
1666     case OP_NOTEXACTI:
1667     case OP_NOTPOSSTARI:
1668     case OP_NOTPOSPLUSI:
1669     case OP_NOTPOSQUERYI:
1670     case OP_NOTPOSUPTOI:
1671
1672     case OP_TYPEEXACT:
1673     case OP_TYPEPOSSTAR:
1674     case OP_TYPEPOSPLUS:
1675     case OP_TYPEPOSQUERY:
1676     case OP_TYPEPOSUPTO:
1677
1678     case OP_CLASS:
1679     case OP_NCLASS:
1680     case OP_XCLASS:
1681
1682     case OP_CALLOUT:
1683     case OP_CALLOUT_STR:
1684
1685     cc = next_opcode(common, cc);
1686     SLJIT_ASSERT(cc != NULL);
1687     break;
1688     }
1689
1690 /* Possessive quantifiers can use a special case. */
1691 if (SLJIT_UNLIKELY(possessive == length))
1692   return stack_restore ? no_frame : no_stack;
1693
1694 if (length > 0)
1695   return length + 1;
1696 return stack_restore ? no_frame : no_stack;
1697 }
1698
1699 static void init_frame(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, int stackpos, int stacktop)
1700 {
1701 DEFINE_COMPILER;
1702 BOOL setsom_found = FALSE;
1703 BOOL setmark_found = FALSE;
1704 /* The last capture is a local variable even for recursions. */
1705 BOOL capture_last_found = FALSE;
1706 int offset;
1707
1708 /* >= 1 + shortest item size (2) */
1709 SLJIT_UNUSED_ARG(stacktop);
1710 SLJIT_ASSERT(stackpos >= stacktop + 2);
1711
1712 stackpos = STACK(stackpos);
1713 if (ccend == NULL)
1714   {
1715   ccend = bracketend(cc) - (1 + LINK_SIZE);
1716   if (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)
1717     cc = next_opcode(common, cc);
1718   }
1719
1720 SLJIT_ASSERT(cc != NULL);
1721 while (cc < ccend)
1722   switch(*cc)
1723     {
1724     case OP_SET_SOM:
1725     SLJIT_ASSERT(common->has_set_som);
1726     if (!setsom_found)
1727       {
1728       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1729       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1730       stackpos -= (int)sizeof(sljit_sw);
1731       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1732       stackpos -= (int)sizeof(sljit_sw);
1733       setsom_found = TRUE;
1734       }
1735     cc += 1;
1736     break;
1737
1738     case OP_MARK:
1739     case OP_COMMIT_ARG:
1740     case OP_PRUNE_ARG:
1741     case OP_THEN_ARG:
1742     SLJIT_ASSERT(common->mark_ptr != 0);
1743     if (!setmark_found)
1744       {
1745       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1746       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1747       stackpos -= (int)sizeof(sljit_sw);
1748       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1749       stackpos -= (int)sizeof(sljit_sw);
1750       setmark_found = TRUE;
1751       }
1752     cc += 1 + 2 + cc[1];
1753     break;
1754
1755     case OP_RECURSE:
1756     if (common->has_set_som && !setsom_found)
1757       {
1758       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1759       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1760       stackpos -= (int)sizeof(sljit_sw);
1761       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1762       stackpos -= (int)sizeof(sljit_sw);
1763       setsom_found = TRUE;
1764       }
1765     if (common->mark_ptr != 0 && !setmark_found)
1766       {
1767       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1768       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1769       stackpos -= (int)sizeof(sljit_sw);
1770       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1771       stackpos -= (int)sizeof(sljit_sw);
1772       setmark_found = TRUE;
1773       }
1774     if (common->capture_last_ptr != 0 && !capture_last_found)
1775       {
1776       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1777       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1778       stackpos -= (int)sizeof(sljit_sw);
1779       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1780       stackpos -= (int)sizeof(sljit_sw);
1781       capture_last_found = TRUE;
1782       }
1783     cc += 1 + LINK_SIZE;
1784     break;
1785
1786     case OP_CBRA:
1787     case OP_CBRAPOS:
1788     case OP_SCBRA:
1789     case OP_SCBRAPOS:
1790     if (common->capture_last_ptr != 0 && !capture_last_found)
1791       {
1792       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1793       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1794       stackpos -= (int)sizeof(sljit_sw);
1795       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1796       stackpos -= (int)sizeof(sljit_sw);
1797       capture_last_found = TRUE;
1798       }
1799     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1800     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1801     stackpos -= (int)sizeof(sljit_sw);
1802     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
1803     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
1804     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1805     stackpos -= (int)sizeof(sljit_sw);
1806     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1807     stackpos -= (int)sizeof(sljit_sw);
1808
1809     cc += 1 + LINK_SIZE + IMM2_SIZE;
1810     break;
1811
1812     default:
1813     cc = next_opcode(common, cc);
1814     SLJIT_ASSERT(cc != NULL);
1815     break;
1816     }
1817
1818 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1819 SLJIT_ASSERT(stackpos == STACK(stacktop));
1820 }
1821
1822 #define RECURSE_TMP_REG_COUNT 3
1823
1824 typedef struct delayed_mem_copy_status {
1825   struct sljit_compiler *compiler;
1826   int store_bases[RECURSE_TMP_REG_COUNT];
1827   int store_offsets[RECURSE_TMP_REG_COUNT];
1828   int tmp_regs[RECURSE_TMP_REG_COUNT];
1829   int saved_tmp_regs[RECURSE_TMP_REG_COUNT];
1830   int next_tmp_reg;
1831 } delayed_mem_copy_status;
1832
1833 static void delayed_mem_copy_init(delayed_mem_copy_status *status, compiler_common *common)
1834 {
1835 int i;
1836
1837 for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
1838   {
1839   SLJIT_ASSERT(status->tmp_regs[i] >= 0);
1840   SLJIT_ASSERT(sljit_get_register_index(status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]);
1841
1842   status->store_bases[i] = -1;
1843   }
1844 status->next_tmp_reg = 0;
1845 status->compiler = common->compiler;
1846 }
1847
1848 static void delayed_mem_copy_move(delayed_mem_copy_status *status, int load_base, sljit_sw load_offset,
1849   int store_base, sljit_sw store_offset)
1850 {
1851 struct sljit_compiler *compiler = status->compiler;
1852 int next_tmp_reg = status->next_tmp_reg;
1853 int tmp_reg = status->tmp_regs[next_tmp_reg];
1854
1855 SLJIT_ASSERT(load_base > 0 && store_base > 0);
1856
1857 if (status->store_bases[next_tmp_reg] == -1)
1858   {
1859   /* Preserve virtual registers. */
1860   if (sljit_get_register_index(status->saved_tmp_regs[next_tmp_reg]) < 0)
1861     OP1(SLJIT_MOV, status->saved_tmp_regs[next_tmp_reg], 0, tmp_reg, 0);
1862   }
1863 else
1864   OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);
1865
1866 OP1(SLJIT_MOV, tmp_reg, 0, SLJIT_MEM1(load_base), load_offset);
1867 status->store_bases[next_tmp_reg] = store_base;
1868 status->store_offsets[next_tmp_reg] = store_offset;
1869
1870 status->next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
1871 }
1872
1873 static void delayed_mem_copy_finish(delayed_mem_copy_status *status)
1874 {
1875 struct sljit_compiler *compiler = status->compiler;
1876 int next_tmp_reg = status->next_tmp_reg;
1877 int tmp_reg, saved_tmp_reg, i;
1878
1879 for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
1880   {
1881   if (status->store_bases[next_tmp_reg] != -1)
1882     {
1883     tmp_reg = status->tmp_regs[next_tmp_reg];
1884     saved_tmp_reg = status->saved_tmp_regs[next_tmp_reg];
1885
1886     OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0);
1887
1888     /* Restore virtual registers. */
1889     if (sljit_get_register_index(saved_tmp_reg) < 0)
1890       OP1(SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0);
1891     }
1892
1893   next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
1894   }
1895 }
1896
1897 #undef RECURSE_TMP_REG_COUNT
1898
1899 static int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
1900   BOOL *needs_control_head, BOOL *has_quit, BOOL *has_accept)
1901 {
1902 int length = 1;
1903 int size;
1904 PCRE2_SPTR alternative;
1905 BOOL quit_found = FALSE;
1906 BOOL accept_found = FALSE;
1907 BOOL setsom_found = FALSE;
1908 BOOL setmark_found = FALSE;
1909 BOOL capture_last_found = FALSE;
1910 BOOL control_head_found = FALSE;
1911
1912 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1913 SLJIT_ASSERT(common->control_head_ptr != 0);
1914 control_head_found = TRUE;
1915 #endif
1916
1917 /* Calculate the sum of the private machine words. */
1918 while (cc < ccend)
1919   {
1920   size = 0;
1921   switch(*cc)
1922     {
1923     case OP_SET_SOM:
1924     SLJIT_ASSERT(common->has_set_som);
1925     setsom_found = TRUE;
1926     cc += 1;
1927     break;
1928
1929     case OP_RECURSE:
1930     if (common->has_set_som)
1931       setsom_found = TRUE;
1932     if (common->mark_ptr != 0)
1933       setmark_found = TRUE;
1934     if (common->capture_last_ptr != 0)
1935       capture_last_found = TRUE;
1936     cc += 1 + LINK_SIZE;
1937     break;
1938
1939     case OP_KET:
1940     if (PRIVATE_DATA(cc) != 0)
1941       {
1942       length++;
1943       SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
1944       cc += PRIVATE_DATA(cc + 1);
1945       }
1946     cc += 1 + LINK_SIZE;
1947     break;
1948
1949     case OP_ASSERT:
1950     case OP_ASSERT_NOT:
1951     case OP_ASSERTBACK:
1952     case OP_ASSERTBACK_NOT:
1953     case OP_ONCE:
1954     case OP_BRAPOS:
1955     case OP_SBRA:
1956     case OP_SBRAPOS:
1957     case OP_SCOND:
1958     length++;
1959     SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
1960     cc += 1 + LINK_SIZE;
1961     break;
1962
1963     case OP_CBRA:
1964     case OP_SCBRA:
1965     length += 2;
1966     if (common->capture_last_ptr != 0)
1967       capture_last_found = TRUE;
1968     if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1969       length++;
1970     cc += 1 + LINK_SIZE + IMM2_SIZE;
1971     break;
1972
1973     case OP_CBRAPOS:
1974     case OP_SCBRAPOS:
1975     length += 2 + 2;
1976     if (common->capture_last_ptr != 0)
1977       capture_last_found = TRUE;
1978     cc += 1 + LINK_SIZE + IMM2_SIZE;
1979     break;
1980
1981     case OP_COND:
1982     /* Might be a hidden SCOND. */
1983     alternative = cc + GET(cc, 1);
1984     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1985       length++;
1986     cc += 1 + LINK_SIZE;
1987     break;
1988
1989     CASE_ITERATOR_PRIVATE_DATA_1
1990     if (PRIVATE_DATA(cc) != 0)
1991       length++;
1992     cc += 2;
1993 #ifdef SUPPORT_UNICODE
1994     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1995 #endif
1996     break;
1997
1998     CASE_ITERATOR_PRIVATE_DATA_2A
1999     if (PRIVATE_DATA(cc) != 0)
2000       length += 2;
2001     cc += 2;
2002 #ifdef SUPPORT_UNICODE
2003     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2004 #endif
2005     break;
2006
2007     CASE_ITERATOR_PRIVATE_DATA_2B
2008     if (PRIVATE_DATA(cc) != 0)
2009       length += 2;
2010     cc += 2 + IMM2_SIZE;
2011 #ifdef SUPPORT_UNICODE
2012     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2013 #endif
2014     break;
2015
2016     CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2017     if (PRIVATE_DATA(cc) != 0)
2018       length++;
2019     cc += 1;
2020     break;
2021
2022     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2023     if (PRIVATE_DATA(cc) != 0)
2024       length += 2;
2025     cc += 1;
2026     break;
2027
2028     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2029     if (PRIVATE_DATA(cc) != 0)
2030       length += 2;
2031     cc += 1 + IMM2_SIZE;
2032     break;
2033
2034     case OP_CLASS:
2035     case OP_NCLASS:
2036 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
2037     case OP_XCLASS:
2038     size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
2039 #else
2040     size = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
2041 #endif
2042     if (PRIVATE_DATA(cc) != 0)
2043       length += get_class_iterator_size(cc + size);
2044     cc += size;
2045     break;
2046
2047     case OP_MARK:
2048     case OP_COMMIT_ARG:
2049     case OP_PRUNE_ARG:
2050     case OP_THEN_ARG:
2051     SLJIT_ASSERT(common->mark_ptr != 0);
2052     if (!setmark_found)
2053       setmark_found = TRUE;
2054     if (common->control_head_ptr != 0)
2055       control_head_found = TRUE;
2056     if (*cc != OP_MARK)
2057       quit_found = TRUE;
2058
2059     cc += 1 + 2 + cc[1];
2060     break;
2061
2062     case OP_PRUNE:
2063     case OP_SKIP:
2064     case OP_COMMIT:
2065     quit_found = TRUE;
2066     cc++;
2067     break;
2068
2069     case OP_SKIP_ARG:
2070     quit_found = TRUE;
2071     cc += 1 + 2 + cc[1];
2072     break;
2073
2074     case OP_THEN:
2075     SLJIT_ASSERT(common->control_head_ptr != 0);
2076     quit_found = TRUE;
2077     if (!control_head_found)
2078       control_head_found = TRUE;
2079     cc++;
2080     break;
2081
2082     case OP_ACCEPT:
2083     case OP_ASSERT_ACCEPT:
2084     accept_found = TRUE;
2085     cc++;
2086     break;
2087
2088     default:
2089     cc = next_opcode(common, cc);
2090     SLJIT_ASSERT(cc != NULL);
2091     break;
2092     }
2093   }
2094 SLJIT_ASSERT(cc == ccend);
2095
2096 if (control_head_found)
2097   length++;
2098 if (capture_last_found)
2099   length++;
2100 if (quit_found)
2101   {
2102   if (setsom_found)
2103     length++;
2104   if (setmark_found)
2105     length++;
2106   }
2107
2108 *needs_control_head = control_head_found;
2109 *has_quit = quit_found;
2110 *has_accept = accept_found;
2111 return length;
2112 }
2113
2114 enum copy_recurse_data_types {
2115   recurse_copy_from_global,
2116   recurse_copy_private_to_global,
2117   recurse_copy_shared_to_global,
2118   recurse_copy_kept_shared_to_global,
2119   recurse_swap_global
2120 };
2121
2122 static void copy_recurse_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend,
2123   int type, int stackptr, int stacktop, BOOL has_quit)
2124 {
2125 delayed_mem_copy_status status;
2126 PCRE2_SPTR alternative;
2127 sljit_sw private_srcw[2];
2128 sljit_sw shared_srcw[3];
2129 sljit_sw kept_shared_srcw[2];
2130 int private_count, shared_count, kept_shared_count;
2131 int from_sp, base_reg, offset, i;
2132 BOOL setsom_found = FALSE;
2133 BOOL setmark_found = FALSE;
2134 BOOL capture_last_found = FALSE;
2135 BOOL control_head_found = FALSE;
2136
2137 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
2138 SLJIT_ASSERT(common->control_head_ptr != 0);
2139 control_head_found = TRUE;
2140 #endif
2141
2142 switch (type)
2143   {
2144   case recurse_copy_from_global:
2145   from_sp = TRUE;
2146   base_reg = STACK_TOP;
2147   break;
2148
2149   case recurse_copy_private_to_global:
2150   case recurse_copy_shared_to_global:
2151   case recurse_copy_kept_shared_to_global:
2152   from_sp = FALSE;
2153   base_reg = STACK_TOP;
2154   break;
2155
2156   default:
2157   SLJIT_ASSERT(type == recurse_swap_global);
2158   from_sp = FALSE;
2159   base_reg = TMP2;
2160   break;
2161   }
2162
2163 stackptr = STACK(stackptr);
2164 stacktop = STACK(stacktop);
2165
2166 status.tmp_regs[0] = TMP1;
2167 status.saved_tmp_regs[0] = TMP1;
2168
2169 if (base_reg != TMP2)
2170   {
2171   status.tmp_regs[1] = TMP2;
2172   status.saved_tmp_regs[1] = TMP2;
2173   }
2174 else
2175   {
2176   status.saved_tmp_regs[1] = RETURN_ADDR;
2177   if (sljit_get_register_index (RETURN_ADDR) == -1)
2178     status.tmp_regs[1] = STR_PTR;
2179   else
2180     status.tmp_regs[1] = RETURN_ADDR;
2181   }
2182
2183 status.saved_tmp_regs[2] = TMP3;
2184 if (sljit_get_register_index (TMP3) == -1)
2185   status.tmp_regs[2] = STR_END;
2186 else
2187   status.tmp_regs[2] = TMP3;
2188
2189 delayed_mem_copy_init(&status, common);
2190
2191 if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
2192   {
2193   SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);
2194
2195   if (!from_sp)
2196     delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->recursive_head_ptr);
2197
2198   if (from_sp || type == recurse_swap_global)
2199     delayed_mem_copy_move(&status, SLJIT_SP, common->recursive_head_ptr, base_reg, stackptr);
2200   }
2201
2202 stackptr += sizeof(sljit_sw);
2203
2204 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
2205 if (type != recurse_copy_shared_to_global)
2206   {
2207   if (!from_sp)
2208     delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, common->control_head_ptr);
2209
2210   if (from_sp || type == recurse_swap_global)
2211     delayed_mem_copy_move(&status, SLJIT_SP, common->control_head_ptr, base_reg, stackptr);
2212   }
2213
2214 stackptr += sizeof(sljit_sw);
2215 #endif
2216
2217 while (cc < ccend)
2218   {
2219   private_count = 0;
2220   shared_count = 0;
2221   kept_shared_count = 0;
2222
2223   switch(*cc)
2224     {
2225     case OP_SET_SOM:
2226     SLJIT_ASSERT(common->has_set_som);
2227     if (has_quit && !setsom_found)
2228       {
2229       kept_shared_srcw[0] = OVECTOR(0);
2230       kept_shared_count = 1;
2231       setsom_found = TRUE;
2232       }
2233     cc += 1;
2234     break;
2235
2236     case OP_RECURSE:
2237     if (has_quit)
2238       {
2239       if (common->has_set_som && !setsom_found)
2240         {
2241         kept_shared_srcw[0] = OVECTOR(0);
2242         kept_shared_count = 1;
2243         setsom_found = TRUE;
2244         }
2245       if (common->mark_ptr != 0 && !setmark_found)
2246         {
2247         kept_shared_srcw[kept_shared_count] = common->mark_ptr;
2248         kept_shared_count++;
2249         setmark_found = TRUE;
2250         }
2251       }
2252     if (common->capture_last_ptr != 0 && !capture_last_found)
2253       {
2254       shared_srcw[0] = common->capture_last_ptr;
2255       shared_count = 1;
2256       capture_last_found = TRUE;
2257       }
2258     cc += 1 + LINK_SIZE;
2259     break;
2260
2261     case OP_KET:
2262     if (PRIVATE_DATA(cc) != 0)
2263       {
2264       private_count = 1;
2265       private_srcw[0] = PRIVATE_DATA(cc);
2266       SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
2267       cc += PRIVATE_DATA(cc + 1);
2268       }
2269     cc += 1 + LINK_SIZE;
2270     break;
2271
2272     case OP_ASSERT:
2273     case OP_ASSERT_NOT:
2274     case OP_ASSERTBACK:
2275     case OP_ASSERTBACK_NOT:
2276     case OP_ONCE:
2277     case OP_BRAPOS:
2278     case OP_SBRA:
2279     case OP_SBRAPOS:
2280     case OP_SCOND:
2281     private_count = 1;
2282     private_srcw[0] = PRIVATE_DATA(cc);
2283     cc += 1 + LINK_SIZE;
2284     break;
2285
2286     case OP_CBRA:
2287     case OP_SCBRA:
2288     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
2289     shared_srcw[0] = OVECTOR(offset);
2290     shared_srcw[1] = OVECTOR(offset + 1);
2291     shared_count = 2;
2292
2293     if (common->capture_last_ptr != 0 && !capture_last_found)
2294       {
2295       shared_srcw[2] = common->capture_last_ptr;
2296       shared_count = 3;
2297       capture_last_found = TRUE;
2298       }
2299
2300     if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
2301       {
2302       private_count = 1;
2303       private_srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
2304       }
2305     cc += 1 + LINK_SIZE + IMM2_SIZE;
2306     break;
2307
2308     case OP_CBRAPOS:
2309     case OP_SCBRAPOS:
2310     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
2311     shared_srcw[0] = OVECTOR(offset);
2312     shared_srcw[1] = OVECTOR(offset + 1);
2313     shared_count = 2;
2314
2315     if (common->capture_last_ptr != 0 && !capture_last_found)
2316       {
2317       shared_srcw[2] = common->capture_last_ptr;
2318       shared_count = 3;
2319       capture_last_found = TRUE;
2320       }
2321
2322     private_count = 2;
2323     private_srcw[0] = PRIVATE_DATA(cc);
2324     private_srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
2325     cc += 1 + LINK_SIZE + IMM2_SIZE;
2326     break;
2327
2328     case OP_COND:
2329     /* Might be a hidden SCOND. */
2330     alternative = cc + GET(cc, 1);
2331     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
2332       {
2333       private_count = 1;
2334       private_srcw[0] = PRIVATE_DATA(cc);
2335       }
2336     cc += 1 + LINK_SIZE;
2337     break;
2338
2339     CASE_ITERATOR_PRIVATE_DATA_1
2340     if (PRIVATE_DATA(cc))
2341       {
2342       private_count = 1;
2343       private_srcw[0] = PRIVATE_DATA(cc);
2344       }
2345     cc += 2;
2346 #ifdef SUPPORT_UNICODE
2347     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2348 #endif
2349     break;
2350
2351     CASE_ITERATOR_PRIVATE_DATA_2A
2352     if (PRIVATE_DATA(cc))
2353       {
2354       private_count = 2;
2355       private_srcw[0] = PRIVATE_DATA(cc);
2356       private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
2357       }
2358     cc += 2;
2359 #ifdef SUPPORT_UNICODE
2360     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2361 #endif
2362     break;
2363
2364     CASE_ITERATOR_PRIVATE_DATA_2B
2365     if (PRIVATE_DATA(cc))
2366       {
2367       private_count = 2;
2368       private_srcw[0] = PRIVATE_DATA(cc);
2369       private_srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
2370       }
2371     cc += 2 + IMM2_SIZE;
2372 #ifdef SUPPORT_UNICODE
2373     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2374 #endif
2375     break;
2376
2377     CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2378     if (PRIVATE_DATA(cc))
2379       {
2380       private_count = 1;
2381       private_srcw[0] = PRIVATE_DATA(cc);
2382       }
2383     cc += 1;
2384     break;
2385
2386     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2387     if (PRIVATE_DATA(cc))
2388       {
2389       private_count = 2;
2390       private_srcw[0] = PRIVATE_DATA(cc);
2391       private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
2392       }
2393     cc += 1;
2394     break;
2395
2396     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2397     if (PRIVATE_DATA(cc))
2398       {
2399       private_count = 2;
2400       private_srcw[0] = PRIVATE_DATA(cc);
2401       private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
2402       }
2403     cc += 1 + IMM2_SIZE;
2404     break;
2405
2406     case OP_CLASS:
2407     case OP_NCLASS:
2408 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
2409     case OP_XCLASS:
2410     i = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(PCRE2_UCHAR);
2411 #else
2412     i = 1 + 32 / (int)sizeof(PCRE2_UCHAR);
2413 #endif
2414     if (PRIVATE_DATA(cc) != 0)
2415       switch(get_class_iterator_size(cc + i))
2416         {
2417         case 1:
2418         private_count = 1;
2419         private_srcw[0] = PRIVATE_DATA(cc);
2420         break;
2421
2422         case 2:
2423         private_count = 2;
2424         private_srcw[0] = PRIVATE_DATA(cc);
2425         private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
2426         break;
2427
2428         default:
2429         SLJIT_UNREACHABLE();
2430         break;
2431         }
2432     cc += i;
2433     break;
2434
2435     case OP_MARK:
2436     case OP_COMMIT_ARG:
2437     case OP_PRUNE_ARG:
2438     case OP_THEN_ARG:
2439     SLJIT_ASSERT(common->mark_ptr != 0);
2440     if (has_quit && !setmark_found)
2441       {
2442       kept_shared_srcw[0] = common->mark_ptr;
2443       kept_shared_count = 1;
2444       setmark_found = TRUE;
2445       }
2446     if (common->control_head_ptr != 0 && !control_head_found)
2447       {
2448       shared_srcw[0] = common->control_head_ptr;
2449       shared_count = 1;
2450       control_head_found = TRUE;
2451       }
2452     cc += 1 + 2 + cc[1];
2453     break;
2454
2455     case OP_THEN:
2456     SLJIT_ASSERT(common->control_head_ptr != 0);
2457     if (!control_head_found)
2458       {
2459       shared_srcw[0] = common->control_head_ptr;
2460       shared_count = 1;
2461       control_head_found = TRUE;
2462       }
2463     cc++;
2464     break;
2465
2466     default:
2467     cc = next_opcode(common, cc);
2468     SLJIT_ASSERT(cc != NULL);
2469     break;
2470     }
2471
2472   if (type != recurse_copy_shared_to_global && type != recurse_copy_kept_shared_to_global)
2473     {
2474     SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_private_to_global || type == recurse_swap_global);
2475
2476     for (i = 0; i < private_count; i++)
2477       {
2478       SLJIT_ASSERT(private_srcw[i] != 0);
2479
2480       if (!from_sp)
2481         delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, private_srcw[i]);
2482
2483       if (from_sp || type == recurse_swap_global)
2484         delayed_mem_copy_move(&status, SLJIT_SP, private_srcw[i], base_reg, stackptr);
2485
2486       stackptr += sizeof(sljit_sw);
2487       }
2488     }
2489   else
2490     stackptr += sizeof(sljit_sw) * private_count;
2491
2492   if (type != recurse_copy_private_to_global && type != recurse_copy_kept_shared_to_global)
2493     {
2494     SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_swap_global);
2495
2496     for (i = 0; i < shared_count; i++)
2497       {
2498       SLJIT_ASSERT(shared_srcw[i] != 0);
2499
2500       if (!from_sp)
2501         delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, shared_srcw[i]);
2502
2503       if (from_sp || type == recurse_swap_global)
2504         delayed_mem_copy_move(&status, SLJIT_SP, shared_srcw[i], base_reg, stackptr);
2505
2506       stackptr += sizeof(sljit_sw);
2507       }
2508     }
2509   else
2510     stackptr += sizeof(sljit_sw) * shared_count;
2511
2512   if (type != recurse_copy_private_to_global && type != recurse_swap_global)
2513     {
2514     SLJIT_ASSERT(type == recurse_copy_from_global || type == recurse_copy_shared_to_global || type == recurse_copy_kept_shared_to_global);
2515
2516     for (i = 0; i < kept_shared_count; i++)
2517       {
2518       SLJIT_ASSERT(kept_shared_srcw[i] != 0);
2519
2520       if (!from_sp)
2521         delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, kept_shared_srcw[i]);
2522
2523       if (from_sp || type == recurse_swap_global)
2524         delayed_mem_copy_move(&status, SLJIT_SP, kept_shared_srcw[i], base_reg, stackptr);
2525
2526       stackptr += sizeof(sljit_sw);
2527       }
2528     }
2529   else
2530     stackptr += sizeof(sljit_sw) * kept_shared_count;
2531   }
2532
2533 SLJIT_ASSERT(cc == ccend && stackptr == stacktop);
2534
2535 delayed_mem_copy_finish(&status);
2536 }
2537
2538 static SLJIT_INLINE PCRE2_SPTR set_then_offsets(compiler_common *common, PCRE2_SPTR cc, sljit_u8 *current_offset)
2539 {
2540 PCRE2_SPTR end = bracketend(cc);
2541 BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
2542
2543 /* Assert captures then. */
2544 if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
2545   current_offset = NULL;
2546 /* Conditional block does not. */
2547 if (*cc == OP_COND || *cc == OP_SCOND)
2548   has_alternatives = FALSE;
2549
2550 cc = next_opcode(common, cc);
2551 if (has_alternatives)
2552   current_offset = common->then_offsets + (cc - common->start);
2553
2554 while (cc < end)
2555   {
2556   if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
2557     cc = set_then_offsets(common, cc, current_offset);
2558   else
2559     {
2560     if (*cc == OP_ALT && has_alternatives)
2561       current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
2562     if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
2563       *current_offset = 1;
2564     cc = next_opcode(common, cc);
2565     }
2566   }
2567
2568 return end;
2569 }
2570
2571 #undef CASE_ITERATOR_PRIVATE_DATA_1
2572 #undef CASE_ITERATOR_PRIVATE_DATA_2A
2573 #undef CASE_ITERATOR_PRIVATE_DATA_2B
2574 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2575 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2576 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2577
2578 static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
2579 {
2580 return (value & (value - 1)) == 0;
2581 }
2582
2583 static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
2584 {
2585 while (list)
2586   {
2587   /* sljit_set_label is clever enough to do nothing
2588   if either the jump or the label is NULL. */
2589   SET_LABEL(list->jump, label);
2590   list = list->next;
2591   }
2592 }
2593
2594 static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)
2595 {
2596 jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
2597 if (list_item)
2598   {
2599   list_item->next = *list;
2600   list_item->jump = jump;
2601   *list = list_item;
2602   }
2603 }
2604
2605 static void add_stub(compiler_common *common, struct sljit_jump *start)
2606 {
2607 DEFINE_COMPILER;
2608 stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
2609
2610 if (list_item)
2611   {
2612   list_item->start = start;
2613   list_item->quit = LABEL();
2614   list_item->next = common->stubs;
2615   common->stubs = list_item;
2616   }
2617 }
2618
2619 static void flush_stubs(compiler_common *common)
2620 {
2621 DEFINE_COMPILER;
2622 stub_list *list_item = common->stubs;
2623
2624 while (list_item)
2625   {
2626   JUMPHERE(list_item->start);
2627   add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
2628   JUMPTO(SLJIT_JUMP, list_item->quit);
2629   list_item = list_item->next;
2630   }
2631 common->stubs = NULL;
2632 }
2633
2634 static void add_label_addr(compiler_common *common, sljit_uw *update_addr)
2635 {
2636 DEFINE_COMPILER;
2637 label_addr_list *label_addr;
2638
2639 label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
2640 if (label_addr == NULL)
2641   return;
2642 label_addr->label = LABEL();
2643 label_addr->update_addr = update_addr;
2644 label_addr->next = common->label_addrs;
2645 common->label_addrs = label_addr;
2646 }
2647
2648 static SLJIT_INLINE void count_match(compiler_common *common)
2649 {
2650 DEFINE_COMPILER;
2651
2652 OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
2653 add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
2654 }
2655
2656 static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
2657 {
2658 /* May destroy all locals and registers except TMP2. */
2659 DEFINE_COMPILER;
2660
2661 SLJIT_ASSERT(size > 0);
2662 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2663 #ifdef DESTROY_REGISTERS
2664 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
2665 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2666 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2667 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
2668 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
2669 #endif
2670 add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));
2671 }
2672
2673 static SLJIT_INLINE void free_stack(compiler_common *common, int size)
2674 {
2675 DEFINE_COMPILER;
2676
2677 SLJIT_ASSERT(size > 0);
2678 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2679 }
2680
2681 static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
2682 {
2683 DEFINE_COMPILER;
2684 sljit_uw *result;
2685
2686 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
2687   return NULL;
2688
2689 result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
2690 if (SLJIT_UNLIKELY(result == NULL))
2691   {
2692   sljit_set_compiler_memory_error(compiler);
2693   return NULL;
2694   }
2695
2696 *(void**)result = common->read_only_data_head;
2697 common->read_only_data_head = (void *)result;
2698 return result + 1;
2699 }
2700
2701 static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
2702 {
2703 DEFINE_COMPILER;
2704 struct sljit_label *loop;
2705 sljit_s32 i;
2706
2707 /* At this point we can freely use all temporary registers. */
2708 SLJIT_ASSERT(length > 1);
2709 /* TMP1 returns with begin - 1. */
2710 OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2711 if (length < 8)
2712   {
2713   for (i = 1; i < length; i++)
2714     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
2715   }
2716 else
2717   {
2718   if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)
2719     {
2720     GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
2721     OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
2722     loop = LABEL();
2723     sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));
2724     OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
2725     JUMPTO(SLJIT_NOT_ZERO, loop);
2726     }
2727   else
2728     {
2729     GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));
2730     OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
2731     loop = LABEL();
2732     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);
2733     OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));
2734     OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
2735     JUMPTO(SLJIT_NOT_ZERO, loop);
2736     }
2737   }
2738 }
2739
2740 static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
2741 {
2742 DEFINE_COMPILER;
2743 sljit_s32 i;
2744
2745 SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);
2746
2747 OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2748 for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
2749   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
2750 }
2751
2752 static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2753 {
2754 DEFINE_COMPILER;
2755 struct sljit_label *loop;
2756 int i;
2757
2758 SLJIT_ASSERT(length > 1);
2759 /* OVECTOR(1) contains the "string begin - 1" constant. */
2760 if (length > 2)
2761   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
2762 if (length < 8)
2763   {
2764   for (i = 2; i < length; i++)
2765     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
2766   }
2767 else
2768   {
2769   if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)
2770     {
2771     GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2772     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2773     loop = LABEL();
2774     sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
2775     OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2776     JUMPTO(SLJIT_NOT_ZERO, loop);
2777     }
2778   else
2779     {
2780     GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));
2781     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2782     loop = LABEL();
2783     OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
2784     OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));
2785     OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2786     JUMPTO(SLJIT_NOT_ZERO, loop);
2787     }
2788   }
2789
2790 OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2791 if (common->mark_ptr != 0)
2792   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
2793 if (common->control_head_ptr != 0)
2794   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
2795 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2796 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
2797 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
2798 }
2799
2800 static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
2801 {
2802 while (current != NULL)
2803   {
2804   switch (current[1])
2805     {
2806     case type_then_trap:
2807     break;
2808
2809     case type_mark:
2810     if (PRIV(strcmp)(skip_arg, (PCRE2_SPTR)current[2]) == 0)
2811       return current[3];
2812     break;
2813
2814     default:
2815     SLJIT_UNREACHABLE();
2816     break;
2817     }
2818   SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
2819   current = (sljit_sw*)current[0];
2820   }
2821 return 0;
2822 }
2823
2824 static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2825 {
2826 DEFINE_COMPILER;
2827 struct sljit_label *loop;
2828 BOOL has_pre;
2829
2830 /* At this point we can freely use all registers. */
2831 OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
2832 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
2833
2834 OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
2835 OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
2836 if (common->mark_ptr != 0)
2837   OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
2838 OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));
2839 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
2840 if (common->mark_ptr != 0)
2841   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
2842 OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),
2843   SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
2844
2845 has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
2846
2847 GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
2848 OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
2849
2850 loop = LABEL();
2851
2852 if (has_pre)
2853   sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));
2854 else
2855   {
2856   OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);
2857   OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
2858   }
2859
2860 OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(PCRE2_SIZE));
2861 OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);
2862 /* Copy the integer value to the output buffer */
2863 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
2864 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
2865 #endif
2866
2867 SLJIT_ASSERT(sizeof(PCRE2_SIZE) == 4 || sizeof(PCRE2_SIZE) == 8);
2868 OP1(((sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV), SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);
2869
2870 OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2871 JUMPTO(SLJIT_NOT_ZERO, loop);
2872
2873 /* Calculate the return value, which is the maximum ovector value. */
2874 if (topbracket > 1)
2875   {
2876   if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))) == SLJIT_SUCCESS)
2877     {
2878     GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
2879     OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
2880
2881     /* OVECTOR(0) is never equal to SLJIT_S2. */
2882     loop = LABEL();
2883     sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
2884     OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2885     CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
2886     OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
2887     }
2888   else
2889     {
2890     GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));
2891     OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
2892
2893     /* OVECTOR(0) is never equal to SLJIT_S2. */
2894     loop = LABEL();
2895     OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);
2896     OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * (sljit_sw)sizeof(sljit_sw));
2897     OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2898     CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
2899     OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
2900     }
2901   }
2902 else
2903   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
2904 }
2905
2906 static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
2907 {
2908 DEFINE_COMPILER;
2909 sljit_s32 mov_opcode;
2910
2911 SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0);
2912 SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2913   && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
2914
2915 OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
2916 OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),
2917   common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr);
2918 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
2919
2920 /* Store match begin and end. */
2921 OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
2922 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
2923 OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data));
2924
2925 mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
2926
2927 OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S1, 0);
2928 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
2929 OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
2930 #endif
2931 OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);
2932
2933 OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S1, 0);
2934 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
2935 OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);
2936 #endif
2937 OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector) + sizeof(PCRE2_SIZE), STR_END, 0);
2938
2939 JUMPTO(SLJIT_JUMP, quit);
2940 }
2941
2942 static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
2943 {
2944 /* May destroy TMP1. */
2945 DEFINE_COMPILER;
2946 struct sljit_jump *jump;
2947
2948 if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
2949   {
2950   /* The value of -1 must be kept for start_used_ptr! */
2951   OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);
2952   /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
2953   is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
2954   jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
2955   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2956   JUMPHERE(jump);
2957   }
2958 else if (common->mode == PCRE2_JIT_PARTIAL_HARD)
2959   {
2960   jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2961   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2962   JUMPHERE(jump);
2963   }
2964 }
2965
2966 static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, PCRE2_SPTR cc)
2967 {
2968 /* Detects if the character has an othercase. */
2969 unsigned int c;
2970
2971 #ifdef SUPPORT_UNICODE
2972 if (common->utf)
2973   {
2974   GETCHAR(c, cc);
2975   if (c > 127)
2976     {
2977     return c != UCD_OTHERCASE(c);
2978     }
2979 #if PCRE2_CODE_UNIT_WIDTH != 8
2980   return common->fcc[c] != c;
2981 #endif
2982   }
2983 else
2984 #endif
2985   c = *cc;
2986 return MAX_255(c) ? common->fcc[c] != c : FALSE;
2987 }
2988
2989 static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
2990 {
2991 /* Returns with the othercase. */
2992 #ifdef SUPPORT_UNICODE
2993 if (common->utf && c > 127)
2994   {
2995   return UCD_OTHERCASE(c);
2996   }
2997 #endif
2998 return TABLE_GET(c, common->fcc, c);
2999 }
3000
3001 static unsigned int char_get_othercase_bit(compiler_common *common, PCRE2_SPTR cc)
3002 {
3003 /* Detects if the character and its othercase has only 1 bit difference. */
3004 unsigned int c, oc, bit;
3005 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3006 int n;
3007 #endif
3008
3009 #ifdef SUPPORT_UNICODE
3010 if (common->utf)
3011   {
3012   GETCHAR(c, cc);
3013   if (c <= 127)
3014     oc = common->fcc[c];
3015   else
3016     {
3017     oc = UCD_OTHERCASE(c);
3018     }
3019   }
3020 else
3021   {
3022   c = *cc;
3023   oc = TABLE_GET(c, common->fcc, c);
3024   }
3025 #else
3026 c = *cc;
3027 oc = TABLE_GET(c, common->fcc, c);
3028 #endif
3029
3030 SLJIT_ASSERT(c != oc);
3031
3032 bit = c ^ oc;
3033 /* Optimized for English alphabet. */
3034 if (c <= 127 && bit == 0x20)
3035   return (0 << 8) | 0x20;
3036
3037 /* Since c != oc, they must have at least 1 bit difference. */
3038 if (!is_powerof2(bit))
3039   return 0;
3040
3041 #if PCRE2_CODE_UNIT_WIDTH == 8
3042
3043 #ifdef SUPPORT_UNICODE
3044 if (common->utf && c > 127)
3045   {
3046   n = GET_EXTRALEN(*cc);
3047   while ((bit & 0x3f) == 0)
3048     {
3049     n--;
3050     bit >>= 6;
3051     }
3052   return (n << 8) | bit;
3053   }
3054 #endif /* SUPPORT_UNICODE */
3055 return (0 << 8) | bit;
3056
3057 #elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
3058
3059 #ifdef SUPPORT_UNICODE
3060 if (common->utf && c > 65535)
3061   {
3062   if (bit >= (1 << 10))
3063     bit >>= 10;
3064   else
3065     return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
3066   }
3067 #endif /* SUPPORT_UNICODE */
3068 return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
3069
3070 #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
3071 }
3072
3073 static void check_partial(compiler_common *common, BOOL force)
3074 {
3075 /* Checks whether a partial matching is occurred. Does not modify registers. */
3076 DEFINE_COMPILER;
3077 struct sljit_jump *jump = NULL;
3078
3079 SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE);
3080
3081 if (common->mode == PCRE2_JIT_COMPLETE)
3082   return;
3083
3084 if (!force)
3085   jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
3086 else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
3087   jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
3088
3089 if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
3090   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
3091 else
3092   {
3093   if (common->partialmatchlabel != NULL)
3094     JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
3095   else
3096     add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
3097   }
3098
3099 if (jump != NULL)
3100   JUMPHERE(jump);
3101 }
3102
3103 static void check_str_end(compiler_common *common, jump_list **end_reached)
3104 {
3105 /* Does not affect registers. Usually used in a tight spot. */
3106 DEFINE_COMPILER;
3107 struct sljit_jump *jump;
3108
3109 if (common->mode == PCRE2_JIT_COMPLETE)
3110   {
3111   add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
3112   return;
3113   }
3114
3115 jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
3116 if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
3117   {
3118   add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
3119   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
3120   add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
3121   }
3122 else
3123   {
3124   add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
3125   if (common->partialmatchlabel != NULL)
3126     JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
3127   else
3128     add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
3129   }
3130 JUMPHERE(jump);
3131 }
3132
3133 static void detect_partial_match(compiler_common *common, jump_list **backtracks)
3134 {
3135 DEFINE_COMPILER;
3136 struct sljit_jump *jump;
3137
3138 if (common->mode == PCRE2_JIT_COMPLETE)
3139   {
3140   add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
3141   return;
3142   }
3143
3144 /* Partial matching mode. */
3145 jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
3146 add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
3147 if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
3148   {
3149   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
3150   add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3151   }
3152 else
3153   {
3154   if (common->partialmatchlabel != NULL)
3155     JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
3156   else
3157     add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
3158   }
3159 JUMPHERE(jump);
3160 }
3161
3162 static void peek_char(compiler_common *common, sljit_u32 max)
3163 {
3164 /* Reads the character into TMP1, keeps STR_PTR.
3165 Does not check STR_END. TMP2 Destroyed. */
3166 DEFINE_COMPILER;
3167 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3168 struct sljit_jump *jump;
3169 #endif
3170
3171 SLJIT_UNUSED_ARG(max);
3172
3173 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3174 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3175 if (common->utf)
3176   {
3177   if (max < 128) return;
3178
3179   jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3180   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3181   add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
3182   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3183   JUMPHERE(jump);
3184   }
3185 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
3186
3187 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
3188 if (common->utf)
3189   {
3190   if (max < 0xd800) return;
3191
3192   OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3193   jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
3194   /* TMP2 contains the high surrogate. */
3195   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3196   OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
3197   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
3198   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
3199   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3200   JUMPHERE(jump);
3201   }
3202 #endif
3203 }
3204
3205 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3206
3207 static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass)
3208 {
3209 /* Tells whether the character codes below 128 are enough
3210 to determine a match. */
3211 const sljit_u8 value = nclass ? 0xff : 0;
3212 const sljit_u8 *end = bitset + 32;
3213
3214 bitset += 16;
3215 do
3216   {
3217   if (*bitset++ != value)
3218     return FALSE;
3219   }
3220 while (bitset < end);
3221 return TRUE;
3222 }
3223
3224 static void read_char7_type(compiler_common *common, BOOL full_read)
3225 {
3226 /* Reads the precise character type of a character into TMP1, if the character
3227 is less than 128. Otherwise it returns with zero. Does not check STR_END. The
3228 full_read argument tells whether characters above max are accepted or not. */
3229 DEFINE_COMPILER;
3230 struct sljit_jump *jump;
3231
3232 SLJIT_ASSERT(common->utf);
3233
3234 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
3235 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3236
3237 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3238
3239 if (full_read)
3240   {
3241   jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
3242   OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3243   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3244   JUMPHERE(jump);
3245   }
3246 }
3247
3248 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
3249
3250 static void read_char_range(compiler_common *common, sljit_u32 min, sljit_u32 max, BOOL update_str_ptr)
3251 {
3252 /* Reads the precise value of a character into TMP1, if the character is
3253 between min and max (c >= min && c <= max). Otherwise it returns with a value
3254 outside the range. Does not check STR_END. */
3255 DEFINE_COMPILER;
3256 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3257 struct sljit_jump *jump;
3258 #endif
3259 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3260 struct sljit_jump *jump2;
3261 #endif
3262
3263 SLJIT_UNUSED_ARG(update_str_ptr);
3264 SLJIT_UNUSED_ARG(min);
3265 SLJIT_UNUSED_ARG(max);
3266 SLJIT_ASSERT(min <= max);
3267
3268 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3269 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3270
3271 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3272 if (common->utf)
3273   {
3274   if (max < 128 && !update_str_ptr) return;
3275
3276   jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3277   if (min >= 0x10000)
3278     {
3279     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
3280     if (update_str_ptr)
3281       OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3282     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3283     jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
3284     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3285     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3286     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3287     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3288     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3289     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3290     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3291     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
3292     if (!update_str_ptr)
3293       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
3294     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3295     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3296     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3297     JUMPHERE(jump2);
3298     if (update_str_ptr)
3299       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
3300     }
3301   else if (min >= 0x800 && max <= 0xffff)
3302     {
3303     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
3304     if (update_str_ptr)
3305       OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3306     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3307     jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
3308     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3309     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3310     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3311     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3312     if (!update_str_ptr)
3313       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3314     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3315     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3316     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3317     JUMPHERE(jump2);
3318     if (update_str_ptr)
3319       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
3320     }
3321   else if (max >= 0x800)
3322     add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
3323   else if (max < 128)
3324     {
3325     OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3326     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3327     }
3328   else
3329     {
3330     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3331     if (!update_str_ptr)
3332       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3333     else
3334       OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3335     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3336     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3337     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3338     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3339     if (update_str_ptr)
3340       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
3341     }
3342   JUMPHERE(jump);
3343   }
3344 #endif
3345
3346 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
3347 if (common->utf)
3348   {
3349   if (max >= 0x10000)
3350     {
3351     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3352     jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
3353     /* TMP2 contains the high surrogate. */
3354     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3355     OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
3356     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
3357     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3358     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
3359     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3360     JUMPHERE(jump);
3361     return;
3362     }
3363
3364   if (max < 0xd800 && !update_str_ptr) return;
3365
3366   /* Skip low surrogate if necessary. */
3367   OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3368   jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
3369   if (update_str_ptr)
3370     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3371   if (max >= 0xd800)
3372     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
3373   JUMPHERE(jump);
3374   }
3375 #endif
3376 }
3377
3378 static SLJIT_INLINE void read_char(compiler_common *common)
3379 {
3380 read_char_range(common, 0, READ_CHAR_MAX, TRUE);
3381 }
3382
3383 static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
3384 {
3385 /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
3386 DEFINE_COMPILER;
3387 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
3388 struct sljit_jump *jump;
3389 #endif
3390 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3391 struct sljit_jump *jump2;
3392 #endif
3393
3394 SLJIT_UNUSED_ARG(update_str_ptr);
3395
3396 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
3397 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3398
3399 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3400 if (common->utf)
3401   {
3402   /* This can be an extra read in some situations, but hopefully
3403   it is needed in most cases. */
3404   OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3405   jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
3406   if (!update_str_ptr)
3407     {
3408     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3409     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3410     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3411     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3412     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3413     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
3414     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3415     jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
3416     OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3417     JUMPHERE(jump2);
3418     }
3419   else
3420     add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
3421   JUMPHERE(jump);
3422   return;
3423   }
3424 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
3425
3426 #if PCRE2_CODE_UNIT_WIDTH != 8
3427 /* The ctypes array contains only 256 values. */
3428 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3429 jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
3430 #endif
3431 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3432 #if PCRE2_CODE_UNIT_WIDTH != 8
3433 JUMPHERE(jump);
3434 #endif
3435
3436 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
3437 if (common->utf && update_str_ptr)
3438   {
3439   /* Skip low surrogate if necessary. */
3440   OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
3441   jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
3442   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3443   JUMPHERE(jump);
3444   }
3445 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */
3446 }
3447
3448 static void skip_char_back(compiler_common *common)
3449 {
3450 /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
3451 DEFINE_COMPILER;
3452 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3453 #if PCRE2_CODE_UNIT_WIDTH == 8
3454 struct sljit_label *label;
3455
3456 if (common->utf)
3457   {
3458   label = LABEL();
3459   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
3460   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3461   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
3462   CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
3463   return;
3464   }
3465 #elif PCRE2_CODE_UNIT_WIDTH == 16
3466 if (common->utf)
3467   {
3468   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
3469   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3470   /* Skip low surrogate if necessary. */
3471   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3472   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
3473   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
3474   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3475   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3476   return;
3477   }
3478 #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
3479 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
3480 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3481 }
3482
3483 static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
3484 {
3485 /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
3486 DEFINE_COMPILER;
3487 struct sljit_jump *jump;
3488
3489 if (nltype == NLTYPE_ANY)
3490   {
3491   add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3492   sljit_set_current_flags(compiler, SLJIT_SET_Z);
3493   add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
3494   }
3495 else if (nltype == NLTYPE_ANYCRLF)
3496   {
3497   if (jumpifmatch)
3498     {
3499     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
3500     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3501     }
3502   else
3503     {
3504     jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3505     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3506     JUMPHERE(jump);
3507     }
3508   }
3509 else
3510   {
3511   SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
3512   add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3513   }
3514 }
3515
3516 #ifdef SUPPORT_UNICODE
3517
3518 #if PCRE2_CODE_UNIT_WIDTH == 8
3519 static void do_utfreadchar(compiler_common *common)
3520 {
3521 /* Fast decoding a UTF-8 character. TMP1 contains the first byte
3522 of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
3523 DEFINE_COMPILER;
3524 struct sljit_jump *jump;
3525
3526 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3527 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3528 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3529 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3530 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3531 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3532
3533 /* Searching for the first zero. */
3534 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
3535 jump = JUMP(SLJIT_NOT_ZERO);
3536 /* Two byte sequence. */
3537 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3538 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
3539 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3540
3541 JUMPHERE(jump);
3542 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3543 OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
3544 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3545 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3546 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3547
3548 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
3549 jump = JUMP(SLJIT_NOT_ZERO);
3550 /* Three byte sequence. */
3551 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3552 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
3553 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3554
3555 /* Four byte sequence. */
3556 JUMPHERE(jump);
3557 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
3558 OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
3559 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3560 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
3561 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3562 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3563 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
3564 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3565 }
3566
3567 static void do_utfreadchar16(compiler_common *common)
3568 {
3569 /* Fast decoding a UTF-8 character. TMP1 contains the first byte
3570 of the character (>= 0xc0). Return value in TMP1. */
3571 DEFINE_COMPILER;
3572 struct sljit_jump *jump;
3573
3574 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3575 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3576 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3577 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3578 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3579 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3580
3581 /* Searching for the first zero. */
3582 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
3583 jump = JUMP(SLJIT_NOT_ZERO);
3584 /* Two byte sequence. */
3585 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3586 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3587
3588 JUMPHERE(jump);
3589 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
3590 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO);
3591 /* This code runs only in 8 bit mode. No need to shift the value. */
3592 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3593 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3594 OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
3595 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3596 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3597 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3598 /* Three byte sequence. */
3599 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3600 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3601 }
3602
3603 static void do_utfreadtype8(compiler_common *common)
3604 {
3605 /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
3606 of the character (>= 0xc0). Return value in TMP1. */
3607 DEFINE_COMPILER;
3608 struct sljit_jump *jump;
3609 struct sljit_jump *compare;
3610
3611 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3612
3613 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
3614 jump = JUMP(SLJIT_NOT_ZERO);
3615 /* Two byte sequence. */
3616 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3617 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3618 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
3619 /* The upper 5 bits are known at this point. */
3620 compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
3621 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3622 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3623 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
3624 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3625 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3626
3627 JUMPHERE(compare);
3628 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3629 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3630
3631 /* We only have types for characters less than 256. */
3632 JUMPHERE(jump);
3633 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3634 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3635 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3636 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3637 }
3638
3639 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
3640
3641 /* UCD_BLOCK_SIZE must be 128 (see the assert below). */
3642 #define UCD_BLOCK_MASK 127
3643 #define UCD_BLOCK_SHIFT 7
3644
3645 static void do_getucd(compiler_common *common)
3646 {
3647 /* Search the UCD record for the character comes in TMP1.
3648 Returns chartype in TMP1 and UCD offset in TMP2. */
3649 DEFINE_COMPILER;
3650 #if PCRE2_CODE_UNIT_WIDTH == 32
3651 struct sljit_jump *jump;
3652 #endif
3653
3654 #if defined SLJIT_DEBUG && SLJIT_DEBUG
3655 /* dummy_ucd_record */
3656 const ucd_record *record = GET_UCD(INVALID_UTF_CHAR);
3657 SLJIT_ASSERT(record->script == ucp_Common && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther);
3658 SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0);
3659 #endif
3660
3661 SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
3662
3663 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3664
3665 #if PCRE2_CODE_UNIT_WIDTH == 32
3666 if (!common->utf)
3667   {
3668   jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);
3669   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
3670   JUMPHERE(jump);
3671   }
3672 #endif
3673
3674 OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
3675 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3676 OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
3677 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
3678 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
3679 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
3680 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
3681 OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
3682 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
3683 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
3684 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3685 }
3686
3687 #endif /* SUPPORT_UNICODE */
3688
3689 static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common)
3690 {
3691 DEFINE_COMPILER;
3692 struct sljit_label *mainloop;
3693 struct sljit_label *newlinelabel = NULL;
3694 struct sljit_jump *start;
3695 struct sljit_jump *end = NULL;
3696 struct sljit_jump *end2 = NULL;
3697 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3698 struct sljit_jump *singlechar;
3699 #endif
3700 jump_list *newline = NULL;
3701 sljit_u32 overall_options = common->re->overall_options;
3702 BOOL hascrorlf = (common->re->flags & PCRE2_HASCRORLF) != 0;
3703 BOOL newlinecheck = FALSE;
3704 BOOL readuchar = FALSE;
3705
3706 if (!(hascrorlf || (overall_options & PCRE2_FIRSTLINE) != 0)
3707     && (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
3708   newlinecheck = TRUE;
3709
3710 SLJIT_ASSERT(common->abort_label == NULL);
3711
3712 if ((overall_options & PCRE2_FIRSTLINE) != 0)
3713   {
3714   /* Search for the end of the first line. */
3715   SLJIT_ASSERT(common->match_end_ptr != 0);
3716   OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
3717
3718   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3719     {
3720     mainloop = LABEL();
3721     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3722     end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3723     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3724     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3725     CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
3726     CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
3727     JUMPHERE(end);
3728     OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3729     }
3730   else
3731     {
3732     end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3733     mainloop = LABEL();
3734     /* Continual stores does not cause data dependency. */
3735     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
3736     read_char_range(common, common->nlmin, common->nlmax, TRUE);
3737     check_newlinechar(common, common->nltype, &newline, TRUE);
3738     CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
3739     JUMPHERE(end);
3740     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
3741     set_jumps(newline, LABEL());
3742     }
3743
3744   OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3745   }
3746 else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0)
3747   {
3748   /* Check whether offset limit is set and valid. */
3749   SLJIT_ASSERT(common->match_end_ptr != 0);
3750
3751   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3752   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));
3753   OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
3754   end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET);
3755   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3756 #if PCRE2_CODE_UNIT_WIDTH == 16
3757   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3758 #elif PCRE2_CODE_UNIT_WIDTH == 32
3759   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
3760 #endif
3761   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3762   OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
3763   end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
3764   OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
3765   JUMPHERE(end2);
3766   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
3767   add_jump(compiler, &common->abort, CMP(SLJIT_LESS, TMP2, 0, STR_PTR, 0));
3768   JUMPHERE(end);
3769   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, TMP2, 0);
3770   }
3771
3772 start = JUMP(SLJIT_JUMP);
3773
3774 if (newlinecheck)
3775   {
3776   newlinelabel = LABEL();
3777   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3778   end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3779   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3780   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
3781   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
3782 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
3783   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3784 #endif
3785   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3786   end2 = JUMP(SLJIT_JUMP);
3787   }
3788
3789 mainloop = LABEL();
3790
3791 /* Increasing the STR_PTR here requires one less jump in the most common case. */
3792 #ifdef SUPPORT_UNICODE
3793 if (common->utf) readuchar = TRUE;
3794 #endif
3795 if (newlinecheck) readuchar = TRUE;
3796
3797 if (readuchar)
3798   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3799
3800 if (newlinecheck)
3801   CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
3802
3803 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3804 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3805 #if PCRE2_CODE_UNIT_WIDTH == 8
3806 if (common->utf)
3807   {
3808   singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3809   OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3810   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3811   JUMPHERE(singlechar);
3812   }
3813 #elif PCRE2_CODE_UNIT_WIDTH == 16
3814 if (common->utf)
3815   {
3816   singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3817   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3818   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3819   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
3820   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3821   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3822   JUMPHERE(singlechar);
3823   }
3824 #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
3825 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
3826 JUMPHERE(start);
3827
3828 if (newlinecheck)
3829   {
3830   JUMPHERE(end);
3831   JUMPHERE(end2);
3832   }
3833
3834 return mainloop;
3835 }
3836
3837
3838 static SLJIT_INLINE void add_prefix_char(PCRE2_UCHAR chr, fast_forward_char_data *chars, BOOL last)
3839 {
3840 sljit_u32 i, count = chars->count;
3841
3842 if (count == 255)
3843   return;
3844
3845 if (count == 0)
3846   {
3847   chars->count = 1;
3848   chars->chars[0] = chr;
3849
3850   if (last)
3851     chars->last_count = 1;
3852   return;
3853   }
3854
3855 for (i = 0; i < count; i++)
3856   if (chars->chars[i] == chr)
3857     return;
3858
3859 if (count >= MAX_DIFF_CHARS)
3860   {
3861   chars->count = 255;
3862   return;
3863   }
3864
3865 chars->chars[count] = chr;
3866 chars->count = count + 1;
3867
3868 if (last)
3869   chars->last_count++;
3870 }
3871
3872 static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, fast_forward_char_data *chars, int max_chars, sljit_u32 *rec_count)
3873 {
3874 /* Recursive function, which scans prefix literals. */
3875 BOOL last, any, class, caseless;
3876 int len, repeat, len_save, consumed = 0;
3877 sljit_u32 chr; /* Any unicode character. */
3878 sljit_u8 *bytes, *bytes_end, byte;
3879 PCRE2_SPTR alternative, cc_save, oc;
3880 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3881 PCRE2_UCHAR othercase[4];
3882 #elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
3883 PCRE2_UCHAR othercase[2];
3884 #else
3885 PCRE2_UCHAR othercase[1];
3886 #endif
3887
3888 repeat = 1;
3889 while (TRUE)
3890   {
3891   if (*rec_count == 0)
3892     return 0;
3893   (*rec_count)--;
3894
3895   last = TRUE;
3896   any = FALSE;
3897   class = FALSE;
3898   caseless = FALSE;
3899
3900   switch (*cc)
3901     {
3902     case OP_CHARI:
3903     caseless = TRUE;
3904     /* Fall through */
3905     case OP_CHAR:
3906     last = FALSE;
3907     cc++;
3908     break;
3909
3910     case OP_SOD:
3911     case OP_SOM:
3912     case OP_SET_SOM:
3913     case OP_NOT_WORD_BOUNDARY:
3914     case OP_WORD_BOUNDARY:
3915     case OP_EODN:
3916     case OP_EOD:
3917     case OP_CIRC:
3918     case OP_CIRCM:
3919     case OP_DOLL:
3920     case OP_DOLLM:
3921     /* Zero width assertions. */
3922     cc++;
3923     continue;
3924
3925     case OP_ASSERT:
3926     case OP_ASSERT_NOT:
3927     case OP_ASSERTBACK:
3928     case OP_ASSERTBACK_NOT:
3929     cc = bracketend(cc);
3930     continue;
3931
3932     case OP_PLUSI:
3933     case OP_MINPLUSI:
3934     case OP_POSPLUSI:
3935     caseless = TRUE;
3936     /* Fall through */
3937     case OP_PLUS:
3938     case OP_MINPLUS:
3939     case OP_POSPLUS:
3940     cc++;
3941     break;
3942
3943     case OP_EXACTI:
3944     caseless = TRUE;
3945     /* Fall through */
3946     case OP_EXACT:
3947     repeat = GET2(cc, 1);
3948     last = FALSE;
3949     cc += 1 + IMM2_SIZE;
3950     break;
3951
3952     case OP_QUERYI:
3953     case OP_MINQUERYI:
3954     case OP_POSQUERYI:
3955     caseless = TRUE;
3956     /* Fall through */
3957     case OP_QUERY:
3958     case OP_MINQUERY:
3959     case OP_POSQUERY:
3960     len = 1;
3961     cc++;
3962 #ifdef SUPPORT_UNICODE
3963     if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3964 #endif
3965     max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count);
3966     if (max_chars == 0)
3967       return consumed;
3968     last = FALSE;
3969     break;
3970
3971     case OP_KET:
3972     cc += 1 + LINK_SIZE;
3973     continue;
3974
3975     case OP_ALT:
3976     cc += GET(cc, 1);
3977     continue;
3978
3979     case OP_ONCE:
3980     case OP_BRA:
3981     case OP_BRAPOS:
3982     case OP_CBRA:
3983     case OP_CBRAPOS:
3984     alternative = cc + GET(cc, 1);
3985     while (*alternative == OP_ALT)
3986       {
3987       max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count);
3988       if (max_chars == 0)
3989         return consumed;
3990       alternative += GET(alternative, 1);
3991       }
3992
3993     if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3994       cc += IMM2_SIZE;
3995     cc += 1 + LINK_SIZE;
3996     continue;
3997
3998     case OP_CLASS:
3999 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4000     if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE))
4001       return consumed;
4002 #endif
4003     class = TRUE;
4004     break;
4005
4006     case OP_NCLASS:
4007 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4008     if (common->utf) return consumed;
4009 #endif
4010     class = TRUE;
4011     break;
4012
4013 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
4014     case OP_XCLASS:
4015 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4016     if (common->utf) return consumed;
4017 #endif
4018     any = TRUE;
4019     cc += GET(cc, 1);
4020     break;
4021 #endif
4022
4023     case OP_DIGIT:
4024 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4025     if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
4026       return consumed;
4027 #endif
4028     any = TRUE;
4029     cc++;
4030     break;
4031
4032     case OP_WHITESPACE:
4033 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4034     if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))
4035       return consumed;
4036 #endif
4037     any = TRUE;
4038     cc++;
4039     break;
4040
4041     case OP_WORDCHAR:
4042 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4043     if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))
4044       return consumed;
4045 #endif
4046     any = TRUE;
4047     cc++;
4048     break;
4049
4050     case OP_NOT:
4051     case OP_NOTI:
4052     cc++;
4053     /* Fall through. */
4054     case OP_NOT_DIGIT:
4055     case OP_NOT_WHITESPACE:
4056     case OP_NOT_WORDCHAR:
4057     case OP_ANY:
4058     case OP_ALLANY:
4059 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4060     if (common->utf) return consumed;
4061 #endif
4062     any = TRUE;
4063     cc++;
4064     break;
4065
4066 #ifdef SUPPORT_UNICODE
4067     case OP_NOTPROP:
4068     case OP_PROP:
4069 #if PCRE2_CODE_UNIT_WIDTH != 32
4070     if (common->utf) return consumed;
4071 #endif
4072     any = TRUE;
4073     cc += 1 + 2;
4074     break;
4075 #endif
4076
4077     case OP_TYPEEXACT:
4078     repeat = GET2(cc, 1);
4079     cc += 1 + IMM2_SIZE;
4080     continue;
4081
4082     case OP_NOTEXACT:
4083     case OP_NOTEXACTI:
4084 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4085     if (common->utf) return consumed;
4086 #endif
4087     any = TRUE;
4088     repeat = GET2(cc, 1);
4089     cc += 1 + IMM2_SIZE + 1;
4090     break;
4091
4092     default:
4093     return consumed;
4094     }
4095
4096   if (any)
4097     {
4098     do
4099       {
4100       chars->count = 255;
4101
4102       consumed++;
4103       if (--max_chars == 0)
4104         return consumed;
4105       chars++;
4106       }
4107     while (--repeat > 0);
4108
4109     repeat = 1;
4110     continue;
4111     }
4112
4113   if (class)
4114     {
4115     bytes = (sljit_u8*) (cc + 1);
4116     cc += 1 + 32 / sizeof(PCRE2_UCHAR);
4117
4118     switch (*cc)
4119       {
4120       case OP_CRSTAR:
4121       case OP_CRMINSTAR:
4122       case OP_CRPOSSTAR:
4123       case OP_CRQUERY:
4124       case OP_CRMINQUERY:
4125       case OP_CRPOSQUERY:
4126       max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count);
4127       if (max_chars == 0)
4128         return consumed;
4129       break;
4130
4131       default:
4132       case OP_CRPLUS:
4133       case OP_CRMINPLUS:
4134       case OP_CRPOSPLUS:
4135       break;
4136
4137       case OP_CRRANGE:
4138       case OP_CRMINRANGE:
4139       case OP_CRPOSRANGE:
4140       repeat = GET2(cc, 1);
4141       if (repeat <= 0)
4142         return consumed;
4143       break;
4144       }
4145
4146     do
4147       {
4148       if (bytes[31] & 0x80)
4149         chars->count = 255;
4150       else if (chars->count != 255)
4151         {
4152         bytes_end = bytes + 32;
4153         chr = 0;
4154         do
4155           {
4156           byte = *bytes++;
4157           SLJIT_ASSERT((chr & 0x7) == 0);
4158           if (byte == 0)
4159             chr += 8;
4160           else
4161             {
4162             do
4163               {
4164               if ((byte & 0x1) != 0)
4165                 add_prefix_char(chr, chars, TRUE);
4166               byte >>= 1;
4167               chr++;
4168               }
4169             while (byte != 0);
4170             chr = (chr + 7) & ~7;
4171             }
4172           }
4173         while (chars->count != 255 && bytes < bytes_end);
4174         bytes = bytes_end - 32;
4175         }
4176
4177       consumed++;
4178       if (--max_chars == 0)
4179         return consumed;
4180       chars++;
4181       }
4182     while (--repeat > 0);
4183
4184     switch (*cc)
4185       {
4186       case OP_CRSTAR:
4187       case OP_CRMINSTAR:
4188       case OP_CRPOSSTAR:
4189       return consumed;
4190
4191       case OP_CRQUERY:
4192       case OP_CRMINQUERY:
4193       case OP_CRPOSQUERY:
4194       cc++;
4195       break;
4196
4197       case OP_CRRANGE:
4198       case OP_CRMINRANGE:
4199       case OP_CRPOSRANGE:
4200       if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE))
4201         return consumed;
4202       cc += 1 + 2 * IMM2_SIZE;
4203       break;
4204       }
4205
4206     repeat = 1;
4207     continue;
4208     }
4209
4210   len = 1;
4211 #ifdef SUPPORT_UNICODE
4212   if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
4213 #endif
4214
4215   if (caseless && char_has_othercase(common, cc))
4216     {
4217 #ifdef SUPPORT_UNICODE
4218     if (common->utf)
4219       {
4220       GETCHAR(chr, cc);
4221       if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
4222         return consumed;
4223       }
4224     else
4225 #endif
4226       {
4227       chr = *cc;
4228       othercase[0] = TABLE_GET(chr, common->fcc, chr);
4229       }
4230     }
4231   else
4232     {
4233     caseless = FALSE;
4234     othercase[0] = 0; /* Stops compiler warning - PH */
4235     }
4236
4237   len_save = len;
4238   cc_save = cc;
4239   while (TRUE)
4240     {
4241     oc = othercase;
4242     do
4243       {
4244       len--;
4245       consumed++;
4246
4247       chr = *cc;
4248       add_prefix_char(*cc, chars, len == 0);
4249
4250       if (caseless)
4251         add_prefix_char(*oc, chars, len == 0);
4252
4253       if (--max_chars == 0)
4254         return consumed;
4255       chars++;
4256       cc++;
4257       oc++;
4258       }
4259     while (len > 0);
4260
4261     if (--repeat == 0)
4262       break;
4263
4264     len = len_save;
4265     cc = cc_save;
4266     }
4267
4268   repeat = 1;
4269   if (last)
4270     return consumed;
4271   }
4272 }
4273
4274 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4275 static void jumpto_if_not_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg, struct sljit_label *label)
4276 {
4277 #if PCRE2_CODE_UNIT_WIDTH == 8
4278 OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
4279 CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0x80, label);
4280 #elif PCRE2_CODE_UNIT_WIDTH == 16
4281 OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
4282 CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00, label);
4283 #else
4284 #error "Unknown code width"
4285 #endif
4286 }
4287 #endif
4288
4289 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
4290
4291 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4292 static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg)
4293 {
4294 #if PCRE2_CODE_UNIT_WIDTH == 8
4295 OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
4296 return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80);
4297 #elif PCRE2_CODE_UNIT_WIDTH == 16
4298 OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
4299 return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);
4300 #else
4301 #error "Unknown code width"
4302 #endif
4303 }
4304 #endif
4305
4306 static sljit_s32 character_to_int32(PCRE2_UCHAR chr)
4307 {
4308 sljit_s32 value = (sljit_s32)chr;
4309 #if PCRE2_CODE_UNIT_WIDTH == 8
4310 #define SSE2_COMPARE_TYPE_INDEX 0
4311 return (value << 24) | (value << 16) | (value << 8) | value;
4312 #elif PCRE2_CODE_UNIT_WIDTH == 16
4313 #define SSE2_COMPARE_TYPE_INDEX 1
4314 return (value << 16) | value;
4315 #elif PCRE2_CODE_UNIT_WIDTH == 32
4316 #define SSE2_COMPARE_TYPE_INDEX 2
4317 return value;
4318 #else
4319 #error "Unsupported unit width"
4320 #endif
4321 }
4322
4323 static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg)
4324 {
4325 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
4326 sljit_u8 instruction[5];
4327 #else
4328 sljit_u8 instruction[4];
4329 #endif
4330
4331 SLJIT_ASSERT(dst_xmm_reg < 8);
4332
4333 /* MOVDQA xmm1, xmm2/m128 */
4334 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
4335 if (src_general_reg < 8)
4336   {
4337   instruction[0] = 0x66;
4338   instruction[1] = 0x0f;
4339   instruction[2] = 0x6f;
4340   instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
4341   sljit_emit_op_custom(compiler, instruction, 4);
4342   }
4343 else
4344   {
4345   instruction[0] = 0x66;
4346   instruction[1] = 0x41;
4347   instruction[2] = 0x0f;
4348   instruction[3] = 0x6f;
4349   instruction[4] = (dst_xmm_reg << 3) | (src_general_reg & 0x7);
4350   sljit_emit_op_custom(compiler, instruction, 4);
4351   }
4352 #else
4353 instruction[0] = 0x66;
4354 instruction[1] = 0x0f;
4355 instruction[2] = 0x6f;
4356 instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
4357 sljit_emit_op_custom(compiler, instruction, 4);
4358 #endif
4359 }
4360
4361 static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, PCRE2_UCHAR char1, PCRE2_UCHAR char2,
4362   sljit_u32 bit, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)
4363 {
4364 sljit_u8 instruction[4];
4365 instruction[0] = 0x66;
4366 instruction[1] = 0x0f;
4367
4368 if (char1 == char2 || bit != 0)
4369   {
4370   if (bit != 0)
4371     {
4372     /* POR xmm1, xmm2/m128 */
4373     /* instruction[0] = 0x66; */
4374     /* instruction[1] = 0x0f; */
4375     instruction[2] = 0xeb;
4376     instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind;
4377     sljit_emit_op_custom(compiler, instruction, 4);
4378     }
4379
4380   /* PCMPEQB/W/D xmm1, xmm2/m128 */
4381   /* instruction[0] = 0x66; */
4382   /* instruction[1] = 0x0f; */
4383   instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
4384   instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
4385   sljit_emit_op_custom(compiler, instruction, 4);
4386   }
4387 else
4388   {
4389   /* MOVDQA xmm1, xmm2/m128 */
4390   /* instruction[0] = 0x66; */
4391   /* instruction[1] = 0x0f; */
4392   instruction[2] = 0x6f;
4393   instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind;
4394   sljit_emit_op_custom(compiler, instruction, 4);
4395
4396   /* PCMPEQB/W/D xmm1, xmm2/m128 */
4397   /* instruction[0] = 0x66; */
4398   /* instruction[1] = 0x0f; */
4399   instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
4400   instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
4401   sljit_emit_op_custom(compiler, instruction, 4);
4402
4403   instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;
4404   sljit_emit_op_custom(compiler, instruction, 4);
4405
4406   /* POR xmm1, xmm2/m128 */
4407   /* instruction[0] = 0x66; */
4408   /* instruction[1] = 0x0f; */
4409   instruction[2] = 0xeb;
4410   instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind;
4411   sljit_emit_op_custom(compiler, instruction, 4);
4412   }
4413 }
4414
4415 static void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
4416 {
4417 DEFINE_COMPILER;
4418 struct sljit_label *start;
4419 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4420 struct sljit_label *restart;
4421 #endif
4422 struct sljit_jump *quit;
4423 struct sljit_jump *partial_quit[2];
4424 sljit_u8 instruction[8];
4425 sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
4426 sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
4427 sljit_s32 data_ind = 0;
4428 sljit_s32 tmp_ind = 1;
4429 sljit_s32 cmp1_ind = 2;
4430 sljit_s32 cmp2_ind = 3;
4431 sljit_u32 bit = 0;
4432
4433 SLJIT_UNUSED_ARG(offset);
4434
4435 if (char1 != char2)
4436   {
4437   bit = char1 ^ char2;
4438   if (!is_powerof2(bit))
4439     bit = 0;
4440   }
4441
4442 partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4443 if (common->mode == PCRE2_JIT_COMPLETE)
4444   add_jump(compiler, &common->failed_match, partial_quit[0]);
4445
4446 /* First part (unaligned start) */
4447
4448 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
4449
4450 SLJIT_ASSERT(tmp1_ind < 8);
4451
4452 /* MOVD xmm, r/m32 */
4453 instruction[0] = 0x66;
4454 instruction[1] = 0x0f;
4455 instruction[2] = 0x6e;
4456 instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_ind;
4457 sljit_emit_op_custom(compiler, instruction, 4);
4458
4459 if (char1 != char2)
4460   {
4461   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
4462
4463   /* MOVD xmm, r/m32 */
4464   instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_ind;
4465   sljit_emit_op_custom(compiler, instruction, 4);
4466   }
4467
4468 OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
4469
4470 /* PSHUFD xmm1, xmm2/m128, imm8 */
4471 /* instruction[0] = 0x66; */
4472 /* instruction[1] = 0x0f; */
4473 instruction[2] = 0x70;
4474 instruction[3] = 0xc0 | (cmp1_ind << 3) | 2;
4475 instruction[4] = 0;
4476 sljit_emit_op_custom(compiler, instruction, 5);
4477
4478 if (char1 != char2)
4479   {
4480   /* PSHUFD xmm1, xmm2/m128, imm8 */
4481   instruction[3] = 0xc0 | (cmp2_ind << 3) | 3;
4482   sljit_emit_op_custom(compiler, instruction, 5);
4483   }
4484
4485 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4486 restart = LABEL();
4487 #endif
4488 OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
4489 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
4490
4491 load_from_mem_sse2(compiler, data_ind, str_ptr_ind);
4492 fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
4493
4494 /* PMOVMSKB reg, xmm */
4495 /* instruction[0] = 0x66; */
4496 /* instruction[1] = 0x0f; */
4497 instruction[2] = 0xd7;
4498 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
4499 sljit_emit_op_custom(compiler, instruction, 4);
4500
4501 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4502 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
4503
4504 /* BSF r32, r/m32 */
4505 instruction[0] = 0x0f;
4506 instruction[1] = 0xbc;
4507 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
4508 sljit_emit_op_custom(compiler, instruction, 3);
4509 sljit_set_current_flags(compiler, SLJIT_SET_Z);
4510
4511 quit = JUMP(SLJIT_NOT_ZERO);
4512
4513 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4514
4515 start = LABEL();
4516 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
4517
4518 partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4519 if (common->mode == PCRE2_JIT_COMPLETE)
4520   add_jump(compiler, &common->failed_match, partial_quit[1]);
4521
4522 /* Second part (aligned) */
4523
4524 load_from_mem_sse2(compiler, 0, str_ptr_ind);
4525 fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
4526
4527 /* PMOVMSKB reg, xmm */
4528 instruction[0] = 0x66;
4529 instruction[1] = 0x0f;
4530 instruction[2] = 0xd7;
4531 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
4532 sljit_emit_op_custom(compiler, instruction, 4);
4533
4534 /* BSF r32, r/m32 */
4535 instruction[0] = 0x0f;
4536 instruction[1] = 0xbc;
4537 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
4538 sljit_emit_op_custom(compiler, instruction, 3);
4539 sljit_set_current_flags(compiler, SLJIT_SET_Z);
4540
4541 JUMPTO(SLJIT_ZERO, start);
4542
4543 JUMPHERE(quit);
4544 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4545
4546 if (common->mode != PCRE2_JIT_COMPLETE)
4547   {
4548   JUMPHERE(partial_quit[0]);
4549   JUMPHERE(partial_quit[1]);
4550   OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
4551   CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
4552   }
4553 else
4554   add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4555
4556 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4557 if (common->utf && offset > 0)
4558   {
4559   SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
4560
4561   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
4562
4563   quit = jump_if_utf_char_start(compiler, TMP1);
4564
4565   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4566   add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4567   OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
4568   JUMPTO(SLJIT_JUMP, restart);
4569
4570   JUMPHERE(quit);
4571   }
4572 #endif
4573 }
4574
4575 #ifndef _WIN64
4576
4577 static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_sse2_offset(void)
4578 {
4579 #if PCRE2_CODE_UNIT_WIDTH == 8
4580 return 15;
4581 #elif PCRE2_CODE_UNIT_WIDTH == 16
4582 return 7;
4583 #elif PCRE2_CODE_UNIT_WIDTH == 32
4584 return 3;
4585 #else
4586 #error "Unsupported unit width"
4587 #endif
4588 }
4589
4590 static void fast_forward_char_pair_sse2(compiler_common *common, sljit_s32 offs1,
4591   PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
4592 {
4593 DEFINE_COMPILER;
4594 sljit_u32 bit1 = 0;
4595 sljit_u32 bit2 = 0;
4596 sljit_u32 diff = IN_UCHARS(offs1 - offs2);
4597 sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
4598 sljit_s32 tmp2_ind = sljit_get_register_index(TMP2);
4599 sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
4600 sljit_s32 data1_ind = 0;
4601 sljit_s32 data2_ind = 1;
4602 sljit_s32 tmp_ind = 2;
4603 sljit_s32 cmp1a_ind = 3;
4604 sljit_s32 cmp1b_ind = 4;
4605 sljit_s32 cmp2a_ind = 5;
4606 sljit_s32 cmp2b_ind = 6;
4607 struct sljit_label *start;
4608 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4609 struct sljit_label *restart;
4610 #endif
4611 struct sljit_jump *jump[2];
4612
4613 sljit_u8 instruction[8];
4614
4615 SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
4616 SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_sse2_offset()));
4617 SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
4618
4619 /* Initialize. */
4620 if (common->match_end_ptr != 0)
4621   {
4622   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4623   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
4624   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
4625
4626   OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
4627   CMOV(SLJIT_LESS, STR_END, TMP1, 0);
4628   }
4629
4630 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
4631 add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4632
4633 /* MOVD xmm, r/m32 */
4634 instruction[0] = 0x66;
4635 instruction[1] = 0x0f;
4636 instruction[2] = 0x6e;
4637
4638 if (char1a == char1b)
4639   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
4640 else
4641   {
4642   bit1 = char1a ^ char1b;
4643   if (is_powerof2(bit1))
4644     {
4645     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));
4646     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));
4647     }
4648   else
4649     {
4650     bit1 = 0;
4651     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
4652     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b));
4653     }
4654   }
4655
4656 instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_ind;
4657 sljit_emit_op_custom(compiler, instruction, 4);
4658
4659 if (char1a != char1b)
4660   {
4661   instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_ind;
4662   sljit_emit_op_custom(compiler, instruction, 4);
4663   }
4664
4665 if (char2a == char2b)
4666   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
4667 else
4668   {
4669   bit2 = char2a ^ char2b;
4670   if (is_powerof2(bit2))
4671     {
4672     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));
4673     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));
4674     }
4675   else
4676     {
4677     bit2 = 0;
4678     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
4679     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b));
4680     }
4681   }
4682
4683 instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_ind;
4684 sljit_emit_op_custom(compiler, instruction, 4);
4685
4686 if (char2a != char2b)
4687   {
4688   instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_ind;
4689   sljit_emit_op_custom(compiler, instruction, 4);
4690   }
4691
4692 /* PSHUFD xmm1, xmm2/m128, imm8 */
4693 /* instruction[0] = 0x66; */
4694 /* instruction[1] = 0x0f; */
4695 instruction[2] = 0x70;
4696 instruction[4] = 0;
4697
4698 instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind;
4699 sljit_emit_op_custom(compiler, instruction, 5);
4700
4701 if (char1a != char1b)
4702   {
4703   instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind;
4704   sljit_emit_op_custom(compiler, instruction, 5);
4705   }
4706
4707 instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind;
4708 sljit_emit_op_custom(compiler, instruction, 5);
4709
4710 if (char2a != char2b)
4711   {
4712   instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind;
4713   sljit_emit_op_custom(compiler, instruction, 5);
4714   }
4715
4716 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4717 restart = LABEL();
4718 #endif
4719
4720 OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1 - offs2));
4721 OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
4722 OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
4723 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, ~0xf);
4724
4725 load_from_mem_sse2(compiler, data1_ind, str_ptr_ind);
4726
4727 jump[0] = CMP(SLJIT_EQUAL, STR_PTR, 0, TMP1, 0);
4728
4729 load_from_mem_sse2(compiler, data2_ind, tmp1_ind);
4730
4731 /* MOVDQA xmm1, xmm2/m128 */
4732 /* instruction[0] = 0x66; */
4733 /* instruction[1] = 0x0f; */
4734 instruction[2] = 0x6f;
4735 instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind;
4736 sljit_emit_op_custom(compiler, instruction, 4);
4737
4738 /* PSLLDQ xmm1, xmm2/m128, imm8 */
4739 /* instruction[0] = 0x66; */
4740 /* instruction[1] = 0x0f; */
4741 instruction[2] = 0x73;
4742 instruction[3] = 0xc0 | (7 << 3) | tmp_ind;
4743 instruction[4] = diff;
4744 sljit_emit_op_custom(compiler, instruction, 5);
4745
4746 /* PSRLDQ xmm1, xmm2/m128, imm8 */
4747 /* instruction[0] = 0x66; */
4748 /* instruction[1] = 0x0f; */
4749 /* instruction[2] = 0x73; */
4750 instruction[3] = 0xc0 | (3 << 3) | data2_ind;
4751 instruction[4] = 16 - diff;
4752 sljit_emit_op_custom(compiler, instruction, 5);
4753
4754 /* POR xmm1, xmm2/m128 */
4755 /* instruction[0] = 0x66; */
4756 /* instruction[1] = 0x0f; */
4757 instruction[2] = 0xeb;
4758 instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind;
4759 sljit_emit_op_custom(compiler, instruction, 4);
4760
4761 jump[1] = JUMP(SLJIT_JUMP);
4762
4763 JUMPHERE(jump[0]);
4764
4765 /* MOVDQA xmm1, xmm2/m128 */
4766 /* instruction[0] = 0x66; */
4767 /* instruction[1] = 0x0f; */
4768 instruction[2] = 0x6f;
4769 instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind;
4770 sljit_emit_op_custom(compiler, instruction, 4);
4771
4772 /* PSLLDQ xmm1, xmm2/m128, imm8 */
4773 /* instruction[0] = 0x66; */
4774 /* instruction[1] = 0x0f; */
4775 instruction[2] = 0x73;
4776 instruction[3] = 0xc0 | (7 << 3) | data2_ind;
4777 instruction[4] = diff;
4778 sljit_emit_op_custom(compiler, instruction, 5);
4779
4780 JUMPHERE(jump[1]);
4781
4782 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
4783
4784 fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind);
4785 fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind);
4786
4787 /* PAND xmm1, xmm2/m128 */
4788 /* instruction[0] = 0x66; */
4789 /* instruction[1] = 0x0f; */
4790 instruction[2] = 0xdb;
4791 instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
4792 sljit_emit_op_custom(compiler, instruction, 4);
4793
4794 /* PMOVMSKB reg, xmm */
4795 /* instruction[0] = 0x66; */
4796 /* instruction[1] = 0x0f; */
4797 instruction[2] = 0xd7;
4798 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
4799 sljit_emit_op_custom(compiler, instruction, 4);
4800
4801 /* Ignore matches before the first STR_PTR. */
4802 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4803 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
4804
4805 /* BSF r32, r/m32 */
4806 instruction[0] = 0x0f;
4807 instruction[1] = 0xbc;
4808 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
4809 sljit_emit_op_custom(compiler, instruction, 3);
4810 sljit_set_current_flags(compiler, SLJIT_SET_Z);
4811
4812 jump[0] = JUMP(SLJIT_NOT_ZERO);
4813
4814 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4815
4816 /* Main loop. */
4817 instruction[0] = 0x66;
4818 instruction[1] = 0x0f;
4819
4820 start = LABEL();
4821
4822 load_from_mem_sse2(compiler, data2_ind, str_ptr_ind);
4823
4824 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
4825 add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4826
4827 load_from_mem_sse2(compiler, data1_ind, str_ptr_ind);
4828
4829 /* PSRLDQ xmm1, xmm2/m128, imm8 */
4830 /* instruction[0] = 0x66; */
4831 /* instruction[1] = 0x0f; */
4832 instruction[2] = 0x73;
4833 instruction[3] = 0xc0 | (3 << 3) | data2_ind;
4834 instruction[4] = 16 - diff;
4835 sljit_emit_op_custom(compiler, instruction, 5);
4836
4837 /* MOVDQA xmm1, xmm2/m128 */
4838 /* instruction[0] = 0x66; */
4839 /* instruction[1] = 0x0f; */
4840 instruction[2] = 0x6f;
4841 instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind;
4842 sljit_emit_op_custom(compiler, instruction, 4);
4843
4844 /* PSLLDQ xmm1, xmm2/m128, imm8 */
4845 /* instruction[0] = 0x66; */
4846 /* instruction[1] = 0x0f; */
4847 instruction[2] = 0x73;
4848 instruction[3] = 0xc0 | (7 << 3) | tmp_ind;
4849 instruction[4] = diff;
4850 sljit_emit_op_custom(compiler, instruction, 5);
4851
4852 /* POR xmm1, xmm2/m128 */
4853 /* instruction[0] = 0x66; */
4854 /* instruction[1] = 0x0f; */
4855 instruction[2] = 0xeb;
4856 instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind;
4857 sljit_emit_op_custom(compiler, instruction, 4);
4858
4859 fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind);
4860 fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind);
4861
4862 /* PAND xmm1, xmm2/m128 */
4863 /* instruction[0] = 0x66; */
4864 /* instruction[1] = 0x0f; */
4865 instruction[2] = 0xdb;
4866 instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
4867 sljit_emit_op_custom(compiler, instruction, 4);
4868
4869 /* PMOVMSKB reg, xmm */
4870 /* instruction[0] = 0x66; */
4871 /* instruction[1] = 0x0f; */
4872 instruction[2] = 0xd7;
4873 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
4874 sljit_emit_op_custom(compiler, instruction, 4);
4875
4876 /* BSF r32, r/m32 */
4877 instruction[0] = 0x0f;
4878 instruction[1] = 0xbc;
4879 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
4880 sljit_emit_op_custom(compiler, instruction, 3);
4881 sljit_set_current_flags(compiler, SLJIT_SET_Z);
4882
4883 JUMPTO(SLJIT_ZERO, start);
4884
4885 JUMPHERE(jump[0]);
4886
4887 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4888
4889 add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4890
4891 if (common->match_end_ptr != 0)
4892   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4893
4894 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4895 if (common->utf)
4896   {
4897   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
4898
4899   jump[0] = jump_if_utf_char_start(compiler, TMP1);
4900
4901   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4902   CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);
4903
4904   add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));
4905
4906   JUMPHERE(jump[0]);
4907   }
4908 #endif
4909
4910 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
4911
4912 if (common->match_end_ptr != 0)
4913   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4914 }
4915
4916 static BOOL check_fast_forward_char_pair_sse2(compiler_common *common, fast_forward_char_data *chars, int max)
4917 {
4918 sljit_s32 i, j, priority, count;
4919 sljit_u32 priorities;
4920 PCRE2_UCHAR a1, a2, b1, b2;
4921
4922 priorities = 0;
4923
4924 count = 0;
4925 for (i = 0; i < max; i++)
4926   {
4927   if (chars[i].last_count > 2)
4928     {
4929     SLJIT_ASSERT(chars[i].last_count <= 7);
4930
4931     priorities |= (1 << chars[i].last_count);
4932     count++;
4933     }
4934   }
4935
4936 if (count < 2)
4937   return FALSE;
4938
4939 for (priority = 7; priority > 2; priority--)
4940   {
4941   if ((priorities & (1 << priority)) == 0)
4942     continue;
4943
4944   for (i = max - 1; i >= 1; i--)
4945     if (chars[i].last_count >= priority)
4946       {
4947       SLJIT_ASSERT(chars[i].count <= 2 && chars[i].count >= 1);
4948
4949       a1 = chars[i].chars[0];
4950       a2 = chars[i].chars[1];
4951
4952       j = i - max_fast_forward_char_pair_sse2_offset();
4953       if (j < 0)
4954         j = 0;
4955
4956       while (j < i)
4957         {
4958         if (chars[j].last_count >= priority)
4959           {
4960           b1 = chars[j].chars[0];
4961           b2 = chars[j].chars[1];
4962
4963           if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)
4964             {
4965             fast_forward_char_pair_sse2(common, i, a1, a2, j, b1, b2);
4966             return TRUE;
4967             }
4968           }
4969         j++;
4970         }
4971       }
4972   }
4973
4974 return FALSE;
4975 }
4976
4977 #endif
4978
4979 #undef SSE2_COMPARE_TYPE_INDEX
4980
4981 #endif
4982
4983 static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
4984 {
4985 DEFINE_COMPILER;
4986 struct sljit_label *start;
4987 struct sljit_jump *match;
4988 struct sljit_jump *partial_quit;
4989 PCRE2_UCHAR mask;
4990 BOOL has_match_end = (common->match_end_ptr != 0);
4991
4992 SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0);
4993
4994 if (has_match_end)
4995   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4996
4997 if (offset > 0)
4998   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4999
5000 if (has_match_end)
5001   {
5002   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
5003
5004   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
5005   OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
5006   CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
5007   }
5008
5009 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
5010
5011 /* SSE2 accelerated first character search. */
5012
5013 if (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
5014   {
5015   fast_forward_first_char2_sse2(common, char1, char2, offset);
5016
5017   if (offset > 0)
5018     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
5019
5020   if (has_match_end)
5021     OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
5022   return;
5023   }
5024
5025 #endif
5026
5027 start = LABEL();
5028
5029 partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5030 if (common->mode == PCRE2_JIT_COMPLETE)
5031   add_jump(compiler, &common->failed_match, partial_quit);
5032
5033 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5034 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5035
5036 if (char1 == char2)
5037   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1, start);
5038 else
5039   {
5040   mask = char1 ^ char2;
5041   if (is_powerof2(mask))
5042     {
5043     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
5044     CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start);
5045     }
5046   else
5047     {
5048     match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
5049     CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start);
5050     JUMPHERE(match);
5051     }
5052   }
5053
5054 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5055 if (common->utf && offset > 0)
5056   {
5057   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-(offset + 1)));
5058   jumpto_if_not_utf_char_start(compiler, TMP1, start);
5059   }
5060 #endif
5061
5062 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset + 1));
5063
5064 if (common->mode != PCRE2_JIT_COMPLETE)
5065   JUMPHERE(partial_quit);
5066
5067 if (has_match_end)
5068   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
5069 }
5070
5071 static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)
5072 {
5073 DEFINE_COMPILER;
5074 struct sljit_label *start;
5075 struct sljit_jump *match;
5076 fast_forward_char_data chars[MAX_N_CHARS];
5077 sljit_s32 offset;
5078 PCRE2_UCHAR mask;
5079 PCRE2_UCHAR *char_set, *char_set_end;
5080 int i, max, from;
5081 int range_right = -1, range_len;
5082 sljit_u8 *update_table = NULL;
5083 BOOL in_range;
5084 sljit_u32 rec_count;
5085
5086 for (i = 0; i < MAX_N_CHARS; i++)
5087   {
5088   chars[i].count = 0;
5089   chars[i].last_count = 0;
5090   }
5091
5092 rec_count = 10000;
5093 max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);
5094
5095 if (max < 1)
5096   return FALSE;
5097
5098 /* Convert last_count to priority. */
5099 for (i = 0; i < max; i++)
5100   {
5101   SLJIT_ASSERT(chars[i].count > 0 && chars[i].last_count <= chars[i].count);
5102
5103   if (chars[i].count == 1)
5104     {
5105     chars[i].last_count = (chars[i].last_count == 1) ? 7 : 5;
5106     /* Simplifies algorithms later. */
5107     chars[i].chars[1] = chars[i].chars[0];
5108     }
5109   else if (chars[i].count == 2)
5110     {
5111     SLJIT_ASSERT(chars[i].chars[0] != chars[i].chars[1]);
5112
5113     if (is_powerof2(chars[i].chars[0] ^ chars[i].chars[1]))
5114       chars[i].last_count = (chars[i].last_count == 2) ? 6 : 4;
5115     else
5116       chars[i].last_count = (chars[i].last_count == 2) ? 3 : 2;
5117     }
5118   else
5119     chars[i].last_count = (chars[i].count == 255) ? 0 : 1;
5120   }
5121
5122 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) && !(defined _WIN64)
5123 if (check_fast_forward_char_pair_sse2(common, chars, max))
5124   return TRUE;
5125 #endif
5126
5127 in_range = FALSE;
5128 /* Prevent compiler "uninitialized" warning */
5129 from = 0;
5130 range_len = 4 /* minimum length */ - 1;
5131 for (i = 0; i <= max; i++)
5132   {
5133   if (in_range && (i - from) > range_len && (chars[i - 1].count < 255))
5134     {
5135     range_len = i - from;
5136     range_right = i - 1;
5137     }
5138
5139   if (i < max && chars[i].count < 255)
5140     {
5141     SLJIT_ASSERT(chars[i].count > 0);
5142     if (!in_range)
5143       {
5144       in_range = TRUE;
5145       from = i;
5146       }
5147     }
5148   else
5149     in_range = FALSE;
5150   }
5151
5152 if (range_right >= 0)
5153   {
5154   update_table = (sljit_u8 *)allocate_read_only_data(common, 256);
5155   if (update_table == NULL)
5156     return TRUE;
5157   memset(update_table, IN_UCHARS(range_len), 256);
5158
5159   for (i = 0; i < range_len; i++)
5160     {
5161     SLJIT_ASSERT(chars[range_right - i].count > 0 && chars[range_right - i].count < 255);
5162
5163     char_set = chars[range_right - i].chars;
5164     char_set_end = char_set + chars[range_right - i].count;
5165     do
5166       {
5167       if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))
5168         update_table[(*char_set) & 0xff] = IN_UCHARS(i);
5169       char_set++;
5170       }
5171     while (char_set < char_set_end);
5172     }
5173   }
5174
5175 offset = -1;
5176 /* Scan forward. */
5177 for (i = 0; i < max; i++)
5178   {
5179   if (range_right == i)
5180     continue;
5181
5182   if (offset == -1)
5183     {
5184     if (chars[i].last_count >= 2)
5185       offset = i;
5186     }
5187   else if (chars[offset].last_count < chars[i].last_count)
5188     offset = i;
5189   }
5190
5191 SLJIT_ASSERT(offset == -1 || (chars[offset].count >= 1 && chars[offset].count <= 2));
5192
5193 if (range_right < 0)
5194   {
5195   if (offset < 0)
5196     return FALSE;
5197   /* Works regardless the value is 1 or 2. */
5198   fast_forward_first_char2(common, chars[offset].chars[0], chars[offset].chars[1], offset);
5199   return TRUE;
5200   }
5201
5202 SLJIT_ASSERT(range_right != offset);
5203
5204 if (common->match_end_ptr != 0)
5205   {
5206   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
5207   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
5208   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
5209   OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
5210   CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
5211   }
5212 else
5213   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
5214
5215 SLJIT_ASSERT(range_right >= 0);
5216
5217 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
5218 OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
5219 #endif
5220
5221 start = LABEL();
5222 add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
5223
5224 #if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
5225 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
5226 #else
5227 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
5228 #endif
5229
5230 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
5231 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
5232 #else
5233 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
5234 #endif
5235 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5236 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
5237
5238 if (offset >= 0)
5239   {
5240   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset));
5241   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5242
5243   if (chars[offset].count == 1)
5244     CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0], start);
5245   else
5246     {
5247     mask = chars[offset].chars[0] ^ chars[offset].chars[1];
5248     if (is_powerof2(mask))
5249       {
5250       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
5251       CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0] | mask, start);
5252       }
5253     else
5254       {
5255       match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[0]);
5256       CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset].chars[1], start);
5257       JUMPHERE(match);
5258       }
5259     }
5260   }
5261
5262 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5263 if (common->utf && offset != 0)
5264   {
5265   if (offset < 0)
5266     {
5267     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5268     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5269     }
5270   else
5271     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
5272
5273   jumpto_if_not_utf_char_start(compiler, TMP1, start);
5274
5275   if (offset < 0)
5276     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5277   }
5278 #endif
5279
5280 if (offset >= 0)
5281   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5282
5283 if (common->match_end_ptr != 0)
5284   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
5285 else
5286   OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
5287 return TRUE;
5288 }
5289
5290 static SLJIT_INLINE void fast_forward_first_char(compiler_common *common)
5291 {
5292 PCRE2_UCHAR first_char = (PCRE2_UCHAR)(common->re->first_codeunit);
5293 PCRE2_UCHAR oc;
5294
5295 oc = first_char;
5296 if ((common->re->flags & PCRE2_FIRSTCASELESS) != 0)
5297   {
5298   oc = TABLE_GET(first_char, common->fcc, first_char);
5299 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
5300   if (first_char > 127 && common->utf)
5301     oc = UCD_OTHERCASE(first_char);
5302 #endif
5303   }
5304
5305 fast_forward_first_char2(common, first_char, oc, 0);
5306 }
5307
5308 static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
5309 {
5310 DEFINE_COMPILER;
5311 struct sljit_label *loop;
5312 struct sljit_jump *lastchar;
5313 struct sljit_jump *firstchar;
5314 struct sljit_jump *quit;
5315 struct sljit_jump *foundcr = NULL;
5316 struct sljit_jump *notfoundnl;
5317 jump_list *newline = NULL;
5318
5319 if (common->match_end_ptr != 0)
5320   {
5321   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
5322   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
5323   }
5324
5325 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
5326   {
5327   lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5328   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5329   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
5330   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
5331   firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
5332
5333   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
5334   OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
5335   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
5336 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
5337   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
5338 #endif
5339   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
5340
5341   loop = LABEL();
5342   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5343   quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5344   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5345   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
5346   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
5347   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
5348
5349   JUMPHERE(quit);
5350   JUMPHERE(firstchar);
5351   JUMPHERE(lastchar);
5352
5353   if (common->match_end_ptr != 0)
5354     OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
5355   return;
5356   }
5357
5358 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5359 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
5360 firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
5361 skip_char_back(common);
5362
5363 loop = LABEL();
5364 common->ff_newline_shortcut = loop;
5365
5366 read_char_range(common, common->nlmin, common->nlmax, TRUE);
5367 lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5368 if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
5369   foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
5370 check_newlinechar(common, common->nltype, &newline, FALSE);
5371 set_jumps(newline, loop);
5372
5373 if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
5374   {
5375   quit = JUMP(SLJIT_JUMP);
5376   JUMPHERE(foundcr);
5377   notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5378   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5379   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
5380   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
5381 #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
5382   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
5383 #endif
5384   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5385   JUMPHERE(notfoundnl);
5386   JUMPHERE(quit);
5387   }
5388 JUMPHERE(lastchar);
5389 JUMPHERE(firstchar);
5390
5391 if (common->match_end_ptr != 0)
5392   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
5393 }
5394
5395 static BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
5396
5397 static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common)
5398 {
5399 DEFINE_COMPILER;
5400 const sljit_u8 *start_bits = common->re->start_bitmap;
5401 struct sljit_label *start;
5402 struct sljit_jump *partial_quit;
5403 #if PCRE2_CODE_UNIT_WIDTH != 8
5404 struct sljit_jump *found = NULL;
5405 #endif
5406 jump_list *matches = NULL;
5407
5408 if (common->match_end_ptr != 0)
5409   {
5410   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
5411   OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
5412   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
5413   OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
5414   CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
5415   }
5416
5417 start = LABEL();
5418
5419 partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5420 if (common->mode == PCRE2_JIT_COMPLETE)
5421   add_jump(compiler, &common->failed_match, partial_quit);
5422
5423 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5424 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5425
5426 if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &matches))
5427   {
5428 #if PCRE2_CODE_UNIT_WIDTH != 8
5429   if ((start_bits[31] & 0x80) != 0)
5430     found = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255);
5431   else
5432     CMPTO(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 255, start);
5433 #elif defined SUPPORT_UNICODE
5434   if (common->utf && is_char7_bitset(start_bits, FALSE))
5435     CMPTO(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 127, start);
5436 #endif
5437   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
5438   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
5439   OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
5440   if (sljit_get_register_index(TMP3) >= 0)
5441     {
5442     OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0);
5443     OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP3, 0);
5444     }
5445   else
5446     {
5447     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5448     OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
5449     }
5450   JUMPTO(SLJIT_ZERO, start);
5451   }
5452 else
5453   set_jumps(matches, start);
5454
5455 #if PCRE2_CODE_UNIT_WIDTH != 8
5456 if (found != NULL)
5457   JUMPHERE(found);
5458 #endif
5459
5460 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5461
5462 if (common->mode != PCRE2_JIT_COMPLETE)
5463   JUMPHERE(partial_quit);
5464
5465 if (common->match_end_ptr != 0)
5466   OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
5467 }
5468
5469 static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, PCRE2_UCHAR req_char, BOOL caseless, BOOL has_firstchar)
5470 {
5471 DEFINE_COMPILER;
5472 struct sljit_label *loop;
5473 struct sljit_jump *toolong;
5474 struct sljit_jump *alreadyfound;
5475 struct sljit_jump *found;
5476 struct sljit_jump *foundoc = NULL;
5477 struct sljit_jump *notfound;
5478 sljit_u32 oc, bit;
5479
5480 SLJIT_ASSERT(common->req_char_ptr != 0);
5481 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
5482 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_CU_MAX);
5483 toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0);
5484 alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
5485
5486 if (has_firstchar)
5487   OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5488 else
5489   OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
5490
5491 loop = LABEL();
5492 notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0);
5493
5494 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
5495 oc = req_char;
5496 if (caseless)
5497   {
5498   oc = TABLE_GET(req_char, common->fcc, req_char);
5499 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
5500   if (req_char > 127 && common->utf)
5501     oc = UCD_OTHERCASE(req_char);
5502 #endif
5503   }
5504 if (req_char == oc)
5505   found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
5506 else
5507   {
5508   bit = req_char ^ oc;
5509   if (is_powerof2(bit))
5510     {
5511     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
5512     found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
5513     }
5514   else
5515     {
5516     found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
5517     foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
5518     }
5519   }
5520 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
5521 JUMPTO(SLJIT_JUMP, loop);
5522
5523 JUMPHERE(found);
5524 if (foundoc)
5525   JUMPHERE(foundoc);
5526 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
5527 JUMPHERE(alreadyfound);
5528 JUMPHERE(toolong);
5529 return notfound;
5530 }
5531
5532 static void do_revertframes(compiler_common *common)
5533 {
5534 DEFINE_COMPILER;
5535 struct sljit_jump *jump;
5536 struct sljit_label *mainloop;
5537
5538 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5539 GET_LOCAL_BASE(TMP1, 0, 0);
5540
5541 /* Drop frames until we reach STACK_TOP. */
5542 mainloop = LABEL();
5543 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -sizeof(sljit_sw));
5544 jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0);
5545
5546 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
5547 if (sljit_get_register_index (TMP3) < 0)
5548   {
5549   OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
5550   OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw)));
5551   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
5552   }
5553 else
5554   {
5555   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
5556   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw)));
5557   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
5558   OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
5559   GET_LOCAL_BASE(TMP1, 0, 0);
5560   OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP3, 0);
5561   }
5562 JUMPTO(SLJIT_JUMP, mainloop);
5563
5564 JUMPHERE(jump);
5565 jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0);
5566 /* End of reverting values. */
5567 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5568
5569 JUMPHERE(jump);
5570 OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
5571 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
5572 if (sljit_get_register_index (TMP3) < 0)
5573   {
5574   OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
5575   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
5576   }
5577 else
5578   {
5579   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
5580   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
5581   OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP3, 0);
5582   }
5583 JUMPTO(SLJIT_JUMP, mainloop);
5584 }
5585
5586 static void check_wordboundary(compiler_common *common)
5587 {
5588 DEFINE_COMPILER;
5589 struct sljit_jump *skipread;
5590 jump_list *skipread_list = NULL;
5591 #if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE
5592 struct sljit_jump *jump;
5593 #endif
5594
5595 SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
5596
5597 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
5598 /* Get type of the previous char, and put it to LOCALS1. */
5599 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5600 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
5601 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0);
5602 skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
5603 skip_char_back(common);
5604 check_start_used_ptr(common);
5605 read_char(common);
5606
5607 /* Testing char type. */
5608 #ifdef SUPPORT_UNICODE
5609 if (common->use_ucp)
5610   {
5611   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
5612   jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
5613   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
5614   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
5615   OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
5616   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
5617   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
5618   OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
5619   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
5620   JUMPHERE(jump);
5621   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
5622   }
5623 else
5624 #endif
5625   {
5626 #if PCRE2_CODE_UNIT_WIDTH != 8
5627   jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5628 #elif defined SUPPORT_UNICODE
5629   /* Here LOCALS1 has already been zeroed. */
5630   jump = NULL;
5631   if (common->utf)
5632     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5633 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
5634   OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
5635   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
5636   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5637   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
5638 #if PCRE2_CODE_UNIT_WIDTH != 8
5639   JUMPHERE(jump);
5640 #elif defined SUPPORT_UNICODE
5641   if (jump != NULL)
5642     JUMPHERE(jump);
5643 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
5644   }
5645 JUMPHERE(skipread);
5646
5647 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
5648 check_str_end(common, &skipread_list);
5649 peek_char(common, READ_CHAR_MAX);
5650
5651 /* Testing char type. This is a code duplication. */
5652 #ifdef SUPPORT_UNICODE
5653 if (common->use_ucp)
5654   {
5655   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
5656   jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
5657   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
5658   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
5659   OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
5660   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
5661   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
5662   OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
5663   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
5664   JUMPHERE(jump);
5665   }
5666 else
5667 #endif
5668   {
5669 #if PCRE2_CODE_UNIT_WIDTH != 8
5670   /* TMP2 may be destroyed by peek_char. */
5671   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
5672   jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5673 #elif defined SUPPORT_UNICODE
5674   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
5675   jump = NULL;
5676   if (common->utf)
5677     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5678 #endif
5679   OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
5680   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
5681   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
5682 #if PCRE2_CODE_UNIT_WIDTH != 8
5683   JUMPHERE(jump);
5684 #elif defined SUPPORT_UNICODE
5685   if (jump != NULL)
5686     JUMPHERE(jump);
5687 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
5688   }
5689 set_jumps(skipread_list, LABEL());
5690
5691 OP2(SLJIT_XOR | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
5692 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
5693 }
5694
5695 static BOOL optimize_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
5696 {
5697 /* May destroy TMP1. */
5698 DEFINE_COMPILER;
5699 int ranges[MAX_CLASS_RANGE_SIZE];
5700 sljit_u8 bit, cbit, all;
5701 int i, byte, length = 0;
5702
5703 bit = bits[0] & 0x1;
5704 /* All bits will be zero or one (since bit is zero or one). */
5705 all = -bit;
5706
5707 for (i = 0; i < 256; )
5708   {
5709   byte = i >> 3;
5710   if ((i & 0x7) == 0 && bits[byte] == all)
5711     i += 8;
5712   else
5713     {
5714     cbit = (bits[byte] >> (i & 0x7)) & 0x1;
5715     if (cbit != bit)
5716       {
5717       if (length >= MAX_CLASS_RANGE_SIZE)
5718         return FALSE;
5719       ranges[length] = i;
5720       length++;
5721       bit = cbit;
5722       all = -cbit;
5723       }
5724     i++;
5725     }
5726   }
5727
5728 if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
5729   {
5730   if (length >= MAX_CLASS_RANGE_SIZE)
5731     return FALSE;
5732   ranges[length] = 256;
5733   length++;
5734   }
5735
5736 if (length < 0 || length > 4)
5737   return FALSE;
5738
5739 bit = bits[0] & 0x1;
5740 if (invert) bit ^= 0x1;
5741
5742 /* No character is accepted. */
5743 if (length == 0 && bit == 0)
5744   add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
5745
5746 switch(length)
5747   {
5748   case 0:
5749   /* When bit != 0, all characters are accepted. */
5750   return TRUE;
5751
5752   case 1:
5753   add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
5754   return TRUE;
5755
5756   case 2:
5757   if (ranges[0] + 1 != ranges[1])
5758     {
5759     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
5760     add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5761     }
5762   else
5763     add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
5764   return TRUE;
5765
5766   case 3:
5767   if (bit != 0)
5768     {
5769     add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
5770     if (ranges[0] + 1 != ranges[1])
5771       {
5772       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
5773       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5774       }
5775     else
5776       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
5777     return TRUE;
5778     }
5779
5780   add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
5781   if (ranges[1] + 1 != ranges[2])
5782     {
5783     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
5784     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
5785     }
5786   else
5787     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
5788   return TRUE;
5789
5790   case 4:
5791   if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
5792       && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
5793       && (ranges[1] & (ranges[2] - ranges[0])) == 0
5794       && is_powerof2(ranges[2] - ranges[0]))
5795     {
5796     SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
5797     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
5798     if (ranges[2] + 1 != ranges[3])
5799       {
5800       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
5801       add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
5802       }
5803     else
5804       add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
5805     return TRUE;
5806     }
5807
5808   if (bit != 0)
5809     {
5810     i = 0;
5811     if (ranges[0] + 1 != ranges[1])
5812       {
5813       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
5814       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5815       i = ranges[0];
5816       }
5817     else
5818       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
5819
5820     if (ranges[2] + 1 != ranges[3])
5821       {
5822       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
5823       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
5824       }
5825     else
5826       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
5827     return TRUE;
5828     }
5829
5830   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
5831   add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
5832   if (ranges[1] + 1 != ranges[2])
5833     {
5834     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
5835     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
5836     }
5837   else
5838     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5839   return TRUE;
5840
5841   default:
5842   SLJIT_UNREACHABLE();
5843   return FALSE;
5844   }
5845 }
5846
5847 static BOOL optimize_class_chars(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
5848 {
5849 /* May destroy TMP1. */
5850 DEFINE_COMPILER;
5851 uint16_t char_list[MAX_CLASS_CHARS_SIZE];
5852 uint8_t byte;
5853 sljit_s32 type;
5854 int i, j, k, len, c;
5855
5856 if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV))
5857   return FALSE;
5858
5859 if (invert)
5860   nclass = !nclass;
5861
5862 len = 0;
5863
5864 for (i = 0; i < 32; i++)
5865   {
5866   byte = bits[i];
5867
5868   if (nclass)
5869     byte = ~byte;
5870
5871   j = 0;
5872   while (byte != 0)
5873     {
5874     if (byte & 0x1)
5875       {
5876       c = i * 8 + j;
5877
5878       k = len;
5879
5880       if ((c & 0x20) != 0)
5881         {
5882         for (k = 0; k < len; k++)
5883           if (char_list[k] == c - 0x20)
5884             {
5885             char_list[k] |= 0x120;
5886             break;
5887             }
5888         }
5889
5890       if (k == len)
5891         {
5892         if (len >= MAX_CLASS_CHARS_SIZE)
5893           return FALSE;
5894
5895         char_list[len++] = (uint16_t) c;
5896         }
5897       }
5898
5899     byte >>= 1;
5900     j++;
5901     }
5902   }
5903
5904 if (len == 0) return FALSE;  /* Should never occur, but stops analyzers complaining. */
5905
5906 i = 0;
5907 j = 0;
5908
5909 if (char_list[0] == 0)
5910   {
5911   i++;
5912   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0);
5913   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_ZERO);
5914   }
5915 else
5916   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
5917
5918 while (i < len)
5919   {
5920   if ((char_list[i] & 0x100) != 0)
5921     j++;
5922   else
5923     {
5924     OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_list[i]);
5925     CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
5926     }
5927   i++;
5928   }
5929
5930 if (j != 0)
5931   {
5932   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);
5933
5934   for (i = 0; i < len; i++)
5935     if ((char_list[i] & 0x100) != 0)
5936       {
5937       j--;
5938       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff);
5939       CMOV(SLJIT_ZERO, TMP2, TMP1, 0);
5940       }
5941   }
5942
5943 type = nclass ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
5944 add_jump(compiler, backtracks, CMP(type, TMP2, 0, SLJIT_IMM, 0));
5945 return TRUE;
5946 }
5947
5948 static BOOL optimize_class(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
5949 {
5950 /* May destroy TMP1. */
5951 if (optimize_class_ranges(common, bits, nclass, invert, backtracks))
5952   return TRUE;
5953 return optimize_class_chars(common, bits, nclass, invert, backtracks);
5954 }
5955
5956 static void check_anynewline(compiler_common *common)
5957 {
5958 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
5959 DEFINE_COMPILER;
5960
5961 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5962
5963 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
5964 OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
5965 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
5966 OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
5967 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
5968 #if PCRE2_CODE_UNIT_WIDTH == 8
5969 if (common->utf)
5970   {
5971 #endif
5972   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
5973   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
5974   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
5975 #if PCRE2_CODE_UNIT_WIDTH == 8
5976   }
5977 #endif
5978 #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
5979 OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
5980 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5981 }
5982
5983 static void check_hspace(compiler_common *common)
5984 {
5985 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
5986 DEFINE_COMPILER;
5987
5988 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5989
5990 OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
5991 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
5992 OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
5993 OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
5994 OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
5995 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
5996 #if PCRE2_CODE_UNIT_WIDTH == 8
5997 if (common->utf)
5998   {
5999 #endif
6000   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6001   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
6002   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6003   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
6004   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6005   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
6006   OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
6007   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
6008   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
6009   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6010   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
6011   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6012   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
6013 #if PCRE2_CODE_UNIT_WIDTH == 8
6014   }
6015 #endif
6016 #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
6017 OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
6018
6019 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
6020 }
6021
6022 static void check_vspace(compiler_common *common)
6023 {
6024 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
6025 DEFINE_COMPILER;
6026
6027 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
6028
6029 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
6030 OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
6031 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
6032 OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
6033 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
6034 #if PCRE2_CODE_UNIT_WIDTH == 8
6035 if (common->utf)
6036   {
6037 #endif
6038   OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6039   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
6040   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
6041 #if PCRE2_CODE_UNIT_WIDTH == 8
6042   }
6043 #endif
6044 #endif /* SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == [16|32] */
6045 OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
6046
6047 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
6048 }
6049
6050 static void do_casefulcmp(compiler_common *common)
6051 {
6052 DEFINE_COMPILER;
6053 struct sljit_jump *jump;
6054 struct sljit_label *label;
6055 int char1_reg;
6056 int char2_reg;
6057
6058 if (sljit_get_register_index(TMP3) < 0)
6059   {
6060   char1_reg = STR_END;
6061   char2_reg = STACK_TOP;
6062   }
6063 else
6064   {
6065   char1_reg = TMP3;
6066   char2_reg = RETURN_ADDR;
6067   }
6068
6069 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6070 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
6071
6072 if (char1_reg == STR_END)
6073   {
6074   OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);
6075   OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
6076   }
6077
6078 if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
6079   {
6080   label = LABEL();
6081   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
6082   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6083   jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
6084   OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
6085   JUMPTO(SLJIT_NOT_ZERO, label);
6086
6087   JUMPHERE(jump);
6088   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6089   }
6090 else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
6091   {
6092   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
6093   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6094
6095   label = LABEL();
6096   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
6097   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6098   jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
6099   OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
6100   JUMPTO(SLJIT_NOT_ZERO, label);
6101
6102   JUMPHERE(jump);
6103   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6104   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6105   }
6106 else
6107   {
6108   label = LABEL();
6109   OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
6110   OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
6111   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
6112   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6113   jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
6114   OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
6115   JUMPTO(SLJIT_NOT_ZERO, label);
6116
6117   JUMPHERE(jump);
6118   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6119   }
6120
6121 if (char1_reg == STR_END)
6122   {
6123   OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);
6124   OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
6125   }
6126
6127 sljit_emit_fast_return(compiler, TMP1, 0);
6128 }
6129
6130 static void do_caselesscmp(compiler_common *common)
6131 {
6132 DEFINE_COMPILER;
6133 struct sljit_jump *jump;
6134 struct sljit_label *label;
6135 int char1_reg = STR_END;
6136 int char2_reg;
6137 int lcc_table;
6138 int opt_type = 0;
6139
6140 if (sljit_get_register_index(TMP3) < 0)
6141   {
6142   char2_reg = STACK_TOP;
6143   lcc_table = STACK_LIMIT;
6144   }
6145 else
6146   {
6147   char2_reg = RETURN_ADDR;
6148   lcc_table = TMP3;
6149   }
6150
6151 if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
6152   opt_type = 1;
6153 else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
6154   opt_type = 2;
6155
6156 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6157 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
6158
6159 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);
6160
6161 if (char2_reg == STACK_TOP)
6162   {
6163   OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);
6164   OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
6165   }
6166
6167 OP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);
6168
6169 if (opt_type == 1)
6170   {
6171   label = LABEL();
6172   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
6173   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6174   }
6175 else if (opt_type == 2)
6176   {
6177   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
6178   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6179
6180   label = LABEL();
6181   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
6182   sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6183   }
6184 else
6185   {
6186   label = LABEL();
6187   OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
6188   OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
6189   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
6190   }
6191
6192 #if PCRE2_CODE_UNIT_WIDTH != 8
6193 jump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);
6194 #endif
6195 OP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);
6196 #if PCRE2_CODE_UNIT_WIDTH != 8
6197 JUMPHERE(jump);
6198 jump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);
6199 #endif
6200 OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);
6201 #if PCRE2_CODE_UNIT_WIDTH != 8
6202 JUMPHERE(jump);
6203 #endif
6204
6205 if (opt_type == 0)
6206   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6207
6208 jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
6209 OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
6210 JUMPTO(SLJIT_NOT_ZERO, label);
6211
6212 JUMPHERE(jump);
6213 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6214
6215 if (opt_type == 2)
6216   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6217
6218 if (char2_reg == STACK_TOP)
6219   {
6220   OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);
6221   OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
6222   }
6223
6224 OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
6225 sljit_emit_fast_return(compiler, TMP1, 0);
6226 }
6227
6228 #if defined SUPPORT_UNICODE
6229
6230 static PCRE2_SPTR SLJIT_FUNC do_utf_caselesscmp(PCRE2_SPTR src1, PCRE2_SPTR src2, PCRE2_SPTR end1, PCRE2_SPTR end2)
6231 {
6232 /* This function would be ineffective to do in JIT level. */
6233 sljit_u32 c1, c2;
6234 const ucd_record *ur;
6235 const sljit_u32 *pp;
6236
6237 while (src1 < end1)
6238   {
6239   if (src2 >= end2)
6240     return (PCRE2_SPTR)1;
6241   GETCHARINC(c1, src1);
6242   GETCHARINC(c2, src2);
6243   ur = GET_UCD(c2);
6244   if (c1 != c2 && c1 != c2 + ur->other_case)
6245     {
6246     pp = PRIV(ucd_caseless_sets) + ur->caseset;
6247     for (;;)
6248       {
6249       if (c1 < *pp) return NULL;
6250       if (c1 == *pp++) break;
6251       }
6252     }
6253   }
6254 return src2;
6255 }
6256
6257 #endif /* SUPPORT_UNICODE */
6258
6259 static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc,
6260     compare_context *context, jump_list **backtracks)
6261 {
6262 DEFINE_COMPILER;
6263 unsigned int othercasebit = 0;
6264 PCRE2_SPTR othercasechar = NULL;
6265 #ifdef SUPPORT_UNICODE
6266 int utflength;
6267 #endif
6268
6269 if (caseless && char_has_othercase(common, cc))
6270   {
6271   othercasebit = char_get_othercase_bit(common, cc);
6272   SLJIT_ASSERT(othercasebit);
6273   /* Extracting bit difference info. */
6274 #if PCRE2_CODE_UNIT_WIDTH == 8
6275   othercasechar = cc + (othercasebit >> 8);
6276   othercasebit &= 0xff;
6277 #elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
6278   /* Note that this code only handles characters in the BMP. If there
6279   ever are characters outside the BMP whose othercase differs in only one
6280   bit from itself (there currently are none), this code will need to be
6281   revised for PCRE2_CODE_UNIT_WIDTH == 32. */
6282   othercasechar = cc + (othercasebit >> 9);
6283   if ((othercasebit & 0x100) != 0)
6284     othercasebit = (othercasebit & 0xff) << 8;
6285   else
6286     othercasebit &= 0xff;
6287 #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
6288   }
6289
6290 if (context->sourcereg == -1)
6291   {
6292 #if PCRE2_CODE_UNIT_WIDTH == 8
6293 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
6294   if (context->length >= 4)
6295     OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
6296   else if (context->length >= 2)
6297     OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
6298   else
6299 #endif
6300     OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
6301 #elif PCRE2_CODE_UNIT_WIDTH == 16
6302 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
6303   if (context->length >= 4)
6304     OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
6305   else
6306 #endif
6307     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
6308 #elif PCRE2_CODE_UNIT_WIDTH == 32
6309   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
6310 #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
6311   context->sourcereg = TMP2;
6312   }
6313
6314 #ifdef SUPPORT_UNICODE
6315 utflength = 1;
6316 if (common->utf && HAS_EXTRALEN(*cc))
6317   utflength += GET_EXTRALEN(*cc);
6318
6319 do
6320   {
6321 #endif
6322
6323   context->length -= IN_UCHARS(1);
6324 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
6325
6326   /* Unaligned read is supported. */
6327   if (othercasebit != 0 && othercasechar == cc)
6328     {
6329     context->c.asuchars[context->ucharptr] = *cc | othercasebit;
6330     context->oc.asuchars[context->ucharptr] = othercasebit;
6331     }
6332   else
6333     {
6334     context->c.asuchars[context->ucharptr] = *cc;
6335     context->oc.asuchars[context->ucharptr] = 0;
6336     }
6337   context->ucharptr++;
6338
6339 #if PCRE2_CODE_UNIT_WIDTH == 8
6340   if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
6341 #else
6342   if (context->ucharptr >= 2 || context->length == 0)
6343 #endif
6344     {
6345     if (context->length >= 4)
6346       OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
6347     else if (context->length >= 2)
6348       OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
6349 #if PCRE2_CODE_UNIT_WIDTH == 8
6350     else if (context->length >= 1)
6351       OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
6352 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
6353     context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
6354
6355     switch(context->ucharptr)
6356       {
6357       case 4 / sizeof(PCRE2_UCHAR):
6358       if (context->oc.asint != 0)
6359         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
6360       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
6361       break;
6362
6363       case 2 / sizeof(PCRE2_UCHAR):
6364       if (context->oc.asushort != 0)
6365         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
6366       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
6367       break;
6368
6369 #if PCRE2_CODE_UNIT_WIDTH == 8
6370       case 1:
6371       if (context->oc.asbyte != 0)
6372         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
6373       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
6374       break;
6375 #endif
6376
6377       default:
6378       SLJIT_UNREACHABLE();
6379       break;
6380       }
6381     context->ucharptr = 0;
6382     }
6383
6384 #else
6385
6386   /* Unaligned read is unsupported or in 32 bit mode. */
6387   if (context->length >= 1)
6388     OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
6389
6390   context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
6391
6392   if (othercasebit != 0 && othercasechar == cc)
6393     {
6394     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
6395     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
6396     }
6397   else
6398     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
6399
6400 #endif
6401
6402   cc++;
6403 #ifdef SUPPORT_UNICODE
6404   utflength--;
6405   }
6406 while (utflength > 0);
6407 #endif
6408
6409 return cc;
6410 }
6411
6412 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
6413
6414 #define SET_TYPE_OFFSET(value) \
6415   if ((value) != typeoffset) \
6416     { \
6417     if ((value) < typeoffset) \
6418       OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
6419     else \
6420       OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
6421     } \
6422   typeoffset = (value);
6423
6424 #define SET_CHAR_OFFSET(value) \
6425   if ((value) != charoffset) \
6426     { \
6427     if ((value) < charoffset) \
6428       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
6429     else \
6430       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
6431     } \
6432   charoffset = (value);
6433
6434 static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr);
6435
6436 static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)
6437 {
6438 DEFINE_COMPILER;
6439 jump_list *found = NULL;
6440 jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
6441 sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
6442 struct sljit_jump *jump = NULL;
6443 PCRE2_SPTR ccbegin;
6444 int compares, invertcmp, numberofcmps;
6445 #if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
6446 BOOL utf = common->utf;
6447 #endif
6448
6449 #ifdef SUPPORT_UNICODE
6450 BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
6451 BOOL charsaved = FALSE;
6452 int typereg = TMP1;
6453 const sljit_u32 *other_cases;
6454 sljit_uw typeoffset;
6455 #endif
6456
6457 /* Scanning the necessary info. */
6458 cc++;
6459 ccbegin = cc;
6460 compares = 0;
6461
6462 if (cc[-1] & XCL_MAP)
6463   {
6464   min = 0;
6465   cc += 32 / sizeof(PCRE2_UCHAR);
6466   }
6467
6468 while (*cc != XCL_END)
6469   {
6470   compares++;
6471   if (*cc == XCL_SINGLE)
6472     {
6473     cc ++;
6474     GETCHARINCTEST(c, cc);
6475     if (c > max) max = c;
6476     if (c < min) min = c;
6477 #ifdef SUPPORT_UNICODE
6478     needschar = TRUE;
6479 #endif
6480     }
6481   else if (*cc == XCL_RANGE)
6482     {
6483     cc ++;
6484     GETCHARINCTEST(c, cc);
6485     if (c < min) min = c;
6486     GETCHARINCTEST(c, cc);
6487     if (c > max) max = c;
6488 #ifdef SUPPORT_UNICODE
6489     needschar = TRUE;
6490 #endif
6491     }
6492 #ifdef SUPPORT_UNICODE
6493   else
6494     {
6495     SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
6496     cc++;
6497     if (*cc == PT_CLIST)
6498       {
6499       other_cases = PRIV(ucd_caseless_sets) + cc[1];
6500       while (*other_cases != NOTACHAR)
6501         {
6502         if (*other_cases > max) max = *other_cases;
6503         if (*other_cases < min) min = *other_cases;
6504         other_cases++;
6505         }
6506       }
6507     else
6508       {
6509       max = READ_CHAR_MAX;
6510       min = 0;
6511       }
6512
6513     switch(*cc)
6514       {
6515       case PT_ANY:
6516       /* Any either accepts everything or ignored. */
6517       if (cc[-1] == XCL_PROP)
6518         {
6519         compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE);
6520         if (list == backtracks)
6521           add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6522         return;
6523         }
6524       break;
6525
6526       case PT_LAMP:
6527       case PT_GC:
6528       case PT_PC:
6529       case PT_ALNUM:
6530       needstype = TRUE;
6531       break;
6532
6533       case PT_SC:
6534       needsscript = TRUE;
6535       break;
6536
6537       case PT_SPACE:
6538       case PT_PXSPACE:
6539       case PT_WORD:
6540       case PT_PXGRAPH:
6541       case PT_PXPRINT:
6542       case PT_PXPUNCT:
6543       needstype = TRUE;
6544       needschar = TRUE;
6545       break;
6546
6547       case PT_CLIST:
6548       case PT_UCNC:
6549       needschar = TRUE;
6550       break;
6551
6552       default:
6553       SLJIT_UNREACHABLE();
6554       break;
6555       }
6556     cc += 2;
6557     }
6558 #endif
6559   }
6560 SLJIT_ASSERT(compares > 0);
6561
6562 /* We are not necessary in utf mode even in 8 bit mode. */
6563 cc = ccbegin;
6564 read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
6565
6566 if ((cc[-1] & XCL_HASPROP) == 0)
6567   {
6568   if ((cc[-1] & XCL_MAP) != 0)
6569     {
6570     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
6571     if (!optimize_class(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found))
6572       {
6573       OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
6574       OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
6575       OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
6576       OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
6577       OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
6578       add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
6579       }
6580
6581     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6582     JUMPHERE(jump);
6583
6584     cc += 32 / sizeof(PCRE2_UCHAR);
6585     }
6586   else
6587     {
6588     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
6589     add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));
6590     }
6591   }
6592 else if ((cc[-1] & XCL_MAP) != 0)
6593   {
6594   OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
6595 #ifdef SUPPORT_UNICODE
6596   charsaved = TRUE;
6597 #endif
6598   if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list))
6599     {
6600 #if PCRE2_CODE_UNIT_WIDTH == 8
6601     jump = NULL;
6602     if (common->utf)
6603 #endif
6604       jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
6605
6606     OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
6607     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
6608     OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
6609     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
6610     OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
6611     add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
6612
6613 #if PCRE2_CODE_UNIT_WIDTH == 8
6614     if (common->utf)
6615 #endif
6616       JUMPHERE(jump);
6617     }
6618
6619   OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
6620   cc += 32 / sizeof(PCRE2_UCHAR);
6621   }
6622
6623 #ifdef SUPPORT_UNICODE
6624 if (needstype || needsscript)
6625   {
6626   if (needschar && !charsaved)
6627     OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
6628
6629 #if PCRE2_CODE_UNIT_WIDTH == 32
6630   if (!common->utf)
6631     {
6632     jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1);
6633     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR);
6634     JUMPHERE(jump);
6635     }
6636 #endif
6637
6638   OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
6639   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
6640   OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
6641   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
6642   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
6643   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
6644   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
6645   OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
6646
6647   /* Before anything else, we deal with scripts. */
6648   if (needsscript)
6649     {
6650     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
6651     OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
6652
6653     ccbegin = cc;
6654
6655     while (*cc != XCL_END)
6656       {
6657       if (*cc == XCL_SINGLE)
6658         {
6659         cc ++;
6660         GETCHARINCTEST(c, cc);
6661         }
6662       else if (*cc == XCL_RANGE)
6663         {
6664         cc ++;
6665         GETCHARINCTEST(c, cc);
6666         GETCHARINCTEST(c, cc);
6667         }
6668       else
6669         {
6670         SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
6671         cc++;
6672         if (*cc == PT_SC)
6673           {
6674           compares--;
6675           invertcmp = (compares == 0 && list != backtracks);
6676           if (cc[-1] == XCL_NOTPROP)
6677             invertcmp ^= 0x1;
6678           jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]);
6679           add_jump(compiler, compares > 0 ? list : backtracks, jump);
6680           }
6681         cc += 2;
6682         }
6683       }
6684
6685     cc = ccbegin;
6686     }
6687
6688   if (needschar)
6689     {
6690     OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
6691     }
6692
6693   if (needstype)
6694     {
6695     if (!needschar)
6696       {
6697       OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
6698       OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
6699       }
6700     else
6701       {
6702       OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
6703       OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
6704       typereg = RETURN_ADDR;
6705       }
6706     }
6707   }
6708 #endif
6709
6710 /* Generating code. */
6711 charoffset = 0;
6712 numberofcmps = 0;
6713 #ifdef SUPPORT_UNICODE
6714 typeoffset = 0;
6715 #endif
6716
6717 while (*cc != XCL_END)
6718   {
6719   compares--;
6720   invertcmp = (compares == 0 && list != backtracks);
6721   jump = NULL;
6722
6723   if (*cc == XCL_SINGLE)
6724     {
6725     cc ++;
6726     GETCHARINCTEST(c, cc);
6727
6728     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
6729       {
6730       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
6731       OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6732       numberofcmps++;
6733       }
6734     else if (numberofcmps > 0)
6735       {
6736       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
6737       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
6738       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6739       numberofcmps = 0;
6740       }
6741     else
6742       {
6743       jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
6744       numberofcmps = 0;
6745       }
6746     }
6747   else if (*cc == XCL_RANGE)
6748     {
6749     cc ++;
6750     GETCHARINCTEST(c, cc);
6751     SET_CHAR_OFFSET(c);
6752     GETCHARINCTEST(c, cc);
6753
6754     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
6755       {
6756       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
6757       OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
6758       numberofcmps++;
6759       }
6760     else if (numberofcmps > 0)
6761       {
6762       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
6763       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
6764       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6765       numberofcmps = 0;
6766       }
6767     else
6768       {
6769       jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
6770       numberofcmps = 0;
6771       }
6772     }
6773 #ifdef SUPPORT_UNICODE
6774   else
6775     {
6776     SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
6777     if (*cc == XCL_NOTPROP)
6778       invertcmp ^= 0x1;
6779     cc++;
6780     switch(*cc)
6781       {
6782       case PT_ANY:
6783       if (!invertcmp)
6784         jump = JUMP(SLJIT_JUMP);
6785       break;
6786
6787       case PT_LAMP:
6788       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
6789       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
6790       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
6791       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6792       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
6793       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
6794       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6795       break;
6796
6797       case PT_GC:
6798       c = PRIV(ucp_typerange)[(int)cc[1] * 2];
6799       SET_TYPE_OFFSET(c);
6800       jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
6801       break;
6802
6803       case PT_PC:
6804       jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
6805       break;
6806
6807       case PT_SC:
6808       compares++;
6809       /* Do nothing. */
6810       break;
6811
6812       case PT_SPACE:
6813       case PT_PXSPACE:
6814       SET_CHAR_OFFSET(9);
6815       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
6816       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
6817
6818       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
6819       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6820
6821       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
6822       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6823
6824       SET_TYPE_OFFSET(ucp_Zl);
6825       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
6826       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
6827       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6828       break;
6829
6830       case PT_WORD:
6831       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
6832       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
6833       /* Fall through. */
6834
6835       case PT_ALNUM:
6836       SET_TYPE_OFFSET(ucp_Ll);
6837       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
6838       OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
6839       SET_TYPE_OFFSET(ucp_Nd);
6840       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
6841       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
6842       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6843       break;
6844
6845       case PT_CLIST:
6846       other_cases = PRIV(ucd_caseless_sets) + cc[1];
6847
6848       /* At least three characters are required.
6849          Otherwise this case would be handled by the normal code path. */
6850       SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
6851       SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
6852
6853       /* Optimizing character pairs, if their difference is power of 2. */
6854       if (is_powerof2(other_cases[1] ^ other_cases[0]))
6855         {
6856         if (charoffset == 0)
6857           OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
6858         else
6859           {
6860           OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
6861           OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
6862           }
6863         OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
6864         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
6865         other_cases += 2;
6866         }
6867       else if (is_powerof2(other_cases[2] ^ other_cases[1]))
6868         {
6869         if (charoffset == 0)
6870           OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
6871         else
6872           {
6873           OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
6874           OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
6875           }
6876         OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
6877         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
6878
6879         OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
6880         OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);
6881
6882         other_cases += 3;
6883         }
6884       else
6885         {
6886         OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
6887         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
6888         }
6889
6890       while (*other_cases != NOTACHAR)
6891         {
6892         OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
6893         OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_Z : 0), TMP2, 0, SLJIT_EQUAL);
6894         }
6895       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6896       break;
6897
6898       case PT_UCNC:
6899       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
6900       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
6901       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
6902       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6903       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
6904       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6905
6906       SET_CHAR_OFFSET(0xa0);
6907       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
6908       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
6909       SET_CHAR_OFFSET(0);
6910       OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
6911       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_GREATER_EQUAL);
6912       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6913       break;
6914
6915       case PT_PXGRAPH:
6916       /* C and Z groups are the farthest two groups. */
6917       SET_TYPE_OFFSET(ucp_Ll);
6918       OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
6919       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
6920
6921       jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
6922
6923       /* In case of ucp_Cf, we overwrite the result. */
6924       SET_CHAR_OFFSET(0x2066);
6925       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
6926       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
6927
6928       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
6929       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6930
6931       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
6932       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6933
6934       JUMPHERE(jump);
6935       jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
6936       break;
6937
6938       case PT_PXPRINT:
6939       /* C and Z groups are the farthest two groups. */
6940       SET_TYPE_OFFSET(ucp_Ll);
6941       OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
6942       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER);
6943
6944       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
6945       OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_NOT_EQUAL);
6946
6947       jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
6948
6949       /* In case of ucp_Cf, we overwrite the result. */
6950       SET_CHAR_OFFSET(0x2066);
6951       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
6952       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
6953
6954       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
6955       OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
6956
6957       JUMPHERE(jump);
6958       jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
6959       break;
6960
6961       case PT_PXPUNCT:
6962       SET_TYPE_OFFSET(ucp_Sc);
6963       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
6964       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
6965
6966       SET_CHAR_OFFSET(0);
6967       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
6968       OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL);
6969
6970       SET_TYPE_OFFSET(ucp_Pc);
6971       OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
6972       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL);
6973       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
6974       break;
6975
6976       default:
6977       SLJIT_UNREACHABLE();
6978       break;
6979       }
6980     cc += 2;
6981     }
6982 #endif
6983
6984   if (jump != NULL)
6985     add_jump(compiler, compares > 0 ? list : backtracks, jump);
6986   }
6987
6988 if (found != NULL)
6989   set_jumps(found, LABEL());
6990 }
6991
6992 #undef SET_TYPE_OFFSET
6993 #undef SET_CHAR_OFFSET
6994
6995 #endif
6996
6997 static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks)
6998 {
6999 DEFINE_COMPILER;
7000 int length;
7001 struct sljit_jump *jump[4];
7002 #ifdef SUPPORT_UNICODE
7003 struct sljit_label *label;
7004 #endif /* SUPPORT_UNICODE */
7005
7006 switch(type)
7007   {
7008   case OP_SOD:
7009   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7010   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
7011   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
7012   return cc;
7013
7014   case OP_SOM:
7015   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7016   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
7017   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
7018   return cc;
7019
7020   case OP_NOT_WORD_BOUNDARY:
7021   case OP_WORD_BOUNDARY:
7022   add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
7023   sljit_set_current_flags(compiler, SLJIT_SET_Z);
7024   add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
7025   return cc;
7026
7027   case OP_EODN:
7028   /* Requires rather complex checks. */
7029   jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
7030   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
7031     {
7032     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
7033     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
7034     if (common->mode == PCRE2_JIT_COMPLETE)
7035       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
7036     else
7037       {
7038       jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
7039       OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
7040       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS);
7041       OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
7042       OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_EQUAL);
7043       add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
7044       check_partial(common, TRUE);
7045       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
7046       JUMPHERE(jump[1]);
7047       }
7048     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
7049     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
7050     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
7051     }
7052   else if (common->nltype == NLTYPE_FIXED)
7053     {
7054     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7055     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
7056     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
7057     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
7058     }
7059   else
7060     {
7061     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
7062     jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
7063     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
7064     OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
7065     jump[2] = JUMP(SLJIT_GREATER);
7066     add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL) /* LESS */);
7067     /* Equal. */
7068     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
7069     jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
7070     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
7071
7072     JUMPHERE(jump[1]);
7073     if (common->nltype == NLTYPE_ANYCRLF)
7074       {
7075       OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7076       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));
7077       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
7078       }
7079     else
7080       {
7081       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
7082       read_char_range(common, common->nlmin, common->nlmax, TRUE);
7083       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
7084       add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
7085       sljit_set_current_flags(compiler, SLJIT_SET_Z);
7086       add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
7087       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
7088       }
7089     JUMPHERE(jump[2]);
7090     JUMPHERE(jump[3]);
7091     }
7092   JUMPHERE(jump[0]);
7093   check_partial(common, FALSE);
7094   return cc;
7095
7096   case OP_EOD:
7097   add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
7098   check_partial(common, FALSE);
7099   return cc;
7100
7101   case OP_DOLL:
7102   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
7103   OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
7104   add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
7105
7106   if (!common->endonly)
7107     compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
7108   else
7109     {
7110     add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
7111     check_partial(common, FALSE);
7112     }
7113   return cc;
7114
7115   case OP_DOLLM:
7116   jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
7117   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
7118   OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
7119   add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
7120   check_partial(common, FALSE);
7121   jump[0] = JUMP(SLJIT_JUMP);
7122   JUMPHERE(jump[1]);
7123
7124   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
7125     {
7126     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
7127     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
7128     if (common->mode == PCRE2_JIT_COMPLETE)
7129       add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));
7130     else
7131       {
7132       jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
7133       /* STR_PTR = STR_END - IN_UCHARS(1) */
7134       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
7135       check_partial(common, TRUE);
7136       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
7137       JUMPHERE(jump[1]);
7138       }
7139
7140     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
7141     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
7142     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
7143     }
7144   else
7145     {
7146     peek_char(common, common->nlmax);
7147     check_newlinechar(common, common->nltype, backtracks, FALSE);
7148     }
7149   JUMPHERE(jump[0]);
7150   return cc;
7151
7152   case OP_CIRC:
7153   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
7154   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
7155   add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
7156   OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
7157   add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
7158   return cc;
7159
7160   case OP_CIRCM:
7161   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
7162   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
7163   jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);
7164   OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
7165   add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
7166   jump[0] = JUMP(SLJIT_JUMP);
7167   JUMPHERE(jump[1]);
7168
7169   if (!common->alt_circumflex)
7170     add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
7171
7172   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
7173     {
7174     OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
7175     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0));
7176     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
7177     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
7178     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
7179     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
7180     }
7181   else
7182     {
7183     skip_char_back(common);
7184     read_char_range(common, common->nlmin, common->nlmax, TRUE);
7185     check_newlinechar(common, common->nltype, backtracks, FALSE);
7186     }
7187   JUMPHERE(jump[0]);
7188   return cc;
7189
7190   case OP_REVERSE:
7191   length = GET(cc, 0);
7192   if (length == 0)
7193     return cc + LINK_SIZE;
7194   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7195 #ifdef SUPPORT_UNICODE
7196   if (common->utf)
7197     {
7198     OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
7199     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
7200     label = LABEL();
7201     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
7202     skip_char_back(common);
7203     OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
7204     JUMPTO(SLJIT_NOT_ZERO, label);
7205     }
7206   else
7207 #endif
7208     {
7209     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
7210     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
7211     add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));
7212     }
7213   check_start_used_ptr(common);
7214   return cc + LINK_SIZE;
7215   }
7216 SLJIT_UNREACHABLE();
7217 return cc;
7218 }
7219
7220 #ifdef SUPPORT_UNICODE
7221
7222 #if PCRE2_CODE_UNIT_WIDTH != 32
7223
7224 static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)
7225 {
7226 PCRE2_SPTR start_subject = args->begin;
7227 PCRE2_SPTR end_subject = args->end;
7228 int lgb, rgb, len, ricount;
7229 PCRE2_SPTR prevcc, bptr;
7230 uint32_t c;
7231
7232 prevcc = cc;
7233 GETCHARINC(c, cc);
7234 lgb = UCD_GRAPHBREAK(c);
7235
7236 while (cc < end_subject)
7237   {
7238   len = 1;
7239   GETCHARLEN(c, cc, len);
7240   rgb = UCD_GRAPHBREAK(c);
7241
7242   if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
7243
7244   /* Not breaking between Regional Indicators is allowed only if there
7245   are an even number of preceding RIs. */
7246
7247   if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator)
7248     {
7249     ricount = 0;
7250     bptr = prevcc;
7251
7252     /* bptr is pointing to the left-hand character */
7253     while (bptr > start_subject)
7254       {
7255       bptr--;
7256       BACKCHAR(bptr);
7257       GETCHAR(c, bptr);
7258
7259       if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break;
7260
7261       ricount++;
7262       }
7263
7264     if ((ricount & 1) != 0) break;  /* Grapheme break required */
7265     }
7266
7267   /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
7268   allows any number of them before a following Extended_Pictographic. */
7269
7270   if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
7271        lgb != ucp_gbExtended_Pictographic)
7272     lgb = rgb;
7273
7274   prevcc = cc;
7275   cc += len;
7276   }
7277
7278 return cc;
7279 }
7280
7281 #endif
7282
7283 static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc)
7284 {
7285 PCRE2_SPTR start_subject = args->begin;
7286 PCRE2_SPTR end_subject = args->end;
7287 int lgb, rgb, ricount;
7288 PCRE2_SPTR bptr;
7289 uint32_t c;
7290
7291 GETCHARINC(c, cc);
7292 lgb = UCD_GRAPHBREAK(c);
7293
7294 while (cc < end_subject)
7295   {
7296   c = *cc;
7297   rgb = UCD_GRAPHBREAK(c);
7298
7299   if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
7300
7301   /* Not breaking between Regional Indicators is allowed only if there
7302   are an even number of preceding RIs. */
7303
7304   if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator)
7305     {
7306     ricount = 0;
7307     bptr = cc - 1;
7308
7309     /* bptr is pointing to the left-hand character */
7310     while (bptr > start_subject)
7311       {
7312       bptr--;
7313       c = *bptr;
7314
7315       if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break;
7316
7317       ricount++;
7318       }
7319
7320     if ((ricount & 1) != 0) break;  /* Grapheme break required */
7321     }
7322
7323   /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
7324   allows any number of them before a following Extended_Pictographic. */
7325
7326   if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
7327        lgb != ucp_gbExtended_Pictographic)
7328     lgb = rgb;
7329
7330   cc++;
7331   }
7332
7333 return cc;
7334 }
7335
7336 #endif
7337
7338 static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr)
7339 {
7340 DEFINE_COMPILER;
7341 int length;
7342 unsigned int c, oc, bit;
7343 compare_context context;
7344 struct sljit_jump *jump[3];
7345 jump_list *end_list;
7346 #ifdef SUPPORT_UNICODE
7347 PCRE2_UCHAR propdata[5];
7348 #endif /* SUPPORT_UNICODE */
7349
7350 switch(type)
7351   {
7352   case OP_NOT_DIGIT:
7353   case OP_DIGIT:
7354   /* Digits are usually 0-9, so it is worth to optimize them. */
7355   if (check_str_ptr)
7356     detect_partial_match(common, backtracks);
7357 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
7358   if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE))
7359     read_char7_type(common, type == OP_NOT_DIGIT);
7360   else
7361 #endif
7362     read_char8_type(common, type == OP_NOT_DIGIT);
7363     /* Flip the starting bit in the negative case. */
7364   OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
7365   add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
7366   return cc;
7367
7368   case OP_NOT_WHITESPACE:
7369   case OP_WHITESPACE:
7370   if (check_str_ptr)
7371     detect_partial_match(common, backtracks);
7372 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
7373   if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE))
7374     read_char7_type(common, type == OP_NOT_WHITESPACE);
7375   else
7376 #endif
7377     read_char8_type(common, type == OP_NOT_WHITESPACE);
7378   OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
7379   add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
7380   return cc;
7381
7382   case OP_NOT_WORDCHAR:
7383   case OP_WORDCHAR:
7384   if (check_str_ptr)
7385     detect_partial_match(common, backtracks);
7386 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
7387   if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE))
7388     read_char7_type(common, type == OP_NOT_WORDCHAR);
7389   else
7390 #endif
7391     read_char8_type(common, type == OP_NOT_WORDCHAR);
7392   OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
7393   add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
7394   return cc;
7395
7396   case OP_ANY:
7397   if (check_str_ptr)
7398     detect_partial_match(common, backtracks);
7399   read_char_range(common, common->nlmin, common->nlmax, TRUE);
7400   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
7401     {
7402     jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
7403     end_list = NULL;
7404     if (common->mode != PCRE2_JIT_PARTIAL_HARD)
7405       add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
7406     else
7407       check_str_end(common, &end_list);
7408
7409     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
7410     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
7411     set_jumps(end_list, LABEL());
7412     JUMPHERE(jump[0]);
7413     }
7414   else
7415     check_newlinechar(common, common->nltype, backtracks, TRUE);
7416   return cc;
7417
7418   case OP_ALLANY:
7419   if (check_str_ptr)
7420     detect_partial_match(common, backtracks);
7421 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
7422   if (common->utf)
7423     {
7424     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
7425     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7426 #if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
7427 #if PCRE2_CODE_UNIT_WIDTH == 8
7428     jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
7429     OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
7430     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
7431 #elif PCRE2_CODE_UNIT_WIDTH == 16
7432     jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
7433     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
7434     OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
7435     OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL);
7436     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7437     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
7438 #endif
7439     JUMPHERE(jump[0]);
7440 #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */
7441     return cc;
7442     }
7443 #endif
7444   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7445   return cc;
7446
7447   case OP_ANYBYTE:
7448   if (check_str_ptr)
7449     detect_partial_match(common, backtracks);
7450   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7451   return cc;
7452
7453 #ifdef SUPPORT_UNICODE
7454   case OP_NOTPROP:
7455   case OP_PROP:
7456   propdata[0] = XCL_HASPROP;
7457   propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
7458   propdata[2] = cc[0];
7459   propdata[3] = cc[1];
7460   propdata[4] = XCL_END;
7461   if (check_str_ptr)
7462     detect_partial_match(common, backtracks);
7463   compile_xclass_matchingpath(common, propdata, backtracks);
7464   return cc + 2;
7465 #endif
7466
7467   case OP_ANYNL:
7468   if (check_str_ptr)
7469     detect_partial_match(common, backtracks);
7470   read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
7471   jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
7472   /* We don't need to handle soft partial matching case. */
7473   end_list = NULL;
7474   if (common->mode != PCRE2_JIT_PARTIAL_HARD)
7475     add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
7476   else
7477     check_str_end(common, &end_list);
7478   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
7479   jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
7480   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7481   jump[2] = JUMP(SLJIT_JUMP);
7482   JUMPHERE(jump[0]);
7483   check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
7484   set_jumps(end_list, LABEL());
7485   JUMPHERE(jump[1]);
7486   JUMPHERE(jump[2]);
7487   return cc;
7488
7489   case OP_NOT_HSPACE:
7490   case OP_HSPACE:
7491   if (check_str_ptr)
7492     detect_partial_match(common, backtracks);
7493   read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
7494   add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
7495   sljit_set_current_flags(compiler, SLJIT_SET_Z);
7496   add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
7497   return cc;
7498
7499   case OP_NOT_VSPACE:
7500   case OP_VSPACE:
7501   if (check_str_ptr)
7502     detect_partial_match(common, backtracks);
7503   read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
7504   add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
7505   sljit_set_current_flags(compiler, SLJIT_SET_Z);
7506   add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
7507   return cc;
7508
7509 #ifdef SUPPORT_UNICODE
7510   case OP_EXTUNI:
7511   if (check_str_ptr)
7512     detect_partial_match(common, backtracks);
7513
7514   SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
7515   OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
7516
7517 #if PCRE2_CODE_UNIT_WIDTH != 32
7518   sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
7519       common->utf ? SLJIT_FUNC_OFFSET(do_extuni_utf) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));
7520 #else
7521   sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf));
7522 #endif
7523
7524   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
7525
7526   if (common->mode == PCRE2_JIT_PARTIAL_HARD)
7527     {
7528     jump[0] = CMP(SLJIT_LESS, SLJIT_RETURN_REG, 0, STR_END, 0);
7529     /* Since we successfully read a char above, partial matching must occure. */
7530     check_partial(common, TRUE);
7531     JUMPHERE(jump[0]);
7532     }
7533   return cc;
7534 #endif
7535
7536   case OP_CHAR:
7537   case OP_CHARI:
7538   length = 1;
7539 #ifdef SUPPORT_UNICODE
7540   if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
7541 #endif
7542   if (common->mode == PCRE2_JIT_COMPLETE && check_str_ptr
7543       && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
7544     {
7545     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
7546     add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
7547
7548     context.length = IN_UCHARS(length);
7549     context.sourcereg = -1;
7550 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
7551     context.ucharptr = 0;
7552 #endif
7553     return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
7554     }
7555
7556   if (check_str_ptr)
7557     detect_partial_match(common, backtracks);
7558 #ifdef SUPPORT_UNICODE
7559   if (common->utf)
7560     {
7561     GETCHAR(c, cc);
7562     }
7563   else
7564 #endif
7565     c = *cc;
7566
7567   if (type == OP_CHAR || !char_has_othercase(common, cc))
7568     {
7569     read_char_range(common, c, c, FALSE);
7570     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
7571     return cc + length;
7572     }
7573   oc = char_othercase(common, c);
7574   read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
7575   bit = c ^ oc;
7576   if (is_powerof2(bit))
7577     {
7578     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
7579     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
7580     return cc + length;
7581     }
7582   jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);
7583   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
7584   JUMPHERE(jump[0]);
7585   return cc + length;
7586
7587   case OP_NOT:
7588   case OP_NOTI:
7589   if (check_str_ptr)
7590     detect_partial_match(common, backtracks);
7591
7592   length = 1;
7593 #ifdef SUPPORT_UNICODE
7594   if (common->utf)
7595     {
7596 #if PCRE2_CODE_UNIT_WIDTH == 8
7597     c = *cc;
7598     if (c < 128)
7599       {
7600       OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
7601       if (type == OP_NOT || !char_has_othercase(common, cc))
7602         add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
7603       else
7604         {
7605         /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
7606         OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
7607         add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
7608         }
7609       /* Skip the variable-length character. */
7610       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
7611       jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
7612       OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
7613       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
7614       JUMPHERE(jump[0]);
7615       return cc + 1;
7616       }
7617     else
7618 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
7619       {
7620       GETCHARLEN(c, cc, length);
7621       }
7622     }
7623   else
7624 #endif /* SUPPORT_UNICODE */
7625     c = *cc;
7626
7627   if (type == OP_NOT || !char_has_othercase(common, cc))
7628     {
7629     read_char_range(common, c, c, TRUE);
7630     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
7631     }
7632   else
7633     {
7634     oc = char_othercase(common, c);
7635     read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
7636     bit = c ^ oc;
7637     if (is_powerof2(bit))
7638       {
7639       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
7640       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
7641       }
7642     else
7643       {
7644       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
7645       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
7646       }
7647     }
7648   return cc + length;
7649
7650   case OP_CLASS:
7651   case OP_NCLASS:
7652   if (check_str_ptr)
7653     detect_partial_match(common, backtracks);
7654
7655 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
7656   bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255;
7657   read_char_range(common, 0, bit, type == OP_NCLASS);
7658 #else
7659   read_char_range(common, 0, 255, type == OP_NCLASS);
7660 #endif
7661
7662   if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))
7663     return cc + 32 / sizeof(PCRE2_UCHAR);
7664
7665 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
7666   jump[0] = NULL;
7667   if (common->utf)
7668     {
7669     jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);
7670     if (type == OP_CLASS)
7671       {
7672       add_jump(compiler, backtracks, jump[0]);
7673       jump[0] = NULL;
7674       }
7675     }
7676 #elif PCRE2_CODE_UNIT_WIDTH != 8
7677   jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
7678   if (type == OP_CLASS)
7679     {
7680     add_jump(compiler, backtracks, jump[0]);
7681     jump[0] = NULL;
7682     }
7683 #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
7684
7685   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
7686   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
7687   OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
7688   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
7689   OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
7690   add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
7691
7692 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
7693   if (jump[0] != NULL)
7694     JUMPHERE(jump[0]);
7695 #endif
7696   return cc + 32 / sizeof(PCRE2_UCHAR);
7697
7698 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
7699   case OP_XCLASS:
7700   if (check_str_ptr)
7701     detect_partial_match(common, backtracks);
7702   compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
7703   return cc + GET(cc, 0) - 1;
7704 #endif
7705   }
7706 SLJIT_UNREACHABLE();
7707 return cc;
7708 }
7709
7710 static SLJIT_INLINE PCRE2_SPTR compile_charn_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, jump_list **backtracks)
7711 {
7712 /* This function consumes at least one input character. */
7713 /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
7714 DEFINE_COMPILER;
7715 PCRE2_SPTR ccbegin = cc;
7716 compare_context context;
7717 int size;
7718
7719 context.length = 0;
7720 do
7721   {
7722   if (cc >= ccend)
7723     break;
7724
7725   if (*cc == OP_CHAR)
7726     {
7727     size = 1;
7728 #ifdef SUPPORT_UNICODE
7729     if (common->utf && HAS_EXTRALEN(cc[1]))
7730       size += GET_EXTRALEN(cc[1]);
7731 #endif
7732     }
7733   else if (*cc == OP_CHARI)
7734     {
7735     size = 1;
7736 #ifdef SUPPORT_UNICODE
7737     if (common->utf)
7738       {
7739       if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
7740         size = 0;
7741       else if (HAS_EXTRALEN(cc[1]))
7742         size += GET_EXTRALEN(cc[1]);
7743       }
7744     else
7745 #endif
7746     if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
7747       size = 0;
7748     }
7749   else
7750     size = 0;
7751
7752   cc += 1 + size;
7753   context.length += IN_UCHARS(size);
7754   }
7755 while (size > 0 && context.length <= 128);
7756
7757 cc = ccbegin;
7758 if (context.length > 0)
7759   {
7760   /* We have a fixed-length byte sequence. */
7761   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
7762   add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
7763
7764   context.sourcereg = -1;
7765 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
7766   context.ucharptr = 0;
7767 #endif
7768   do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
7769   return cc;
7770   }
7771
7772 /* A non-fixed length character will be checked if length == 0. */
7773 return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);
7774 }
7775
7776 /* Forward definitions. */
7777 static void compile_matchingpath(compiler_common *, PCRE2_SPTR, PCRE2_SPTR, backtrack_common *);
7778 static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
7779
7780 #define PUSH_BACKTRACK(size, ccstart, error) \
7781   do \
7782     { \
7783     backtrack = sljit_alloc_memory(compiler, (size)); \
7784     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
7785       return error; \
7786     memset(backtrack, 0, size); \
7787     backtrack->prev = parent->top; \
7788     backtrack->cc = (ccstart); \
7789     parent->top = backtrack; \
7790     } \
7791   while (0)
7792
7793 #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
7794   do \
7795     { \
7796     backtrack = sljit_alloc_memory(compiler, (size)); \
7797     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
7798       return; \
7799     memset(backtrack, 0, size); \
7800     backtrack->prev = parent->top; \
7801     backtrack->cc = (ccstart); \
7802     parent->top = backtrack; \
7803     } \
7804   while (0)
7805
7806 #define BACKTRACK_AS(type) ((type *)backtrack)
7807
7808 static void compile_dnref_search(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks)
7809 {
7810 /* The OVECTOR offset goes to TMP2. */
7811 DEFINE_COMPILER;
7812 int count = GET2(cc, 1 + IMM2_SIZE);
7813 PCRE2_SPTR slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
7814 unsigned int offset;
7815 jump_list *found = NULL;
7816
7817 SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
7818
7819 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
7820
7821 count--;
7822 while (count-- > 0)
7823   {
7824   offset = GET2(slot, 0) << 1;
7825   GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
7826   add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
7827   slot += common->name_entry_size;
7828   }
7829
7830 offset = GET2(slot, 0) << 1;
7831 GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
7832 if (backtracks != NULL && !common->unset_backref)
7833   add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
7834
7835 set_jumps(found, LABEL());
7836 }
7837
7838 static void compile_ref_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
7839 {
7840 DEFINE_COMPILER;
7841 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
7842 int offset = 0;
7843 struct sljit_jump *jump = NULL;
7844 struct sljit_jump *partial;
7845 struct sljit_jump *nopartial;
7846
7847 if (ref)
7848   {
7849   offset = GET2(cc, 1) << 1;
7850   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
7851   /* OVECTOR(1) contains the "string begin - 1" constant. */
7852   if (withchecks && !common->unset_backref)
7853     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
7854   }
7855 else
7856   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
7857
7858 #if defined SUPPORT_UNICODE
7859 if (common->utf && *cc == OP_REFI)
7860   {
7861   SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
7862   if (ref)
7863     OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
7864   else
7865     OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
7866
7867   if (withchecks)
7868     jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
7869   /* No free saved registers so save data on stack. */
7870
7871   OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
7872   sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
7873   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
7874
7875   if (common->mode == PCRE2_JIT_COMPLETE)
7876     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
7877   else
7878     {
7879     OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
7880
7881     add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
7882
7883     nopartial = JUMP(SLJIT_NOT_EQUAL);
7884     OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
7885     check_partial(common, FALSE);
7886     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
7887     JUMPHERE(nopartial);
7888     }
7889   }
7890 else
7891 #endif /* SUPPORT_UNICODE */
7892   {
7893   if (ref)
7894     OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
7895   else
7896     OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
7897
7898   if (withchecks)
7899     jump = JUMP(SLJIT_ZERO);
7900
7901   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
7902   partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
7903   if (common->mode == PCRE2_JIT_COMPLETE)
7904     add_jump(compiler, backtracks, partial);
7905
7906   add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
7907   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
7908
7909   if (common->mode != PCRE2_JIT_COMPLETE)
7910     {
7911     nopartial = JUMP(SLJIT_JUMP);
7912     JUMPHERE(partial);
7913     /* TMP2 -= STR_END - STR_PTR */
7914     OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
7915     OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
7916     partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);
7917     OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
7918     add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
7919     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
7920     JUMPHERE(partial);
7921     check_partial(common, FALSE);
7922     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
7923     JUMPHERE(nopartial);
7924     }
7925   }
7926
7927 if (jump != NULL)
7928   {
7929   if (emptyfail)
7930     add_jump(compiler, backtracks, jump);
7931   else
7932     JUMPHERE(jump);
7933   }
7934 }
7935
7936 static SLJIT_INLINE PCRE2_SPTR compile_ref_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
7937 {
7938 DEFINE_COMPILER;
7939 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
7940 backtrack_common *backtrack;
7941 PCRE2_UCHAR type;
7942 int offset = 0;
7943 struct sljit_label *label;
7944 struct sljit_jump *zerolength;
7945 struct sljit_jump *jump = NULL;
7946 PCRE2_SPTR ccbegin = cc;
7947 int min = 0, max = 0;
7948 BOOL minimize;
7949
7950 PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL);
7951
7952 if (ref)
7953   offset = GET2(cc, 1) << 1;
7954 else
7955   cc += IMM2_SIZE;
7956 type = cc[1 + IMM2_SIZE];
7957
7958 SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
7959 minimize = (type & 0x1) != 0;
7960 switch(type)
7961   {
7962   case OP_CRSTAR:
7963   case OP_CRMINSTAR:
7964   min = 0;
7965   max = 0;
7966   cc += 1 + IMM2_SIZE + 1;
7967   break;
7968   case OP_CRPLUS:
7969   case OP_CRMINPLUS:
7970   min = 1;
7971   max = 0;
7972   cc += 1 + IMM2_SIZE + 1;
7973   break;
7974   case OP_CRQUERY:
7975   case OP_CRMINQUERY:
7976   min = 0;
7977   max = 1;
7978   cc += 1 + IMM2_SIZE + 1;
7979   break;
7980   case OP_CRRANGE:
7981   case OP_CRMINRANGE:
7982   min = GET2(cc, 1 + IMM2_SIZE + 1);
7983   max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
7984   cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
7985   break;
7986   default:
7987   SLJIT_UNREACHABLE();
7988   break;
7989   }
7990
7991 if (!minimize)
7992   {
7993   if (min == 0)
7994     {
7995     allocate_stack(common, 2);
7996     if (ref)
7997       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
7998     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7999     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
8000     /* Temporary release of STR_PTR. */
8001     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
8002     /* Handles both invalid and empty cases. Since the minimum repeat,
8003     is zero the invalid case is basically the same as an empty case. */
8004     if (ref)
8005       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
8006     else
8007       {
8008       compile_dnref_search(common, ccbegin, NULL);
8009       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
8010       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
8011       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
8012       }
8013     /* Restore if not zero length. */
8014     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
8015     }
8016   else
8017     {
8018     allocate_stack(common, 1);
8019     if (ref)
8020       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
8021     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8022     if (ref)
8023       {
8024       add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
8025       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
8026       }
8027     else
8028       {
8029       compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
8030       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
8031       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
8032       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
8033       }
8034     }
8035
8036   if (min > 1 || max > 1)
8037     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
8038
8039   label = LABEL();
8040   if (!ref)
8041     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
8042   compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
8043
8044   if (min > 1 || max > 1)
8045     {
8046     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
8047     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
8048     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
8049     if (min > 1)
8050       CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);
8051     if (max > 1)
8052       {
8053       jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
8054       allocate_stack(common, 1);
8055       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8056       JUMPTO(SLJIT_JUMP, label);
8057       JUMPHERE(jump);
8058       }
8059     }
8060
8061   if (max == 0)
8062     {
8063     /* Includes min > 1 case as well. */
8064     allocate_stack(common, 1);
8065     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8066     JUMPTO(SLJIT_JUMP, label);
8067     }
8068
8069   JUMPHERE(zerolength);
8070   BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
8071
8072   count_match(common);
8073   return cc;
8074   }
8075
8076 allocate_stack(common, ref ? 2 : 3);
8077 if (ref)
8078   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
8079 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8080 if (type != OP_CRMINSTAR)
8081   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
8082
8083 if (min == 0)
8084   {
8085   /* Handles both invalid and empty cases. Since the minimum repeat,
8086   is zero the invalid case is basically the same as an empty case. */
8087   if (ref)
8088     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
8089   else
8090     {
8091     compile_dnref_search(common, ccbegin, NULL);
8092     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
8093     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
8094     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
8095     }
8096   /* Length is non-zero, we can match real repeats. */
8097   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8098   jump = JUMP(SLJIT_JUMP);
8099   }
8100 else
8101   {
8102   if (ref)
8103     {
8104     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
8105     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
8106     }
8107   else
8108     {
8109     compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
8110     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
8111     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
8112     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
8113     }
8114   }
8115
8116 BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
8117 if (max > 0)
8118   add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
8119
8120 if (!ref)
8121   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
8122 compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
8123 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8124
8125 if (min > 1)
8126   {
8127   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8128   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
8129   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
8130   CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath);
8131   }
8132 else if (max > 0)
8133   OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
8134
8135 if (jump != NULL)
8136   JUMPHERE(jump);
8137 JUMPHERE(zerolength);
8138
8139 count_match(common);
8140 return cc;
8141 }
8142
8143 static SLJIT_INLINE PCRE2_SPTR compile_recurse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
8144 {
8145 DEFINE_COMPILER;
8146 backtrack_common *backtrack;
8147 recurse_entry *entry = common->entries;
8148 recurse_entry *prev = NULL;
8149 sljit_sw start = GET(cc, 1);
8150 PCRE2_SPTR start_cc;
8151 BOOL needs_control_head;
8152
8153 PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
8154
8155 /* Inlining simple patterns. */
8156 if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
8157   {
8158   start_cc = common->start + start;
8159   compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
8160   BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
8161   return cc + 1 + LINK_SIZE;
8162   }
8163
8164 while (entry != NULL)
8165   {
8166   if (entry->start == start)
8167     break;
8168   prev = entry;
8169   entry = entry->next;
8170   }
8171
8172 if (entry == NULL)
8173   {
8174   entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
8175   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8176     return NULL;
8177   entry->next = NULL;
8178   entry->entry_label = NULL;
8179   entry->backtrack_label = NULL;
8180   entry->entry_calls = NULL;
8181   entry->backtrack_calls = NULL;
8182   entry->start = start;
8183
8184   if (prev != NULL)
8185     prev->next = entry;
8186   else
8187     common->entries = entry;
8188   }
8189
8190 BACKTRACK_AS(recurse_backtrack)->entry = entry;
8191
8192 if (entry->entry_label == NULL)
8193   add_jump(compiler, &entry->entry_calls, JUMP(SLJIT_FAST_CALL));
8194 else
8195   JUMPTO(SLJIT_FAST_CALL, entry->entry_label);
8196 /* Leave if the match is failed. */
8197 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
8198 BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();
8199 return cc + 1 + LINK_SIZE;
8200 }
8201
8202 static sljit_s32 SLJIT_FUNC do_callout(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
8203 {
8204 PCRE2_SPTR begin;
8205 PCRE2_SIZE *ovector;
8206 sljit_u32 oveccount, capture_top;
8207
8208 if (arguments->callout == NULL)
8209   return 0;
8210
8211 SLJIT_COMPILE_ASSERT(sizeof (PCRE2_SIZE) <= sizeof (sljit_sw), pcre2_size_must_be_lower_than_sljit_sw_size);
8212
8213 begin = arguments->begin;
8214 ovector = (PCRE2_SIZE*)(callout_block + 1);
8215 oveccount = callout_block->capture_top;
8216
8217 SLJIT_ASSERT(oveccount >= 1);
8218
8219 callout_block->version = 2;
8220 callout_block->callout_flags = 0;
8221
8222 /* Offsets in subject. */
8223 callout_block->subject_length = arguments->end - arguments->begin;
8224 callout_block->start_match = jit_ovector[0] - begin;
8225 callout_block->current_position = (PCRE2_SPTR)callout_block->offset_vector - begin;
8226 callout_block->subject = begin;
8227
8228 /* Convert and copy the JIT offset vector to the ovector array. */
8229 callout_block->capture_top = 1;
8230 callout_block->offset_vector = ovector;
8231
8232 ovector[0] = PCRE2_UNSET;
8233 ovector[1] = PCRE2_UNSET;
8234 ovector += 2;
8235 jit_ovector += 2;
8236 capture_top = 1;
8237
8238 /* Convert pointers to sizes. */
8239 while (--oveccount != 0)
8240   {
8241   capture_top++;
8242
8243   ovector[0] = (PCRE2_SIZE)(jit_ovector[0] - begin);
8244   ovector[1] = (PCRE2_SIZE)(jit_ovector[1] - begin);
8245
8246   if (ovector[0] != PCRE2_UNSET)
8247     callout_block->capture_top = capture_top;
8248
8249   ovector += 2;
8250   jit_ovector += 2;
8251   }
8252
8253 return (arguments->callout)(callout_block, arguments->callout_data);
8254 }
8255
8256 #define CALLOUT_ARG_OFFSET(arg) \
8257     SLJIT_OFFSETOF(pcre2_callout_block, arg)
8258
8259 static SLJIT_INLINE PCRE2_SPTR compile_callout_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
8260 {
8261 DEFINE_COMPILER;
8262 backtrack_common *backtrack;
8263 sljit_s32 mov_opcode;
8264 unsigned int callout_length = (*cc == OP_CALLOUT)
8265     ? PRIV(OP_lengths)[OP_CALLOUT] : GET(cc, 1 + 2 * LINK_SIZE);
8266 sljit_sw value1;
8267 sljit_sw value2;
8268 sljit_sw value3;
8269 sljit_uw callout_arg_size = (common->re->top_bracket + 1) * 2 * sizeof(sljit_sw);
8270
8271 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
8272
8273 callout_arg_size = (sizeof(pcre2_callout_block) + callout_arg_size + sizeof(sljit_sw) - 1) / sizeof(sljit_sw);
8274
8275 allocate_stack(common, callout_arg_size);
8276
8277 SLJIT_ASSERT(common->capture_last_ptr != 0);
8278 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
8279 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
8280 value1 = (*cc == OP_CALLOUT) ? cc[1 + 2 * LINK_SIZE] : 0;
8281 OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, value1);
8282 OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
8283 OP1(SLJIT_MOV_U32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_top), SLJIT_IMM, common->re->top_bracket + 1);
8284
8285 /* These pointer sized fields temporarly stores internal variables. */
8286 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
8287
8288 if (common->mark_ptr != 0)
8289   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
8290 mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
8291 OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 1));
8292 OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 1 + LINK_SIZE));
8293
8294 if (*cc == OP_CALLOUT)
8295   {
8296   value1 = 0;
8297   value2 = 0;
8298   value3 = 0;
8299   }
8300 else
8301   {
8302   value1 = (sljit_sw) (cc + (1 + 4*LINK_SIZE) + 1);
8303   value2 = (callout_length - (1 + 4*LINK_SIZE + 2));
8304   value3 = (sljit_sw) (GET(cc, 1 + 3*LINK_SIZE));
8305   }
8306
8307 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string), SLJIT_IMM, value1);
8308 OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length), SLJIT_IMM, value2);
8309 OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);
8310 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
8311
8312 SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
8313
8314 /* Needed to save important temporary registers. */
8315 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
8316 /* SLJIT_R0 = arguments */
8317 OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
8318 GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
8319 sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
8320 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
8321 free_stack(common, callout_arg_size);
8322
8323 /* Check return value. */
8324 OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
8325 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
8326 if (common->abort_label == NULL)
8327   add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
8328 else
8329   JUMPTO(SLJIT_NOT_EQUAL32 /* SIG_LESS */, common->abort_label);
8330 return cc + callout_length;
8331 }
8332
8333 #undef CALLOUT_ARG_SIZE
8334 #undef CALLOUT_ARG_OFFSET
8335
8336 static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc)
8337 {
8338 while (TRUE)
8339   {
8340   switch (*cc)
8341     {
8342     case OP_CALLOUT_STR:
8343     cc += GET(cc, 1 + 2*LINK_SIZE);
8344     break;
8345
8346     case OP_NOT_WORD_BOUNDARY:
8347     case OP_WORD_BOUNDARY:
8348     case OP_CIRC:
8349     case OP_CIRCM:
8350     case OP_DOLL:
8351     case OP_DOLLM:
8352     case OP_CALLOUT:
8353     case OP_ALT:
8354     cc += PRIV(OP_lengths)[*cc];
8355     break;
8356
8357     case OP_KET:
8358     return FALSE;
8359
8360     default:
8361     return TRUE;
8362     }
8363   }
8364 }
8365
8366 static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common, PCRE2_SPTR cc, assert_backtrack *backtrack, BOOL conditional)
8367 {
8368 DEFINE_COMPILER;
8369 int framesize;
8370 int extrasize;
8371 BOOL local_quit_available = FALSE;
8372 BOOL needs_control_head;
8373 int private_data_ptr;
8374 backtrack_common altbacktrack;
8375 PCRE2_SPTR ccbegin;
8376 PCRE2_UCHAR opcode;
8377 PCRE2_UCHAR bra = OP_BRA;
8378 jump_list *tmp = NULL;
8379 jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
8380 jump_list **found;
8381 /* Saving previous accept variables. */
8382 BOOL save_local_quit_available = common->local_quit_available;
8383 BOOL save_in_positive_assertion = common->in_positive_assertion;
8384 then_trap_backtrack *save_then_trap = common->then_trap;
8385 struct sljit_label *save_quit_label = common->quit_label;
8386 struct sljit_label *save_accept_label = common->accept_label;
8387 jump_list *save_quit = common->quit;
8388 jump_list *save_positive_assertion_quit = common->positive_assertion_quit;
8389 jump_list *save_accept = common->accept;
8390 struct sljit_jump *jump;
8391 struct sljit_jump *brajump = NULL;
8392
8393 /* Assert captures then. */
8394 common->then_trap = NULL;
8395
8396 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
8397   {
8398   SLJIT_ASSERT(!conditional);
8399   bra = *cc;
8400   cc++;
8401   }
8402 private_data_ptr = PRIVATE_DATA(cc);
8403 SLJIT_ASSERT(private_data_ptr != 0);
8404 framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
8405 backtrack->framesize = framesize;
8406 backtrack->private_data_ptr = private_data_ptr;
8407 opcode = *cc;
8408 SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
8409 found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
8410 ccbegin = cc;
8411 cc += GET(cc, 1);
8412
8413 if (bra == OP_BRAMINZERO)
8414   {
8415   /* This is a braminzero backtrack path. */
8416   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8417   free_stack(common, 1);
8418   brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
8419   }
8420
8421 if (framesize < 0)
8422   {
8423   extrasize = 1;
8424   if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))
8425     extrasize = 0;
8426
8427   if (needs_control_head)
8428     extrasize++;
8429
8430   if (framesize == no_frame)
8431     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
8432
8433   if (extrasize > 0)
8434     allocate_stack(common, extrasize);
8435
8436   if (needs_control_head)
8437     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
8438
8439   if (extrasize > 0)
8440     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8441
8442   if (needs_control_head)
8443     {
8444     SLJIT_ASSERT(extrasize == 2);
8445     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
8446     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
8447     }
8448   }
8449 else
8450   {
8451   extrasize = needs_control_head ? 3 : 2;
8452   allocate_stack(common, framesize + extrasize);
8453
8454   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8455   OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
8456   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
8457   if (needs_control_head)
8458     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
8459   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8460
8461   if (needs_control_head)
8462     {
8463     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
8464     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
8465     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
8466     }
8467   else
8468     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
8469
8470   init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize);
8471   }
8472
8473 memset(&altbacktrack, 0, sizeof(backtrack_common));
8474 if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT))
8475   {
8476   /* Control verbs cannot escape from these asserts. */
8477   local_quit_available = TRUE;
8478   common->local_quit_available = TRUE;
8479   common->quit_label = NULL;
8480   common->quit = NULL;
8481   }
8482
8483 common->in_positive_assertion = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK);
8484 common->positive_assertion_quit = NULL;
8485
8486 while (1)
8487   {
8488   common->accept_label = NULL;
8489   common->accept = NULL;
8490   altbacktrack.top = NULL;
8491   altbacktrack.topbacktracks = NULL;
8492
8493   if (*ccbegin == OP_ALT && extrasize > 0)
8494     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8495
8496   altbacktrack.cc = ccbegin;
8497   compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
8498   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8499     {
8500     if (local_quit_available)
8501       {
8502       common->local_quit_available = save_local_quit_available;
8503       common->quit_label = save_quit_label;
8504       common->quit = save_quit;
8505       }
8506     common->in_positive_assertion = save_in_positive_assertion;
8507     common->then_trap = save_then_trap;
8508     common->accept_label = save_accept_label;
8509     common->positive_assertion_quit = save_positive_assertion_quit;
8510     common->accept = save_accept;
8511     return NULL;
8512     }
8513   common->accept_label = LABEL();
8514   if (common->accept != NULL)
8515     set_jumps(common->accept, common->accept_label);
8516
8517   /* Reset stack. */
8518   if (framesize < 0)
8519     {
8520     if (framesize == no_frame)
8521       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8522     else if (extrasize > 0)
8523       free_stack(common, extrasize);
8524
8525     if (needs_control_head)
8526       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
8527     }
8528   else
8529     {
8530     if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
8531       {
8532       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
8533       OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
8534       if (needs_control_head)
8535         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
8536       }
8537     else
8538       {
8539       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8540       if (needs_control_head)
8541         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 2));
8542       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8543       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));
8544       }
8545     }
8546
8547   if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
8548     {
8549     /* We know that STR_PTR was stored on the top of the stack. */
8550     if (conditional)
8551       {
8552       if (extrasize > 0)
8553         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? STACK(-2) : STACK(-1));
8554       }
8555     else if (bra == OP_BRAZERO)
8556       {
8557       if (framesize < 0)
8558         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));
8559       else
8560         {
8561         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));
8562         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize));
8563         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
8564         }
8565       OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
8566       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8567       }
8568     else if (framesize >= 0)
8569       {
8570       /* For OP_BRA and OP_BRAMINZERO. */
8571       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 1));
8572       }
8573     }
8574   add_jump(compiler, found, JUMP(SLJIT_JUMP));
8575
8576   compile_backtrackingpath(common, altbacktrack.top);
8577   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8578     {
8579     if (local_quit_available)
8580       {
8581       common->local_quit_available = save_local_quit_available;
8582       common->quit_label = save_quit_label;
8583       common->quit = save_quit;
8584       }
8585     common->in_positive_assertion = save_in_positive_assertion;
8586     common->then_trap = save_then_trap;
8587     common->accept_label = save_accept_label;
8588     common->positive_assertion_quit = save_positive_assertion_quit;
8589     common->accept = save_accept;
8590     return NULL;
8591     }
8592   set_jumps(altbacktrack.topbacktracks, LABEL());
8593
8594   if (*cc != OP_ALT)
8595     break;
8596
8597   ccbegin = cc;
8598   cc += GET(cc, 1);
8599   }
8600
8601 if (local_quit_available)
8602   {
8603   SLJIT_ASSERT(common->positive_assertion_quit == NULL);
8604   /* Makes the check less complicated below. */
8605   common->positive_assertion_quit = common->quit;
8606   }
8607
8608 /* None of them matched. */
8609 if (common->positive_assertion_quit != NULL)
8610   {
8611   jump = JUMP(SLJIT_JUMP);
8612   set_jumps(common->positive_assertion_quit, LABEL());
8613   SLJIT_ASSERT(framesize != no_stack);
8614   if (framesize < 0)
8615     OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
8616   else
8617     {
8618     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8619     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8620     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (extrasize + 1) * sizeof(sljit_sw));
8621     }
8622   JUMPHERE(jump);
8623   }
8624
8625 if (needs_control_head)
8626   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
8627
8628 if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
8629   {
8630   /* Assert is failed. */
8631   if ((conditional && extrasize > 0) || bra == OP_BRAZERO)
8632     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8633
8634   if (framesize < 0)
8635     {
8636     /* The topmost item should be 0. */
8637     if (bra == OP_BRAZERO)
8638       {
8639       if (extrasize == 2)
8640         free_stack(common, 1);
8641       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8642       }
8643     else if (extrasize > 0)
8644       free_stack(common, extrasize);
8645     }
8646   else
8647     {
8648     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
8649     /* The topmost item should be 0. */
8650     if (bra == OP_BRAZERO)
8651       {
8652       free_stack(common, framesize + extrasize - 1);
8653       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8654       }
8655     else
8656       free_stack(common, framesize + extrasize);
8657     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
8658     }
8659   jump = JUMP(SLJIT_JUMP);
8660   if (bra != OP_BRAZERO)
8661     add_jump(compiler, target, jump);
8662
8663   /* Assert is successful. */
8664   set_jumps(tmp, LABEL());
8665   if (framesize < 0)
8666     {
8667     /* We know that STR_PTR was stored on the top of the stack. */
8668     if (extrasize > 0)
8669       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize));
8670
8671     /* Keep the STR_PTR on the top of the stack. */
8672     if (bra == OP_BRAZERO)
8673       {
8674       OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
8675       if (extrasize == 2)
8676         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8677       }
8678     else if (bra == OP_BRAMINZERO)
8679       {
8680       OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
8681       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8682       }
8683     }
8684   else
8685     {
8686     if (bra == OP_BRA)
8687       {
8688       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
8689       OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
8690       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1));
8691       }
8692     else
8693       {
8694       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
8695       OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
8696       if (extrasize == 2)
8697         {
8698         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8699         if (bra == OP_BRAMINZERO)
8700           OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8701         }
8702       else
8703         {
8704         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
8705         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
8706         }
8707       }
8708     }
8709
8710   if (bra == OP_BRAZERO)
8711     {
8712     backtrack->matchingpath = LABEL();
8713     SET_LABEL(jump, backtrack->matchingpath);
8714     }
8715   else if (bra == OP_BRAMINZERO)
8716     {
8717     JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
8718     JUMPHERE(brajump);
8719     if (framesize >= 0)
8720       {
8721       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8722       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8723       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
8724       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw));
8725       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
8726       }
8727     set_jumps(backtrack->common.topbacktracks, LABEL());
8728     }
8729   }
8730 else
8731   {
8732   /* AssertNot is successful. */
8733   if (framesize < 0)
8734     {
8735     if (extrasize > 0)
8736       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8737
8738     if (bra != OP_BRA)
8739       {
8740       if (extrasize == 2)
8741         free_stack(common, 1);
8742       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8743       }
8744     else if (extrasize > 0)
8745       free_stack(common, extrasize);
8746     }
8747   else
8748     {
8749     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8750     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
8751     /* The topmost item should be 0. */
8752     if (bra != OP_BRA)
8753       {
8754       free_stack(common, framesize + extrasize - 1);
8755       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8756       }
8757     else
8758       free_stack(common, framesize + extrasize);
8759     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
8760     }
8761
8762   if (bra == OP_BRAZERO)
8763     backtrack->matchingpath = LABEL();
8764   else if (bra == OP_BRAMINZERO)
8765     {
8766     JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
8767     JUMPHERE(brajump);
8768     }
8769
8770   if (bra != OP_BRA)
8771     {
8772     SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
8773     set_jumps(backtrack->common.topbacktracks, LABEL());
8774     backtrack->common.topbacktracks = NULL;
8775     }
8776   }
8777
8778 if (local_quit_available)
8779   {
8780   common->local_quit_available = save_local_quit_available;
8781   common->quit_label = save_quit_label;
8782   common->quit = save_quit;
8783   }
8784 common->in_positive_assertion = save_in_positive_assertion;
8785 common->then_trap = save_then_trap;
8786 common->accept_label = save_accept_label;
8787 common->positive_assertion_quit = save_positive_assertion_quit;
8788 common->accept = save_accept;
8789 return cc + 1 + LINK_SIZE;
8790 }
8791
8792 static SLJIT_INLINE void match_once_common(compiler_common *common, PCRE2_UCHAR ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
8793 {
8794 DEFINE_COMPILER;
8795 int stacksize;
8796
8797 if (framesize < 0)
8798   {
8799   if (framesize == no_frame)
8800     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8801   else
8802     {
8803     stacksize = needs_control_head ? 1 : 0;
8804     if (ket != OP_KET || has_alternatives)
8805       stacksize++;
8806
8807     if (stacksize > 0)
8808       free_stack(common, stacksize);
8809     }
8810
8811   if (needs_control_head)
8812     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? STACK(-2) : STACK(-1));
8813
8814   /* TMP2 which is set here used by OP_KETRMAX below. */
8815   if (ket == OP_KETRMAX)
8816     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
8817   else if (ket == OP_KETRMIN)
8818     {
8819     /* Move the STR_PTR to the private_data_ptr. */
8820     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1));
8821     }
8822   }
8823 else
8824   {
8825   stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
8826   OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
8827   if (needs_control_head)
8828     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-1));
8829
8830   if (ket == OP_KETRMAX)
8831     {
8832     /* TMP2 which is set here used by OP_KETRMAX below. */
8833     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8834     }
8835   }
8836 if (needs_control_head)
8837   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
8838 }
8839
8840 static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
8841 {
8842 DEFINE_COMPILER;
8843
8844 if (common->capture_last_ptr != 0)
8845   {
8846   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
8847   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
8848   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
8849   stacksize++;
8850   }
8851 if (common->optimized_cbracket[offset >> 1] == 0)
8852   {
8853   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
8854   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
8855   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
8856   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8857   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
8858   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
8859   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
8860   stacksize += 2;
8861   }
8862 return stacksize;
8863 }
8864
8865 /*
8866   Handling bracketed expressions is probably the most complex part.
8867
8868   Stack layout naming characters:
8869     S - Push the current STR_PTR
8870     0 - Push a 0 (NULL)
8871     A - Push the current STR_PTR. Needed for restoring the STR_PTR
8872         before the next alternative. Not pushed if there are no alternatives.
8873     M - Any values pushed by the current alternative. Can be empty, or anything.
8874     C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
8875     L - Push the previous local (pointed by localptr) to the stack
8876    () - opional values stored on the stack
8877   ()* - optonal, can be stored multiple times
8878
8879   The following list shows the regular expression templates, their PCRE byte codes
8880   and stack layout supported by pcre-sljit.
8881
8882   (?:)                     OP_BRA     | OP_KET                A M
8883   ()                       OP_CBRA    | OP_KET                C M
8884   (?:)+                    OP_BRA     | OP_KETRMAX        0   A M S   ( A M S )*
8885                            OP_SBRA    | OP_KETRMAX        0   L M S   ( L M S )*
8886   (?:)+?                   OP_BRA     | OP_KETRMIN        0   A M S   ( A M S )*
8887                            OP_SBRA    | OP_KETRMIN        0   L M S   ( L M S )*
8888   ()+                      OP_CBRA    | OP_KETRMAX        0   C M S   ( C M S )*
8889                            OP_SCBRA   | OP_KETRMAX        0   C M S   ( C M S )*
8890   ()+?                     OP_CBRA    | OP_KETRMIN        0   C M S   ( C M S )*
8891                            OP_SCBRA   | OP_KETRMIN        0   C M S   ( C M S )*
8892   (?:)?    OP_BRAZERO    | OP_BRA     | OP_KET            S ( A M 0 )
8893   (?:)??   OP_BRAMINZERO | OP_BRA     | OP_KET            S ( A M 0 )
8894   ()?      OP_BRAZERO    | OP_CBRA    | OP_KET            S ( C M 0 )
8895   ()??     OP_BRAMINZERO | OP_CBRA    | OP_KET            S ( C M 0 )
8896   (?:)*    OP_BRAZERO    | OP_BRA     | OP_KETRMAX      S 0 ( A M S )*
8897            OP_BRAZERO    | OP_SBRA    | OP_KETRMAX      S 0 ( L M S )*
8898   (?:)*?   OP_BRAMINZERO | OP_BRA     | OP_KETRMIN      S 0 ( A M S )*
8899            OP_BRAMINZERO | OP_SBRA    | OP_KETRMIN      S 0 ( L M S )*
8900   ()*      OP_BRAZERO    | OP_CBRA    | OP_KETRMAX      S 0 ( C M S )*
8901            OP_BRAZERO    | OP_SCBRA   | OP_KETRMAX      S 0 ( C M S )*
8902   ()*?     OP_BRAMINZERO | OP_CBRA    | OP_KETRMIN      S 0 ( C M S )*
8903            OP_BRAMINZERO | OP_SCBRA   | OP_KETRMIN      S 0 ( C M S )*
8904
8905
8906   Stack layout naming characters:
8907     A - Push the alternative index (starting from 0) on the stack.
8908         Not pushed if there is no alternatives.
8909     M - Any values pushed by the current alternative. Can be empty, or anything.
8910
8911   The next list shows the possible content of a bracket:
8912   (|)     OP_*BRA    | OP_ALT ...         M A
8913   (?()|)  OP_*COND   | OP_ALT             M A
8914   (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
8915                                           Or nothing, if trace is unnecessary
8916 */
8917
8918 static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
8919 {
8920 DEFINE_COMPILER;
8921 backtrack_common *backtrack;
8922 PCRE2_UCHAR opcode;
8923 int private_data_ptr = 0;
8924 int offset = 0;
8925 int i, stacksize;
8926 int repeat_ptr = 0, repeat_length = 0;
8927 int repeat_type = 0, repeat_count = 0;
8928 PCRE2_SPTR ccbegin;
8929 PCRE2_SPTR matchingpath;
8930 PCRE2_SPTR slot;
8931 PCRE2_UCHAR bra = OP_BRA;
8932 PCRE2_UCHAR ket;
8933 assert_backtrack *assert;
8934 BOOL has_alternatives;
8935 BOOL needs_control_head = FALSE;
8936 struct sljit_jump *jump;
8937 struct sljit_jump *skip;
8938 struct sljit_label *rmax_label = NULL;
8939 struct sljit_jump *braminzero = NULL;
8940
8941 PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
8942
8943 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
8944   {
8945   bra = *cc;
8946   cc++;
8947   opcode = *cc;
8948   }
8949
8950 opcode = *cc;
8951 ccbegin = cc;
8952 matchingpath = bracketend(cc) - 1 - LINK_SIZE;
8953 ket = *matchingpath;
8954 if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
8955   {
8956   repeat_ptr = PRIVATE_DATA(matchingpath);
8957   repeat_length = PRIVATE_DATA(matchingpath + 1);
8958   repeat_type = PRIVATE_DATA(matchingpath + 2);
8959   repeat_count = PRIVATE_DATA(matchingpath + 3);
8960   SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
8961   if (repeat_type == OP_UPTO)
8962     ket = OP_KETRMAX;
8963   if (repeat_type == OP_MINUPTO)
8964     ket = OP_KETRMIN;
8965   }
8966
8967 matchingpath = ccbegin + 1 + LINK_SIZE;
8968 SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
8969 SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
8970 cc += GET(cc, 1);
8971
8972 has_alternatives = *cc == OP_ALT;
8973 if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
8974   {
8975   SLJIT_COMPILE_ASSERT(OP_DNRREF == OP_RREF + 1 && OP_FALSE == OP_RREF + 2 && OP_TRUE == OP_RREF + 3,
8976     compile_time_checks_must_be_grouped_together);
8977   has_alternatives = ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL) ? FALSE : TRUE;
8978   }
8979
8980 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
8981   opcode = OP_SCOND;
8982
8983 if (opcode == OP_CBRA || opcode == OP_SCBRA)
8984   {
8985   /* Capturing brackets has a pre-allocated space. */
8986   offset = GET2(ccbegin, 1 + LINK_SIZE);
8987   if (common->optimized_cbracket[offset] == 0)
8988     {
8989     private_data_ptr = OVECTOR_PRIV(offset);
8990     offset <<= 1;
8991     }
8992   else
8993     {
8994     offset <<= 1;
8995     private_data_ptr = OVECTOR(offset);
8996     }
8997   BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
8998   matchingpath += IMM2_SIZE;
8999   }
9000 else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
9001   {
9002   /* Other brackets simply allocate the next entry. */
9003   private_data_ptr = PRIVATE_DATA(ccbegin);
9004   SLJIT_ASSERT(private_data_ptr != 0);
9005   BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
9006   if (opcode == OP_ONCE)
9007     BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
9008   }
9009
9010 /* Instructions before the first alternative. */
9011 stacksize = 0;
9012 if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
9013   stacksize++;
9014 if (bra == OP_BRAZERO)
9015   stacksize++;
9016
9017 if (stacksize > 0)
9018   allocate_stack(common, stacksize);
9019
9020 stacksize = 0;
9021 if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
9022   {
9023   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
9024   stacksize++;
9025   }
9026
9027 if (bra == OP_BRAZERO)
9028   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
9029
9030 if (bra == OP_BRAMINZERO)
9031   {
9032   /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
9033   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9034   if (ket != OP_KETRMIN)
9035     {
9036     free_stack(common, 1);
9037     braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
9038     }
9039   else
9040     {
9041     if (opcode == OP_ONCE || opcode >= OP_SBRA)
9042       {
9043       jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
9044       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
9045       /* Nothing stored during the first run. */
9046       skip = JUMP(SLJIT_JUMP);
9047       JUMPHERE(jump);
9048       /* Checking zero-length iteration. */
9049       if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
9050         {
9051         /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
9052         braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9053         }
9054       else
9055         {
9056         /* Except when the whole stack frame must be saved. */
9057         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9058         braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2));
9059         }
9060       JUMPHERE(skip);
9061       }
9062     else
9063       {
9064       jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
9065       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
9066       JUMPHERE(jump);
9067       }
9068     }
9069   }
9070
9071 if (repeat_type != 0)
9072   {
9073   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);
9074   if (repeat_type == OP_EXACT)
9075     rmax_label = LABEL();
9076   }
9077
9078 if (ket == OP_KETRMIN)
9079   BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
9080
9081 if (ket == OP_KETRMAX)
9082   {
9083   rmax_label = LABEL();
9084   if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
9085     BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
9086   }
9087
9088 /* Handling capturing brackets and alternatives. */
9089 if (opcode == OP_ONCE)
9090   {
9091   stacksize = 0;
9092   if (needs_control_head)
9093     {
9094     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
9095     stacksize++;
9096     }
9097
9098   if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
9099     {
9100     /* Neither capturing brackets nor recursions are found in the block. */
9101     if (ket == OP_KETRMIN)
9102       {
9103       stacksize += 2;
9104       if (!needs_control_head)
9105         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9106       }
9107     else
9108       {
9109       if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
9110         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
9111       if (ket == OP_KETRMAX || has_alternatives)
9112         stacksize++;
9113       }
9114
9115     if (stacksize > 0)
9116       allocate_stack(common, stacksize);
9117
9118     stacksize = 0;
9119     if (needs_control_head)
9120       {
9121       stacksize++;
9122       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
9123       }
9124
9125     if (ket == OP_KETRMIN)
9126       {
9127       if (needs_control_head)
9128         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9129       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
9130       if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
9131         OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
9132       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
9133       }
9134     else if (ket == OP_KETRMAX || has_alternatives)
9135       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
9136     }
9137   else
9138     {
9139     if (ket != OP_KET || has_alternatives)
9140       stacksize++;
9141
9142     stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
9143     allocate_stack(common, stacksize);
9144
9145     if (needs_control_head)
9146       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
9147
9148     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9149     OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
9150
9151     stacksize = needs_control_head ? 1 : 0;
9152     if (ket != OP_KET || has_alternatives)
9153       {
9154       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
9155       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
9156       stacksize++;
9157       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
9158       }
9159     else
9160       {
9161       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
9162       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
9163       }
9164     init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1);
9165     }
9166   }
9167 else if (opcode == OP_CBRA || opcode == OP_SCBRA)
9168   {
9169   /* Saving the previous values. */
9170   if (common->optimized_cbracket[offset >> 1] != 0)
9171     {
9172     SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
9173     allocate_stack(common, 2);
9174     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9175     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));
9176     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
9177     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
9178     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
9179     }
9180   else
9181     {
9182     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9183     allocate_stack(common, 1);
9184     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
9185     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
9186     }
9187   }
9188 else if (opcode == OP_SBRA || opcode == OP_SCOND)
9189   {
9190   /* Saving the previous value. */
9191   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9192   allocate_stack(common, 1);
9193   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
9194   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
9195   }
9196 else if (has_alternatives)
9197   {
9198   /* Pushing the starting string pointer. */
9199   allocate_stack(common, 1);
9200   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
9201   }
9202
9203 /* Generating code for the first alternative. */
9204 if (opcode == OP_COND || opcode == OP_SCOND)
9205   {
9206   if (*matchingpath == OP_CREF)
9207     {
9208     SLJIT_ASSERT(has_alternatives);
9209     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
9210       CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
9211     matchingpath += 1 + IMM2_SIZE;
9212     }
9213   else if (*matchingpath == OP_DNCREF)
9214     {
9215     SLJIT_ASSERT(has_alternatives);
9216
9217     i = GET2(matchingpath, 1 + IMM2_SIZE);
9218     slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
9219     OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
9220     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
9221     OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
9222     slot += common->name_entry_size;
9223     i--;
9224     while (i-- > 0)
9225       {
9226       OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
9227       OP2(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, TMP2, 0, STR_PTR, 0);
9228       slot += common->name_entry_size;
9229       }
9230     OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
9231     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));
9232     matchingpath += 1 + 2 * IMM2_SIZE;
9233     }
9234   else if ((*matchingpath >= OP_RREF && *matchingpath <= OP_TRUE) || *matchingpath == OP_FAIL)
9235     {
9236     /* Never has other case. */
9237     BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
9238     SLJIT_ASSERT(!has_alternatives);
9239
9240     if (*matchingpath == OP_TRUE)
9241       {
9242       stacksize = 1;
9243       matchingpath++;
9244       }
9245     else if (*matchingpath == OP_FALSE || *matchingpath == OP_FAIL)
9246       stacksize = 0;
9247     else if (*matchingpath == OP_RREF)
9248       {
9249       stacksize = GET2(matchingpath, 1);
9250       if (common->currententry == NULL)
9251         stacksize = 0;
9252       else if (stacksize == RREF_ANY)
9253         stacksize = 1;
9254       else if (common->currententry->start == 0)
9255         stacksize = stacksize == 0;
9256       else
9257         stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
9258
9259       if (stacksize != 0)
9260         matchingpath += 1 + IMM2_SIZE;
9261       }
9262     else
9263       {
9264       if (common->currententry == NULL || common->currententry->start == 0)
9265         stacksize = 0;
9266       else
9267         {
9268         stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
9269         slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
9270         i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
9271         while (stacksize > 0)
9272           {
9273           if ((int)GET2(slot, 0) == i)
9274             break;
9275           slot += common->name_entry_size;
9276           stacksize--;
9277           }
9278         }
9279
9280       if (stacksize != 0)
9281         matchingpath += 1 + 2 * IMM2_SIZE;
9282       }
9283
9284       /* The stacksize == 0 is a common "else" case. */
9285       if (stacksize == 0)
9286         {
9287         if (*cc == OP_ALT)
9288           {
9289           matchingpath = cc + 1 + LINK_SIZE;
9290           cc += GET(cc, 1);
9291           }
9292         else
9293           matchingpath = cc;
9294         }
9295     }
9296   else
9297     {
9298     SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
9299     /* Similar code as PUSH_BACKTRACK macro. */
9300     assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
9301     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9302       return NULL;
9303     memset(assert, 0, sizeof(assert_backtrack));
9304     assert->common.cc = matchingpath;
9305     BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
9306     matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
9307     }
9308   }
9309
9310 compile_matchingpath(common, matchingpath, cc, backtrack);
9311 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9312   return NULL;
9313
9314 if (opcode == OP_ONCE)
9315   match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
9316
9317 stacksize = 0;
9318 if (repeat_type == OP_MINUPTO)
9319   {
9320   /* We need to preserve the counter. TMP2 will be used below. */
9321   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
9322   stacksize++;
9323   }
9324 if (ket != OP_KET || bra != OP_BRA)
9325   stacksize++;
9326 if (offset != 0)
9327   {
9328   if (common->capture_last_ptr != 0)
9329     stacksize++;
9330   if (common->optimized_cbracket[offset >> 1] == 0)
9331     stacksize += 2;
9332   }
9333 if (has_alternatives && opcode != OP_ONCE)
9334   stacksize++;
9335
9336 if (stacksize > 0)
9337   allocate_stack(common, stacksize);
9338
9339 stacksize = 0;
9340 if (repeat_type == OP_MINUPTO)
9341   {
9342   /* TMP2 was set above. */
9343   OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
9344   stacksize++;
9345   }
9346
9347 if (ket != OP_KET || bra != OP_BRA)
9348   {
9349   if (ket != OP_KET)
9350     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
9351   else
9352     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
9353   stacksize++;
9354   }
9355
9356 if (offset != 0)
9357   stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
9358
9359 if (has_alternatives)
9360   {
9361   if (opcode != OP_ONCE)
9362     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
9363   if (ket != OP_KETRMAX)
9364     BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
9365   }
9366
9367 /* Must be after the matchingpath label. */
9368 if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
9369   {
9370   SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
9371   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
9372   }
9373
9374 if (ket == OP_KETRMAX)
9375   {
9376   if (repeat_type != 0)
9377     {
9378     if (has_alternatives)
9379       BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
9380     OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
9381     JUMPTO(SLJIT_NOT_ZERO, rmax_label);
9382     /* Drop STR_PTR for greedy plus quantifier. */
9383     if (opcode != OP_ONCE)
9384       free_stack(common, 1);
9385     }
9386   else if (opcode == OP_ONCE || opcode >= OP_SBRA)
9387     {
9388     if (has_alternatives)
9389       BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
9390     /* Checking zero-length iteration. */
9391     if (opcode != OP_ONCE)
9392       {
9393       CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);
9394       /* Drop STR_PTR for greedy plus quantifier. */
9395       if (bra != OP_BRAZERO)
9396         free_stack(common, 1);
9397       }
9398     else
9399       /* TMP2 must contain the starting STR_PTR. */
9400       CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
9401     }
9402   else
9403     JUMPTO(SLJIT_JUMP, rmax_label);
9404   BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
9405   }
9406
9407 if (repeat_type == OP_EXACT)
9408   {
9409   count_match(common);
9410   OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
9411   JUMPTO(SLJIT_NOT_ZERO, rmax_label);
9412   }
9413 else if (repeat_type == OP_UPTO)
9414   {
9415   /* We need to preserve the counter. */
9416   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
9417   allocate_stack(common, 1);
9418   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
9419   }
9420
9421 if (bra == OP_BRAZERO)
9422   BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
9423
9424 if (bra == OP_BRAMINZERO)
9425   {
9426   /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
9427   JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
9428   if (braminzero != NULL)
9429     {
9430     JUMPHERE(braminzero);
9431     /* We need to release the end pointer to perform the
9432     backtrack for the zero-length iteration. When
9433     framesize is < 0, OP_ONCE will do the release itself. */
9434     if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
9435       {
9436       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9437       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
9438       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw));
9439       }
9440     else if (ket == OP_KETRMIN && opcode != OP_ONCE)
9441       free_stack(common, 1);
9442     }
9443   /* Continue to the normal backtrack. */
9444   }
9445
9446 if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
9447   count_match(common);
9448
9449 /* Skip the other alternatives. */
9450 while (*cc == OP_ALT)
9451   cc += GET(cc, 1);
9452 cc += 1 + LINK_SIZE;
9453
9454 if (opcode == OP_ONCE)
9455   {
9456   /* We temporarily encode the needs_control_head in the lowest bit.
9457      Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
9458      the same value for small signed numbers (including negative numbers). */
9459   BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
9460   }
9461 return cc + repeat_length;
9462 }
9463
9464 static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
9465 {
9466 DEFINE_COMPILER;
9467 backtrack_common *backtrack;
9468 PCRE2_UCHAR opcode;
9469 int private_data_ptr;
9470 int cbraprivptr = 0;
9471 BOOL needs_control_head;
9472 int framesize;
9473 int stacksize;
9474 int offset = 0;
9475 BOOL zero = FALSE;
9476 PCRE2_SPTR ccbegin = NULL;
9477 int stack; /* Also contains the offset of control head. */
9478 struct sljit_label *loop = NULL;
9479 struct jump_list *emptymatch = NULL;
9480
9481 PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
9482 if (*cc == OP_BRAPOSZERO)
9483   {
9484   zero = TRUE;
9485   cc++;
9486   }
9487
9488 opcode = *cc;
9489 private_data_ptr = PRIVATE_DATA(cc);
9490 SLJIT_ASSERT(private_data_ptr != 0);
9491 BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
9492 switch(opcode)
9493   {
9494   case OP_BRAPOS:
9495   case OP_SBRAPOS:
9496   ccbegin = cc + 1 + LINK_SIZE;
9497   break;
9498
9499   case OP_CBRAPOS:
9500   case OP_SCBRAPOS:
9501   offset = GET2(cc, 1 + LINK_SIZE);
9502   /* This case cannot be optimized in the same was as
9503   normal capturing brackets. */
9504   SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
9505   cbraprivptr = OVECTOR_PRIV(offset);
9506   offset <<= 1;
9507   ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
9508   break;
9509
9510   default:
9511   SLJIT_UNREACHABLE();
9512   break;
9513   }
9514
9515 framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
9516 BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
9517 if (framesize < 0)
9518   {
9519   if (offset != 0)
9520     {
9521     stacksize = 2;
9522     if (common->capture_last_ptr != 0)
9523       stacksize++;
9524     }
9525   else
9526     stacksize = 1;
9527
9528   if (needs_control_head)
9529     stacksize++;
9530   if (!zero)
9531     stacksize++;
9532
9533   BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
9534   allocate_stack(common, stacksize);
9535   if (framesize == no_frame)
9536     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
9537
9538   stack = 0;
9539   if (offset != 0)
9540     {
9541     stack = 2;
9542     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
9543     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
9544     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
9545     if (common->capture_last_ptr != 0)
9546       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
9547     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
9548     if (needs_control_head)
9549       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
9550     if (common->capture_last_ptr != 0)
9551       {
9552       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
9553       stack = 3;
9554       }
9555     }
9556   else
9557     {
9558     if (needs_control_head)
9559       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
9560     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
9561     stack = 1;
9562     }
9563
9564   if (needs_control_head)
9565     stack++;
9566   if (!zero)
9567     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
9568   if (needs_control_head)
9569     {
9570     stack--;
9571     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
9572     }
9573   }
9574 else
9575   {
9576   stacksize = framesize + 1;
9577   if (!zero)
9578     stacksize++;
9579   if (needs_control_head)
9580     stacksize++;
9581   if (offset == 0)
9582     stacksize++;
9583   BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
9584
9585   allocate_stack(common, stacksize);
9586   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9587   if (needs_control_head)
9588     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
9589   OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
9590
9591   stack = 0;
9592   if (!zero)
9593     {
9594     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
9595     stack = 1;
9596     }
9597   if (needs_control_head)
9598     {
9599     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
9600     stack++;
9601     }
9602   if (offset == 0)
9603     {
9604     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
9605     stack++;
9606     }
9607   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
9608   init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize);
9609   stack -= 1 + (offset == 0);
9610   }
9611
9612 if (offset != 0)
9613   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
9614
9615 loop = LABEL();
9616 while (*cc != OP_KETRPOS)
9617   {
9618   backtrack->top = NULL;
9619   backtrack->topbacktracks = NULL;
9620   cc += GET(cc, 1);
9621
9622   compile_matchingpath(common, ccbegin, cc, backtrack);
9623   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9624     return NULL;
9625
9626   if (framesize < 0)
9627     {
9628     if (framesize == no_frame)
9629       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9630
9631     if (offset != 0)
9632       {
9633       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
9634       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
9635       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
9636       if (common->capture_last_ptr != 0)
9637         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
9638       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
9639       }
9640     else
9641       {
9642       if (opcode == OP_SBRAPOS)
9643         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9644       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
9645       }
9646
9647     /* Even if the match is empty, we need to reset the control head. */
9648     if (needs_control_head)
9649       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
9650
9651     if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
9652       add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
9653
9654     if (!zero)
9655       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
9656     }
9657   else
9658     {
9659     if (offset != 0)
9660       {
9661       OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
9662       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
9663       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
9664       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
9665       if (common->capture_last_ptr != 0)
9666         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
9667       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
9668       }
9669     else
9670       {
9671       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9672       OP2(SLJIT_SUB, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
9673       if (opcode == OP_SBRAPOS)
9674         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));
9675       OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(-framesize - 2), STR_PTR, 0);
9676       }
9677
9678     /* Even if the match is empty, we need to reset the control head. */
9679     if (needs_control_head)
9680       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
9681
9682     if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
9683       add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
9684
9685     if (!zero)
9686       {
9687       if (framesize < 0)
9688         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
9689       else
9690         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
9691       }
9692     }
9693
9694   JUMPTO(SLJIT_JUMP, loop);
9695   flush_stubs(common);
9696
9697   compile_backtrackingpath(common, backtrack->top);
9698   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9699     return NULL;
9700   set_jumps(backtrack->topbacktracks, LABEL());
9701
9702   if (framesize < 0)
9703     {
9704     if (offset != 0)
9705       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
9706     else
9707       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9708     }
9709   else
9710     {
9711     if (offset != 0)
9712       {
9713       /* Last alternative. */
9714       if (*cc == OP_KETRPOS)
9715         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9716       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
9717       }
9718     else
9719       {
9720       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9721       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), STACK(-framesize - 2));
9722       }
9723     }
9724
9725   if (*cc == OP_KETRPOS)
9726     break;
9727   ccbegin = cc + 1 + LINK_SIZE;
9728   }
9729
9730 /* We don't have to restore the control head in case of a failed match. */
9731
9732 backtrack->topbacktracks = NULL;
9733 if (!zero)
9734   {
9735   if (framesize < 0)
9736     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
9737   else /* TMP2 is set to [private_data_ptr] above. */
9738     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0));
9739   }
9740
9741 /* None of them matched. */
9742 set_jumps(emptymatch, LABEL());
9743 count_match(common);
9744 return cc + 1 + LINK_SIZE;
9745 }
9746
9747 static SLJIT_INLINE PCRE2_SPTR get_iterator_parameters(compiler_common *common, PCRE2_SPTR cc, PCRE2_UCHAR *opcode, PCRE2_UCHAR *type, sljit_u32 *max, sljit_u32 *exact, PCRE2_SPTR *end)
9748 {
9749 int class_len;
9750
9751 *opcode = *cc;
9752 *exact = 0;
9753
9754 if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
9755   {
9756   cc++;
9757   *type = OP_CHAR;
9758   }
9759 else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
9760   {
9761   cc++;
9762   *type = OP_CHARI;
9763   *opcode -= OP_STARI - OP_STAR;
9764   }
9765 else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
9766   {
9767   cc++;
9768   *type = OP_NOT;
9769   *opcode -= OP_NOTSTAR - OP_STAR;
9770   }
9771 else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
9772   {
9773   cc++;
9774   *type = OP_NOTI;
9775   *opcode -= OP_NOTSTARI - OP_STAR;
9776   }
9777 else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
9778   {
9779   cc++;
9780   *opcode -= OP_TYPESTAR - OP_STAR;
9781   *type = OP_END;
9782   }
9783 else
9784   {
9785   SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
9786   *type = *opcode;
9787   cc++;
9788   class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(PCRE2_UCHAR))) : GET(cc, 0);
9789   *opcode = cc[class_len - 1];
9790
9791   if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
9792     {
9793     *opcode -= OP_CRSTAR - OP_STAR;
9794     *end = cc + class_len;
9795
9796     if (*opcode == OP_PLUS || *opcode == OP_MINPLUS)
9797       {
9798       *exact = 1;
9799       *opcode -= OP_PLUS - OP_STAR;
9800       }
9801     }
9802   else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
9803     {
9804     *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
9805     *end = cc + class_len;
9806
9807     if (*opcode == OP_POSPLUS)
9808       {
9809       *exact = 1;
9810       *opcode = OP_POSSTAR;
9811       }
9812     }
9813   else
9814     {
9815     SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
9816     *max = GET2(cc, (class_len + IMM2_SIZE));
9817     *exact = GET2(cc, class_len);
9818
9819     if (*max == 0)
9820       {
9821       if (*opcode == OP_CRPOSRANGE)
9822         *opcode = OP_POSSTAR;
9823       else
9824         *opcode -= OP_CRRANGE - OP_STAR;
9825       }
9826     else
9827       {
9828       *max -= *exact;
9829       if (*max == 0)
9830         *opcode = OP_EXACT;
9831       else if (*max == 1)
9832         {
9833         if (*opcode == OP_CRPOSRANGE)
9834           *opcode = OP_POSQUERY;
9835         else
9836           *opcode -= OP_CRRANGE - OP_QUERY;
9837         }
9838       else
9839         {
9840         if (*opcode == OP_CRPOSRANGE)
9841           *opcode = OP_POSUPTO;
9842         else
9843           *opcode -= OP_CRRANGE - OP_UPTO;
9844         }
9845       }
9846     *end = cc + class_len + 2 * IMM2_SIZE;
9847     }
9848   return cc;
9849   }
9850
9851 switch(*opcode)
9852   {
9853   case OP_EXACT:
9854   *exact = GET2(cc, 0);
9855   cc += IMM2_SIZE;
9856   break;
9857
9858   case OP_PLUS:
9859   case OP_MINPLUS:
9860   *exact = 1;
9861   *opcode -= OP_PLUS - OP_STAR;
9862   break;
9863
9864   case OP_POSPLUS:
9865   *exact = 1;
9866   *opcode = OP_POSSTAR;
9867   break;
9868
9869   case OP_UPTO:
9870   case OP_MINUPTO:
9871   case OP_POSUPTO:
9872   *max = GET2(cc, 0);
9873   cc += IMM2_SIZE;
9874   break;
9875   }
9876
9877 if (*type == OP_END)
9878   {
9879   *type = *cc;
9880   *end = next_opcode(common, cc);
9881   cc++;
9882   return cc;
9883   }
9884
9885 *end = cc + 1;
9886 #ifdef SUPPORT_UNICODE
9887 if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
9888 #endif
9889 return cc;
9890 }
9891
9892 static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
9893 {
9894 DEFINE_COMPILER;
9895 backtrack_common *backtrack;
9896 PCRE2_UCHAR opcode;
9897 PCRE2_UCHAR type;
9898 sljit_u32 max = 0, exact;
9899 BOOL fast_fail;
9900 sljit_s32 fast_str_ptr;
9901 BOOL charpos_enabled;
9902 PCRE2_UCHAR charpos_char;
9903 unsigned int charpos_othercasebit;
9904 PCRE2_SPTR end;
9905 jump_list *no_match = NULL;
9906 jump_list *no_char1_match = NULL;
9907 struct sljit_jump *jump = NULL;
9908 struct sljit_label *label;
9909 int private_data_ptr = PRIVATE_DATA(cc);
9910 int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
9911 int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
9912 int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
9913 int tmp_base, tmp_offset;
9914
9915 PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL);
9916
9917 fast_str_ptr = PRIVATE_DATA(cc + 1);
9918 fast_fail = TRUE;
9919
9920 SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr);
9921
9922 if (cc == common->fast_forward_bc_ptr)
9923   fast_fail = FALSE;
9924 else if (common->fast_fail_start_ptr == 0)
9925   fast_str_ptr = 0;
9926
9927 SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0
9928   || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr));
9929
9930 cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
9931
9932 if (type != OP_EXTUNI)
9933   {
9934   tmp_base = TMP3;
9935   tmp_offset = 0;
9936   }
9937 else
9938   {
9939   tmp_base = SLJIT_MEM1(SLJIT_SP);
9940   tmp_offset = POSSESSIVE0;
9941   }
9942
9943 if (fast_fail && fast_str_ptr != 0)
9944   add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr));
9945
9946 /* Handle fixed part first. */
9947 if (exact > 1)
9948   {
9949   SLJIT_ASSERT(fast_str_ptr == 0);
9950   if (common->mode == PCRE2_JIT_COMPLETE
9951 #ifdef SUPPORT_UNICODE
9952       && !common->utf
9953 #endif
9954       )
9955     {
9956     OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));
9957     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0));
9958     OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
9959     label = LABEL();
9960     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
9961     OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
9962     JUMPTO(SLJIT_NOT_ZERO, label);
9963     }
9964   else
9965     {
9966     OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
9967     label = LABEL();
9968     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
9969     OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
9970     JUMPTO(SLJIT_NOT_ZERO, label);
9971     }
9972   }
9973 else if (exact == 1)
9974   compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
9975
9976 switch(opcode)
9977   {
9978   case OP_STAR:
9979   case OP_UPTO:
9980   SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR);
9981
9982   if (type == OP_ANYNL || type == OP_EXTUNI)
9983     {
9984     SLJIT_ASSERT(private_data_ptr == 0);
9985     SLJIT_ASSERT(fast_str_ptr == 0);
9986
9987     allocate_stack(common, 2);
9988     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
9989     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
9990
9991     if (opcode == OP_UPTO)
9992       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max);
9993
9994     label = LABEL();
9995     compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
9996     if (opcode == OP_UPTO)
9997       {
9998       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
9999       OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
10000       jump = JUMP(SLJIT_ZERO);
10001       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
10002       }
10003
10004     /* We cannot use TMP3 because of this allocate_stack. */
10005     allocate_stack(common, 1);
10006     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
10007     JUMPTO(SLJIT_JUMP, label);
10008     if (jump != NULL)
10009       JUMPHERE(jump);
10010     }
10011   else
10012     {
10013     charpos_enabled = FALSE;
10014     charpos_char = 0;
10015     charpos_othercasebit = 0;
10016
10017     if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))
10018       {
10019       charpos_enabled = TRUE;
10020 #ifdef SUPPORT_UNICODE
10021       charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);
10022 #endif
10023       if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))
10024         {
10025         charpos_othercasebit = char_get_othercase_bit(common, end + 1);
10026         if (charpos_othercasebit == 0)
10027           charpos_enabled = FALSE;
10028         }
10029
10030       if (charpos_enabled)
10031         {
10032         charpos_char = end[1];
10033         /* Consumpe the OP_CHAR opcode. */
10034         end += 2;
10035 #if PCRE2_CODE_UNIT_WIDTH == 8
10036         SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
10037 #elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
10038         SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);
10039         if ((charpos_othercasebit & 0x100) != 0)
10040           charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
10041 #endif
10042         if (charpos_othercasebit != 0)
10043           charpos_char |= charpos_othercasebit;
10044
10045         BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;
10046         BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
10047         BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
10048         }
10049       }
10050
10051     if (charpos_enabled)
10052       {
10053       if (opcode == OP_UPTO)
10054         OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);
10055
10056       /* Search the first instance of charpos_char. */
10057       jump = JUMP(SLJIT_JUMP);
10058       label = LABEL();
10059       if (opcode == OP_UPTO)
10060         {
10061         OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10062         add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
10063         }
10064       compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
10065       if (fast_str_ptr != 0)
10066         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10067       JUMPHERE(jump);
10068
10069       detect_partial_match(common, &backtrack->topbacktracks);
10070       OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
10071       if (charpos_othercasebit != 0)
10072         OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
10073       CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
10074
10075       if (private_data_ptr == 0)
10076         allocate_stack(common, 2);
10077       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10078       OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
10079       if (opcode == OP_UPTO)
10080         {
10081         OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10082         add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
10083         }
10084
10085       /* Search the last instance of charpos_char. */
10086       label = LABEL();
10087       compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
10088       if (fast_str_ptr != 0)
10089         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10090       detect_partial_match(common, &no_match);
10091       OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
10092       if (charpos_othercasebit != 0)
10093         OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
10094       if (opcode == OP_STAR)
10095         {
10096         CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
10097         OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10098         }
10099       else
10100         {
10101         jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
10102         OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10103         JUMPHERE(jump);
10104         }
10105
10106       if (opcode == OP_UPTO)
10107         {
10108         OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10109         JUMPTO(SLJIT_NOT_ZERO, label);
10110         }
10111       else
10112         JUMPTO(SLJIT_JUMP, label);
10113
10114       set_jumps(no_match, LABEL());
10115       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10116       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10117       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10118       }
10119 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10120     else if (common->utf)
10121       {
10122       if (private_data_ptr == 0)
10123         allocate_stack(common, 2);
10124
10125       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10126       OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
10127
10128       if (opcode == OP_UPTO)
10129         OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
10130
10131       label = LABEL();
10132       compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
10133       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10134
10135       if (opcode == OP_UPTO)
10136         {
10137         OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10138         JUMPTO(SLJIT_NOT_ZERO, label);
10139         }
10140       else
10141         JUMPTO(SLJIT_JUMP, label);
10142
10143       set_jumps(no_match, LABEL());
10144       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10145       if (fast_str_ptr != 0)
10146         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10147       }
10148 #endif
10149     else
10150       {
10151       if (private_data_ptr == 0)
10152         allocate_stack(common, 2);
10153
10154       OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
10155       if (opcode == OP_UPTO)
10156         OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
10157
10158       label = LABEL();
10159       detect_partial_match(common, &no_match);
10160       compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
10161       if (opcode == OP_UPTO)
10162         {
10163         OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10164         JUMPTO(SLJIT_NOT_ZERO, label);
10165         OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10166         }
10167       else
10168         JUMPTO(SLJIT_JUMP, label);
10169
10170       set_jumps(no_char1_match, LABEL());
10171       OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10172       set_jumps(no_match, LABEL());
10173       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10174       if (fast_str_ptr != 0)
10175         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10176       }
10177     }
10178   BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
10179   break;
10180
10181   case OP_MINSTAR:
10182   if (private_data_ptr == 0)
10183     allocate_stack(common, 1);
10184   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10185   BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
10186   if (fast_str_ptr != 0)
10187     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10188   break;
10189
10190   case OP_MINUPTO:
10191   SLJIT_ASSERT(fast_str_ptr == 0);
10192   if (private_data_ptr == 0)
10193     allocate_stack(common, 2);
10194   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10195   OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1);
10196   BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
10197   break;
10198
10199   case OP_QUERY:
10200   case OP_MINQUERY:
10201   SLJIT_ASSERT(fast_str_ptr == 0);
10202   if (private_data_ptr == 0)
10203     allocate_stack(common, 1);
10204   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10205   if (opcode == OP_QUERY)
10206     compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
10207   BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
10208   break;
10209
10210   case OP_EXACT:
10211   break;
10212
10213   case OP_POSSTAR:
10214 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10215   if (common->utf)
10216     {
10217     OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
10218     label = LABEL();
10219     compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
10220     OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
10221     JUMPTO(SLJIT_JUMP, label);
10222     set_jumps(no_match, LABEL());
10223     OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
10224     if (fast_str_ptr != 0)
10225       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10226     break;
10227     }
10228 #endif
10229   label = LABEL();
10230   detect_partial_match(common, &no_match);
10231   compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
10232   JUMPTO(SLJIT_JUMP, label);
10233   set_jumps(no_char1_match, LABEL());
10234   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10235   set_jumps(no_match, LABEL());
10236   if (fast_str_ptr != 0)
10237     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
10238   break;
10239
10240   case OP_POSUPTO:
10241   SLJIT_ASSERT(fast_str_ptr == 0);
10242 #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10243   if (common->utf)
10244     {
10245     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
10246     OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
10247     label = LABEL();
10248     compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
10249     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
10250     OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10251     JUMPTO(SLJIT_NOT_ZERO, label);
10252     set_jumps(no_match, LABEL());
10253     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
10254     break;
10255     }
10256 #endif
10257   OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
10258   label = LABEL();
10259   detect_partial_match(common, &no_match);
10260   compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
10261   OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
10262   JUMPTO(SLJIT_NOT_ZERO, label);
10263   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10264   set_jumps(no_char1_match, LABEL());
10265   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10266   set_jumps(no_match, LABEL());
10267   break;
10268
10269   case OP_POSQUERY:
10270   SLJIT_ASSERT(fast_str_ptr == 0);
10271   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
10272   compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
10273   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
10274   set_jumps(no_match, LABEL());
10275   OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
10276   break;
10277
10278   default:
10279   SLJIT_UNREACHABLE();
10280   break;
10281   }
10282
10283 count_match(common);
10284 return end;
10285 }
10286
10287 static SLJIT_INLINE PCRE2_SPTR compile_fail_accept_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
10288 {
10289 DEFINE_COMPILER;
10290 backtrack_common *backtrack;
10291
10292 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
10293
10294 if (*cc == OP_FAIL)
10295   {
10296   add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
10297   return cc + 1;
10298   }
10299
10300 if (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0)
10301   add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
10302
10303 if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
10304   {
10305   /* No need to check notempty conditions. */
10306   if (common->accept_label == NULL)
10307     add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
10308   else
10309     JUMPTO(SLJIT_JUMP, common->accept_label);
10310   return cc + 1;
10311   }
10312
10313 if (common->accept_label == NULL)
10314   add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));
10315 else
10316   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
10317 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
10318 OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
10319 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
10320 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO));
10321 OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
10322 if (common->accept_label == NULL)
10323   add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));
10324 else
10325   JUMPTO(SLJIT_ZERO, common->accept_label);
10326 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
10327 if (common->accept_label == NULL)
10328   add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
10329 else
10330   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
10331 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
10332 return cc + 1;
10333 }
10334
10335 static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *common, PCRE2_SPTR cc)
10336 {
10337 DEFINE_COMPILER;
10338 int offset = GET2(cc, 1);
10339 BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
10340
10341 /* Data will be discarded anyway... */
10342 if (common->currententry != NULL)
10343   return cc + 1 + IMM2_SIZE;
10344
10345 if (!optimized_cbracket)
10346   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));
10347 offset <<= 1;
10348 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
10349 if (!optimized_cbracket)
10350   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
10351 return cc + 1 + IMM2_SIZE;
10352 }
10353
10354 static SLJIT_INLINE PCRE2_SPTR compile_control_verb_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent)
10355 {
10356 DEFINE_COMPILER;
10357 backtrack_common *backtrack;
10358 PCRE2_UCHAR opcode = *cc;
10359 PCRE2_SPTR ccend = cc + 1;
10360
10361 if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG ||
10362     opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
10363   ccend += 2 + cc[1];
10364
10365 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
10366
10367 if (opcode == OP_SKIP)
10368   {
10369   allocate_stack(common, 1);
10370   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
10371   return ccend;
10372   }
10373
10374 if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
10375   {
10376   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
10377   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
10378   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
10379   OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
10380   }
10381
10382 return ccend;
10383 }
10384
10385 static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP };
10386
10387 static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
10388 {
10389 DEFINE_COMPILER;
10390 backtrack_common *backtrack;
10391 BOOL needs_control_head;
10392 int size;
10393
10394 PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
10395 common->then_trap = BACKTRACK_AS(then_trap_backtrack);
10396 BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
10397 BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
10398 BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
10399
10400 size = BACKTRACK_AS(then_trap_backtrack)->framesize;
10401 size = 3 + (size < 0 ? 0 : size);
10402
10403 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
10404 allocate_stack(common, size);
10405 if (size > 3)
10406   OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
10407 else
10408   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
10409 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
10410 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
10411 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
10412
10413 size = BACKTRACK_AS(then_trap_backtrack)->framesize;
10414 if (size >= 0)
10415   init_frame(common, cc, ccend, size - 1, 0);
10416 }
10417
10418 static void compile_matchingpath(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, backtrack_common *parent)
10419 {
10420 DEFINE_COMPILER;
10421 backtrack_common *backtrack;
10422 BOOL has_then_trap = FALSE;
10423 then_trap_backtrack *save_then_trap = NULL;
10424
10425 SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
10426
10427 if (common->has_then && common->then_offsets[cc - common->start] != 0)
10428   {
10429   SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
10430   has_then_trap = TRUE;
10431   save_then_trap = common->then_trap;
10432   /* Tail item on backtrack. */
10433   compile_then_trap_matchingpath(common, cc, ccend, parent);
10434   }
10435
10436 while (cc < ccend)
10437   {
10438   switch(*cc)
10439     {
10440     case OP_SOD:
10441     case OP_SOM:
10442     case OP_NOT_WORD_BOUNDARY:
10443     case OP_WORD_BOUNDARY:
10444     case OP_EODN:
10445     case OP_EOD:
10446     case OP_DOLL:
10447     case OP_DOLLM:
10448     case OP_CIRC:
10449     case OP_CIRCM:
10450     case OP_REVERSE:
10451     cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
10452     break;
10453
10454     case OP_NOT_DIGIT:
10455     case OP_DIGIT:
10456     case OP_NOT_WHITESPACE:
10457     case OP_WHITESPACE:
10458     case OP_NOT_WORDCHAR:
10459     case OP_WORDCHAR:
10460     case OP_ANY:
10461     case OP_ALLANY:
10462     case OP_ANYBYTE:
10463     case OP_NOTPROP:
10464     case OP_PROP:
10465     case OP_ANYNL:
10466     case OP_NOT_HSPACE:
10467     case OP_HSPACE:
10468     case OP_NOT_VSPACE:
10469     case OP_VSPACE:
10470     case OP_EXTUNI:
10471     case OP_NOT:
10472     case OP_NOTI:
10473     cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
10474     break;
10475
10476     case OP_SET_SOM:
10477     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
10478     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
10479     allocate_stack(common, 1);
10480     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
10481     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
10482     cc++;
10483     break;
10484
10485     case OP_CHAR:
10486     case OP_CHARI:
10487     if (common->mode == PCRE2_JIT_COMPLETE)
10488       cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
10489     else
10490       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
10491     break;
10492
10493     case OP_STAR:
10494     case OP_MINSTAR:
10495     case OP_PLUS:
10496     case OP_MINPLUS:
10497     case OP_QUERY:
10498     case OP_MINQUERY:
10499     case OP_UPTO:
10500     case OP_MINUPTO:
10501     case OP_EXACT:
10502     case OP_POSSTAR:
10503     case OP_POSPLUS:
10504     case OP_POSQUERY:
10505     case OP_POSUPTO:
10506     case OP_STARI:
10507     case OP_MINSTARI:
10508     case OP_PLUSI:
10509     case OP_MINPLUSI:
10510     case OP_QUERYI:
10511     case OP_MINQUERYI:
10512     case OP_UPTOI:
10513     case OP_MINUPTOI:
10514     case OP_EXACTI:
10515     case OP_POSSTARI:
10516     case OP_POSPLUSI:
10517     case OP_POSQUERYI:
10518     case OP_POSUPTOI:
10519     case OP_NOTSTAR:
10520     case OP_NOTMINSTAR:
10521     case OP_NOTPLUS:
10522     case OP_NOTMINPLUS:
10523     case OP_NOTQUERY:
10524     case OP_NOTMINQUERY:
10525     case OP_NOTUPTO:
10526     case OP_NOTMINUPTO:
10527     case OP_NOTEXACT:
10528     case OP_NOTPOSSTAR:
10529     case OP_NOTPOSPLUS:
10530     case OP_NOTPOSQUERY:
10531     case OP_NOTPOSUPTO:
10532     case OP_NOTSTARI:
10533     case OP_NOTMINSTARI:
10534     case OP_NOTPLUSI:
10535     case OP_NOTMINPLUSI:
10536     case OP_NOTQUERYI:
10537     case OP_NOTMINQUERYI:
10538     case OP_NOTUPTOI:
10539     case OP_NOTMINUPTOI:
10540     case OP_NOTEXACTI:
10541     case OP_NOTPOSSTARI:
10542     case OP_NOTPOSPLUSI:
10543     case OP_NOTPOSQUERYI:
10544     case OP_NOTPOSUPTOI:
10545     case OP_TYPESTAR:
10546     case OP_TYPEMINSTAR:
10547     case OP_TYPEPLUS:
10548     case OP_TYPEMINPLUS:
10549     case OP_TYPEQUERY:
10550     case OP_TYPEMINQUERY:
10551     case OP_TYPEUPTO:
10552     case OP_TYPEMINUPTO:
10553     case OP_TYPEEXACT:
10554     case OP_TYPEPOSSTAR:
10555     case OP_TYPEPOSPLUS:
10556     case OP_TYPEPOSQUERY:
10557     case OP_TYPEPOSUPTO:
10558     cc = compile_iterator_matchingpath(common, cc, parent);
10559     break;
10560
10561     case OP_CLASS:
10562     case OP_NCLASS:
10563     if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE)
10564       cc = compile_iterator_matchingpath(common, cc, parent);
10565     else
10566       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
10567     break;
10568
10569 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
10570     case OP_XCLASS:
10571     if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
10572       cc = compile_iterator_matchingpath(common, cc, parent);
10573     else
10574       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
10575     break;
10576 #endif
10577
10578     case OP_REF:
10579     case OP_REFI:
10580     if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
10581       cc = compile_ref_iterator_matchingpath(common, cc, parent);
10582     else
10583       {
10584       compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
10585       cc += 1 + IMM2_SIZE;
10586       }
10587     break;
10588
10589     case OP_DNREF:
10590     case OP_DNREFI:
10591     if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
10592       cc = compile_ref_iterator_matchingpath(common, cc, parent);
10593     else
10594       {
10595       compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
10596       compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
10597       cc += 1 + 2 * IMM2_SIZE;
10598       }
10599     break;
10600
10601     case OP_RECURSE:
10602     cc = compile_recurse_matchingpath(common, cc, parent);
10603     break;
10604
10605     case OP_CALLOUT:
10606     case OP_CALLOUT_STR:
10607     cc = compile_callout_matchingpath(common, cc, parent);
10608     break;
10609
10610     case OP_ASSERT:
10611     case OP_ASSERT_NOT:
10612     case OP_ASSERTBACK:
10613     case OP_ASSERTBACK_NOT:
10614     PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
10615     cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
10616     break;
10617
10618     case OP_BRAMINZERO:
10619     PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
10620     cc = bracketend(cc + 1);
10621     if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
10622       {
10623       allocate_stack(common, 1);
10624       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
10625       }
10626     else
10627       {
10628       allocate_stack(common, 2);
10629       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
10630       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
10631       }
10632     BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
10633     count_match(common);
10634     break;
10635
10636     case OP_ONCE:
10637     case OP_BRA:
10638     case OP_CBRA:
10639     case OP_COND:
10640     case OP_SBRA:
10641     case OP_SCBRA:
10642     case OP_SCOND:
10643     cc = compile_bracket_matchingpath(common, cc, parent);
10644     break;
10645
10646     case OP_BRAZERO:
10647     if (cc[1] > OP_ASSERTBACK_NOT)
10648       cc = compile_bracket_matchingpath(common, cc, parent);
10649     else
10650       {
10651       PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
10652       cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
10653       }
10654     break;
10655
10656     case OP_BRAPOS:
10657     case OP_CBRAPOS:
10658     case OP_SBRAPOS:
10659     case OP_SCBRAPOS:
10660     case OP_BRAPOSZERO:
10661     cc = compile_bracketpos_matchingpath(common, cc, parent);
10662     break;
10663
10664     case OP_MARK:
10665     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
10666     SLJIT_ASSERT(common->mark_ptr != 0);
10667     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
10668     allocate_stack(common, common->has_skip_arg ? 5 : 1);
10669     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
10670     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
10671     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
10672     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
10673     OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
10674     if (common->has_skip_arg)
10675       {
10676       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
10677       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
10678       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
10679       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
10680       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
10681       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
10682       }
10683     cc += 1 + 2 + cc[1];
10684     break;
10685
10686     case OP_PRUNE:
10687     case OP_PRUNE_ARG:
10688     case OP_SKIP:
10689     case OP_SKIP_ARG:
10690     case OP_THEN:
10691     case OP_THEN_ARG:
10692     case OP_COMMIT:
10693     case OP_COMMIT_ARG:
10694     cc = compile_control_verb_matchingpath(common, cc, parent);
10695     break;
10696
10697     case OP_FAIL:
10698     case OP_ACCEPT:
10699     case OP_ASSERT_ACCEPT:
10700     cc = compile_fail_accept_matchingpath(common, cc, parent);
10701     break;
10702
10703     case OP_CLOSE:
10704     cc = compile_close_matchingpath(common, cc);
10705     break;
10706
10707     case OP_SKIPZERO:
10708     cc = bracketend(cc + 1);
10709     break;
10710
10711     default:
10712     SLJIT_UNREACHABLE();
10713     return;
10714     }
10715   if (cc == NULL)
10716     return;
10717   }
10718
10719 if (has_then_trap)
10720   {
10721   /* Head item on backtrack. */
10722   PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
10723   BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
10724   BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
10725   common->then_trap = save_then_trap;
10726   }
10727 SLJIT_ASSERT(cc == ccend);
10728 }
10729
10730 #undef PUSH_BACKTRACK
10731 #undef PUSH_BACKTRACK_NOVALUE
10732 #undef BACKTRACK_AS
10733
10734 #define COMPILE_BACKTRACKINGPATH(current) \
10735   do \
10736     { \
10737     compile_backtrackingpath(common, (current)); \
10738     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
10739       return; \
10740     } \
10741   while (0)
10742
10743 #define CURRENT_AS(type) ((type *)current)
10744
10745 static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10746 {
10747 DEFINE_COMPILER;
10748 PCRE2_SPTR cc = current->cc;
10749 PCRE2_UCHAR opcode;
10750 PCRE2_UCHAR type;
10751 sljit_u32 max = 0, exact;
10752 struct sljit_label *label = NULL;
10753 struct sljit_jump *jump = NULL;
10754 jump_list *jumplist = NULL;
10755 PCRE2_SPTR end;
10756 int private_data_ptr = PRIVATE_DATA(cc);
10757 int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
10758 int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
10759 int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
10760
10761 cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
10762
10763 switch(opcode)
10764   {
10765   case OP_STAR:
10766   case OP_UPTO:
10767   if (type == OP_ANYNL || type == OP_EXTUNI)
10768     {
10769     SLJIT_ASSERT(private_data_ptr == 0);
10770     set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
10771     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10772     free_stack(common, 1);
10773     CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10774     }
10775   else
10776     {
10777     if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled)
10778       {
10779       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10780       OP1(SLJIT_MOV, TMP2, 0, base, offset1);
10781       OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
10782
10783       jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
10784       label = LABEL();
10785       OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
10786       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10787       if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0)
10788         OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit);
10789       CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10790       skip_char_back(common);
10791       CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label);
10792       }
10793     else
10794       {
10795       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10796       jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);
10797       skip_char_back(common);
10798       OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10799       JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10800       }
10801     JUMPHERE(jump);
10802     if (private_data_ptr == 0)
10803       free_stack(common, 2);
10804     }
10805   break;
10806
10807   case OP_MINSTAR:
10808   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10809   compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
10810   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10811   JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10812   set_jumps(jumplist, LABEL());
10813   if (private_data_ptr == 0)
10814     free_stack(common, 1);
10815   break;
10816
10817   case OP_MINUPTO:
10818   OP1(SLJIT_MOV, TMP1, 0, base, offset1);
10819   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10820   OP2(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
10821   add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO));
10822
10823   OP1(SLJIT_MOV, base, offset1, TMP1, 0);
10824   compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
10825   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
10826   JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10827
10828   set_jumps(jumplist, LABEL());
10829   if (private_data_ptr == 0)
10830     free_stack(common, 2);
10831   break;
10832
10833   case OP_QUERY:
10834   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10835   OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
10836   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10837   jump = JUMP(SLJIT_JUMP);
10838   set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
10839   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10840   OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
10841   JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10842   JUMPHERE(jump);
10843   if (private_data_ptr == 0)
10844     free_stack(common, 1);
10845   break;
10846
10847   case OP_MINQUERY:
10848   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
10849   OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
10850   jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
10851   compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
10852   JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
10853   set_jumps(jumplist, LABEL());
10854   JUMPHERE(jump);
10855   if (private_data_ptr == 0)
10856     free_stack(common, 1);
10857   break;
10858
10859   case OP_EXACT:
10860   case OP_POSSTAR:
10861   case OP_POSQUERY:
10862   case OP_POSUPTO:
10863   break;
10864
10865   default:
10866   SLJIT_UNREACHABLE();
10867   break;
10868   }
10869
10870 set_jumps(current->topbacktracks, LABEL());
10871 }
10872
10873 static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10874 {
10875 DEFINE_COMPILER;
10876 PCRE2_SPTR cc = current->cc;
10877 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
10878 PCRE2_UCHAR type;
10879
10880 type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
10881
10882 if ((type & 0x1) == 0)
10883   {
10884   /* Maximize case. */
10885   set_jumps(current->topbacktracks, LABEL());
10886   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10887   free_stack(common, 1);
10888   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
10889   return;
10890   }
10891
10892 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10893 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
10894 set_jumps(current->topbacktracks, LABEL());
10895 free_stack(common, ref ? 2 : 3);
10896 }
10897
10898 static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10899 {
10900 DEFINE_COMPILER;
10901 recurse_entry *entry;
10902
10903 if (!CURRENT_AS(recurse_backtrack)->inlined_pattern)
10904   {
10905   entry = CURRENT_AS(recurse_backtrack)->entry;
10906   if (entry->backtrack_label == NULL)
10907     add_jump(compiler, &entry->backtrack_calls, JUMP(SLJIT_FAST_CALL));
10908   else
10909     JUMPTO(SLJIT_FAST_CALL, entry->backtrack_label);
10910   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(recurse_backtrack)->matchingpath);
10911   }
10912 else
10913   compile_backtrackingpath(common, current->top);
10914
10915 set_jumps(current->topbacktracks, LABEL());
10916 }
10917
10918 static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10919 {
10920 DEFINE_COMPILER;
10921 PCRE2_SPTR cc = current->cc;
10922 PCRE2_UCHAR bra = OP_BRA;
10923 struct sljit_jump *brajump = NULL;
10924
10925 SLJIT_ASSERT(*cc != OP_BRAMINZERO);
10926 if (*cc == OP_BRAZERO)
10927   {
10928   bra = *cc;
10929   cc++;
10930   }
10931
10932 if (bra == OP_BRAZERO)
10933   {
10934   SLJIT_ASSERT(current->topbacktracks == NULL);
10935   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10936   }
10937
10938 if (CURRENT_AS(assert_backtrack)->framesize < 0)
10939   {
10940   set_jumps(current->topbacktracks, LABEL());
10941
10942   if (bra == OP_BRAZERO)
10943     {
10944     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
10945     CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
10946     free_stack(common, 1);
10947     }
10948   return;
10949   }
10950
10951 if (bra == OP_BRAZERO)
10952   {
10953   if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
10954     {
10955     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
10956     CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
10957     free_stack(common, 1);
10958     return;
10959     }
10960   free_stack(common, 1);
10961   brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
10962   }
10963
10964 if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
10965   {
10966   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);
10967   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10968   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
10969   OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(assert_backtrack)->framesize - 1) * sizeof(sljit_sw));
10970   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, TMP1, 0);
10971
10972   set_jumps(current->topbacktracks, LABEL());
10973   }
10974 else
10975   set_jumps(current->topbacktracks, LABEL());
10976
10977 if (bra == OP_BRAZERO)
10978   {
10979   /* We know there is enough place on the stack. */
10980   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
10981   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
10982   JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
10983   JUMPHERE(brajump);
10984   }
10985 }
10986
10987 static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10988 {
10989 DEFINE_COMPILER;
10990 int opcode, stacksize, alt_count, alt_max;
10991 int offset = 0;
10992 int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
10993 int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
10994 PCRE2_SPTR cc = current->cc;
10995 PCRE2_SPTR ccbegin;
10996 PCRE2_SPTR ccprev;
10997 PCRE2_UCHAR bra = OP_BRA;
10998 PCRE2_UCHAR ket;
10999 assert_backtrack *assert;
11000 sljit_uw *next_update_addr = NULL;
11001 BOOL has_alternatives;
11002 BOOL needs_control_head = FALSE;
11003 struct sljit_jump *brazero = NULL;
11004 struct sljit_jump *alt1 = NULL;
11005 struct sljit_jump *alt2 = NULL;
11006 struct sljit_jump *once = NULL;
11007 struct sljit_jump *cond = NULL;
11008 struct sljit_label *rmin_label = NULL;
11009 struct sljit_label *exact_label = NULL;
11010
11011 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
11012   {
11013   bra = *cc;
11014   cc++;
11015   }
11016
11017 opcode = *cc;
11018 ccbegin = bracketend(cc) - 1 - LINK_SIZE;
11019 ket = *ccbegin;
11020 if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
11021   {
11022   repeat_ptr = PRIVATE_DATA(ccbegin);
11023   repeat_type = PRIVATE_DATA(ccbegin + 2);
11024   repeat_count = PRIVATE_DATA(ccbegin + 3);
11025   SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
11026   if (repeat_type == OP_UPTO)
11027     ket = OP_KETRMAX;
11028   if (repeat_type == OP_MINUPTO)
11029     ket = OP_KETRMIN;
11030   }
11031 ccbegin = cc;
11032 cc += GET(cc, 1);
11033 has_alternatives = *cc == OP_ALT;
11034 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
11035   has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
11036 if (opcode == OP_CBRA || opcode == OP_SCBRA)
11037   offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
11038 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
11039   opcode = OP_SCOND;
11040
11041 alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
11042
11043 /* Decoding the needs_control_head in framesize. */
11044 if (opcode == OP_ONCE)
11045   {
11046   needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
11047   CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
11048   }
11049
11050 if (ket != OP_KET && repeat_type != 0)
11051   {
11052   /* TMP1 is used in OP_KETRMIN below. */
11053   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11054   free_stack(common, 1);
11055   if (repeat_type == OP_UPTO)
11056     OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
11057   else
11058     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
11059   }
11060
11061 if (ket == OP_KETRMAX)
11062   {
11063   if (bra == OP_BRAZERO)
11064     {
11065     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11066     free_stack(common, 1);
11067     brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
11068     }
11069   }
11070 else if (ket == OP_KETRMIN)
11071   {
11072   if (bra != OP_BRAMINZERO)
11073     {
11074     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11075     if (repeat_type != 0)
11076       {
11077       /* TMP1 was set a few lines above. */
11078       CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
11079       /* Drop STR_PTR for non-greedy plus quantifier. */
11080       if (opcode != OP_ONCE)
11081         free_stack(common, 1);
11082       }
11083     else if (opcode >= OP_SBRA || opcode == OP_ONCE)
11084       {
11085       /* Checking zero-length iteration. */
11086       if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
11087         CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
11088       else
11089         {
11090         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
11091         CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 2), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
11092         }
11093       /* Drop STR_PTR for non-greedy plus quantifier. */
11094       if (opcode != OP_ONCE)
11095         free_stack(common, 1);
11096       }
11097     else
11098       JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
11099     }
11100   rmin_label = LABEL();
11101   if (repeat_type != 0)
11102     OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
11103   }
11104 else if (bra == OP_BRAZERO)
11105   {
11106   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11107   free_stack(common, 1);
11108   brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
11109   }
11110 else if (repeat_type == OP_EXACT)
11111   {
11112   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
11113   exact_label = LABEL();
11114   }
11115
11116 if (offset != 0)
11117   {
11118   if (common->capture_last_ptr != 0)
11119     {
11120     SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
11121     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11122     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11123     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
11124     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
11125     free_stack(common, 3);
11126     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);
11127     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
11128     }
11129   else if (common->optimized_cbracket[offset >> 1] == 0)
11130     {
11131     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11132     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11133     free_stack(common, 2);
11134     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
11135     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
11136     }
11137   }
11138
11139 if (SLJIT_UNLIKELY(opcode == OP_ONCE))
11140   {
11141   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
11142     {
11143     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
11144     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
11145     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize - 1) * sizeof(sljit_sw));
11146     }
11147   once = JUMP(SLJIT_JUMP);
11148   }
11149 else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
11150   {
11151   if (has_alternatives)
11152     {
11153     /* Always exactly one alternative. */
11154     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11155     free_stack(common, 1);
11156
11157     alt_max = 2;
11158     alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
11159     }
11160   }
11161 else if (has_alternatives)
11162   {
11163   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11164   free_stack(common, 1);
11165
11166   if (alt_max > 4)
11167     {
11168     /* Table jump if alt_max is greater than 4. */
11169     next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
11170     if (SLJIT_UNLIKELY(next_update_addr == NULL))
11171       return;
11172     sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
11173     add_label_addr(common, next_update_addr++);
11174     }
11175   else
11176     {
11177     if (alt_max == 4)
11178       alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
11179     alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
11180     }
11181   }
11182
11183 COMPILE_BACKTRACKINGPATH(current->top);
11184 if (current->topbacktracks)
11185   set_jumps(current->topbacktracks, LABEL());
11186
11187 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
11188   {
11189   /* Conditional block always has at most one alternative. */
11190   if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
11191     {
11192     SLJIT_ASSERT(has_alternatives);
11193     assert = CURRENT_AS(bracket_backtrack)->u.assert;
11194     if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
11195       {
11196       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
11197       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
11198       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
11199       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));
11200       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);
11201       }
11202     cond = JUMP(SLJIT_JUMP);
11203     set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
11204     }
11205   else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
11206     {
11207     SLJIT_ASSERT(has_alternatives);
11208     cond = JUMP(SLJIT_JUMP);
11209     set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
11210     }
11211   else
11212     SLJIT_ASSERT(!has_alternatives);
11213   }
11214
11215 if (has_alternatives)
11216   {
11217   alt_count = sizeof(sljit_uw);
11218   do
11219     {
11220     current->top = NULL;
11221     current->topbacktracks = NULL;
11222     current->nextbacktracks = NULL;
11223     /* Conditional blocks always have an additional alternative, even if it is empty. */
11224     if (*cc == OP_ALT)
11225       {
11226       ccprev = cc + 1 + LINK_SIZE;
11227       cc += GET(cc, 1);
11228       if (opcode != OP_COND && opcode != OP_SCOND)
11229         {
11230         if (opcode != OP_ONCE)
11231           {
11232           if (private_data_ptr != 0)
11233             OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
11234           else
11235             OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11236           }
11237         else
11238           OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
11239         }
11240       compile_matchingpath(common, ccprev, cc, current);
11241       if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
11242         return;
11243       }
11244
11245     /* Instructions after the current alternative is successfully matched. */
11246     /* There is a similar code in compile_bracket_matchingpath. */
11247     if (opcode == OP_ONCE)
11248       match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
11249
11250     stacksize = 0;
11251     if (repeat_type == OP_MINUPTO)
11252       {
11253       /* We need to preserve the counter. TMP2 will be used below. */
11254       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
11255       stacksize++;
11256       }
11257     if (ket != OP_KET || bra != OP_BRA)
11258       stacksize++;
11259     if (offset != 0)
11260       {
11261       if (common->capture_last_ptr != 0)
11262         stacksize++;
11263       if (common->optimized_cbracket[offset >> 1] == 0)
11264         stacksize += 2;
11265       }
11266     if (opcode != OP_ONCE)
11267       stacksize++;
11268
11269     if (stacksize > 0)
11270       allocate_stack(common, stacksize);
11271
11272     stacksize = 0;
11273     if (repeat_type == OP_MINUPTO)
11274       {
11275       /* TMP2 was set above. */
11276       OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
11277       stacksize++;
11278       }
11279
11280     if (ket != OP_KET || bra != OP_BRA)
11281       {
11282       if (ket != OP_KET)
11283         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
11284       else
11285         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
11286       stacksize++;
11287       }
11288
11289     if (offset != 0)
11290       stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
11291
11292     if (opcode != OP_ONCE)
11293       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
11294
11295     if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
11296       {
11297       /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
11298       SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
11299       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
11300       }
11301
11302     JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
11303
11304     if (opcode != OP_ONCE)
11305       {
11306       if (alt_max > 4)
11307         add_label_addr(common, next_update_addr++);
11308       else
11309         {
11310         if (alt_count != 2 * sizeof(sljit_uw))
11311           {
11312           JUMPHERE(alt1);
11313           if (alt_max == 3 && alt_count == sizeof(sljit_uw))
11314             alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
11315           }
11316         else
11317           {
11318           JUMPHERE(alt2);
11319           if (alt_max == 4)
11320             alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
11321           }
11322         }
11323       alt_count += sizeof(sljit_uw);
11324       }
11325
11326     COMPILE_BACKTRACKINGPATH(current->top);
11327     if (current->topbacktracks)
11328       set_jumps(current->topbacktracks, LABEL());
11329     SLJIT_ASSERT(!current->nextbacktracks);
11330     }
11331   while (*cc == OP_ALT);
11332
11333   if (cond != NULL)
11334     {
11335     SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
11336     assert = CURRENT_AS(bracket_backtrack)->u.assert;
11337     if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
11338       {
11339       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
11340       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
11341       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(-2));
11342       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (assert->framesize - 1) * sizeof(sljit_sw));
11343       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, TMP1, 0);
11344       }
11345     JUMPHERE(cond);
11346     }
11347
11348   /* Free the STR_PTR. */
11349   if (private_data_ptr == 0)
11350     free_stack(common, 1);
11351   }
11352
11353 if (offset != 0)
11354   {
11355   /* Using both tmp register is better for instruction scheduling. */
11356   if (common->optimized_cbracket[offset >> 1] != 0)
11357     {
11358     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11359     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11360     free_stack(common, 2);
11361     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
11362     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
11363     }
11364   else
11365     {
11366     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11367     free_stack(common, 1);
11368     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
11369     }
11370   }
11371 else if (opcode == OP_SBRA || opcode == OP_SCOND)
11372   {
11373   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
11374   free_stack(common, 1);
11375   }
11376 else if (opcode == OP_ONCE)
11377   {
11378   cc = ccbegin + GET(ccbegin, 1);
11379   stacksize = needs_control_head ? 1 : 0;
11380
11381   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
11382     {
11383     /* Reset head and drop saved frame. */
11384     stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
11385     }
11386   else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
11387     {
11388     /* The STR_PTR must be released. */
11389     stacksize++;
11390     }
11391
11392   if (stacksize > 0)
11393     free_stack(common, stacksize);
11394
11395   JUMPHERE(once);
11396   /* Restore previous private_data_ptr */
11397   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
11398     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracket_backtrack)->u.framesize - 1));
11399   else if (ket == OP_KETRMIN)
11400     {
11401     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11402     /* See the comment below. */
11403     free_stack(common, 2);
11404     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
11405     }
11406   }
11407
11408 if (repeat_type == OP_EXACT)
11409   {
11410   OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
11411   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
11412   CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
11413   }
11414 else if (ket == OP_KETRMAX)
11415   {
11416   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11417   if (bra != OP_BRAZERO)
11418     free_stack(common, 1);
11419
11420   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
11421   if (bra == OP_BRAZERO)
11422     {
11423     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11424     JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
11425     JUMPHERE(brazero);
11426     free_stack(common, 1);
11427     }
11428   }
11429 else if (ket == OP_KETRMIN)
11430   {
11431   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11432
11433   /* OP_ONCE removes everything in case of a backtrack, so we don't
11434   need to explicitly release the STR_PTR. The extra release would
11435   affect badly the free_stack(2) above. */
11436   if (opcode != OP_ONCE)
11437     free_stack(common, 1);
11438   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
11439   if (opcode == OP_ONCE)
11440     free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
11441   else if (bra == OP_BRAMINZERO)
11442     free_stack(common, 1);
11443   }
11444 else if (bra == OP_BRAZERO)
11445   {
11446   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11447   JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
11448   JUMPHERE(brazero);
11449   }
11450 }
11451
11452 static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
11453 {
11454 DEFINE_COMPILER;
11455 int offset;
11456 struct sljit_jump *jump;
11457
11458 if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
11459   {
11460   if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
11461     {
11462     offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
11463     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11464     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11465     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
11466     if (common->capture_last_ptr != 0)
11467       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
11468     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
11469     if (common->capture_last_ptr != 0)
11470       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
11471     }
11472   set_jumps(current->topbacktracks, LABEL());
11473   free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
11474   return;
11475   }
11476
11477 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
11478 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
11479 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracketpos_backtrack)->framesize - 1) * sizeof(sljit_sw));
11480
11481 if (current->topbacktracks)
11482   {
11483   jump = JUMP(SLJIT_JUMP);
11484   set_jumps(current->topbacktracks, LABEL());
11485   /* Drop the stack frame. */
11486   free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
11487   JUMPHERE(jump);
11488   }
11489 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(-CURRENT_AS(bracketpos_backtrack)->framesize - 1));
11490 }
11491
11492 static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
11493 {
11494 assert_backtrack backtrack;
11495
11496 current->top = NULL;
11497 current->topbacktracks = NULL;
11498 current->nextbacktracks = NULL;
11499 if (current->cc[1] > OP_ASSERTBACK_NOT)
11500   {
11501   /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
11502   compile_bracket_matchingpath(common, current->cc, current);
11503   compile_bracket_backtrackingpath(common, current->top);
11504   }
11505 else
11506   {
11507   memset(&backtrack, 0, sizeof(backtrack));
11508   backtrack.common.cc = current->cc;
11509   backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
11510   /* Manual call of compile_assert_matchingpath. */
11511   compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
11512   }
11513 SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
11514 }
11515
11516 static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
11517 {
11518 DEFINE_COMPILER;
11519 PCRE2_UCHAR opcode = *current->cc;
11520 struct sljit_label *loop;
11521 struct sljit_jump *jump;
11522
11523 if (opcode == OP_THEN || opcode == OP_THEN_ARG)
11524   {
11525   if (common->then_trap != NULL)
11526     {
11527     SLJIT_ASSERT(common->control_head_ptr != 0);
11528
11529     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
11530     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
11531     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
11532     jump = JUMP(SLJIT_JUMP);
11533
11534     loop = LABEL();
11535     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11536     JUMPHERE(jump);
11537     CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, loop);
11538     CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0, loop);
11539     add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
11540     return;
11541     }
11542   else if (!common->local_quit_available && common->in_positive_assertion)
11543     {
11544     add_jump(compiler, &common->positive_assertion_quit, JUMP(SLJIT_JUMP));
11545     return;
11546     }
11547   }
11548
11549 if (common->local_quit_available)
11550   {
11551   /* Abort match with a fail. */
11552   if (common->quit_label == NULL)
11553     add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
11554   else
11555     JUMPTO(SLJIT_JUMP, common->quit_label);
11556   return;
11557   }
11558
11559 if (opcode == OP_SKIP_ARG)
11560   {
11561   SLJIT_ASSERT(common->control_head_ptr != 0 && TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
11562   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
11563   OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
11564   sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
11565
11566   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0);
11567   add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0));
11568   return;
11569   }
11570
11571 if (opcode == OP_SKIP)
11572   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11573 else
11574   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
11575 add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
11576 }
11577
11578 static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
11579 {
11580 DEFINE_COMPILER;
11581 struct sljit_jump *jump;
11582 int size;
11583
11584 if (CURRENT_AS(then_trap_backtrack)->then_trap)
11585   {
11586   common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
11587   return;
11588   }
11589
11590 size = CURRENT_AS(then_trap_backtrack)->framesize;
11591 size = 3 + (size < 0 ? 0 : size);
11592
11593 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
11594 free_stack(common, size);
11595 jump = JUMP(SLJIT_JUMP);
11596
11597 set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
11598 /* STACK_TOP is set by THEN. */
11599 if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
11600   {
11601   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
11602   OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(then_trap_backtrack)->framesize - 1) * sizeof(sljit_sw));
11603   }
11604 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11605 free_stack(common, 3);
11606
11607 JUMPHERE(jump);
11608 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
11609 }
11610
11611 static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
11612 {
11613 DEFINE_COMPILER;
11614 then_trap_backtrack *save_then_trap = common->then_trap;
11615
11616 while (current)
11617   {
11618   if (current->nextbacktracks != NULL)
11619     set_jumps(current->nextbacktracks, LABEL());
11620   switch(*current->cc)
11621     {
11622     case OP_SET_SOM:
11623     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11624     free_stack(common, 1);
11625     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);
11626     break;
11627
11628     case OP_STAR:
11629     case OP_MINSTAR:
11630     case OP_PLUS:
11631     case OP_MINPLUS:
11632     case OP_QUERY:
11633     case OP_MINQUERY:
11634     case OP_UPTO:
11635     case OP_MINUPTO:
11636     case OP_EXACT:
11637     case OP_POSSTAR:
11638     case OP_POSPLUS:
11639     case OP_POSQUERY:
11640     case OP_POSUPTO:
11641     case OP_STARI:
11642     case OP_MINSTARI:
11643     case OP_PLUSI:
11644     case OP_MINPLUSI:
11645     case OP_QUERYI:
11646     case OP_MINQUERYI:
11647     case OP_UPTOI:
11648     case OP_MINUPTOI:
11649     case OP_EXACTI:
11650     case OP_POSSTARI:
11651     case OP_POSPLUSI:
11652     case OP_POSQUERYI:
11653     case OP_POSUPTOI:
11654     case OP_NOTSTAR:
11655     case OP_NOTMINSTAR:
11656     case OP_NOTPLUS:
11657     case OP_NOTMINPLUS:
11658     case OP_NOTQUERY:
11659     case OP_NOTMINQUERY:
11660     case OP_NOTUPTO:
11661     case OP_NOTMINUPTO:
11662     case OP_NOTEXACT:
11663     case OP_NOTPOSSTAR:
11664     case OP_NOTPOSPLUS:
11665     case OP_NOTPOSQUERY:
11666     case OP_NOTPOSUPTO:
11667     case OP_NOTSTARI:
11668     case OP_NOTMINSTARI:
11669     case OP_NOTPLUSI:
11670     case OP_NOTMINPLUSI:
11671     case OP_NOTQUERYI:
11672     case OP_NOTMINQUERYI:
11673     case OP_NOTUPTOI:
11674     case OP_NOTMINUPTOI:
11675     case OP_NOTEXACTI:
11676     case OP_NOTPOSSTARI:
11677     case OP_NOTPOSPLUSI:
11678     case OP_NOTPOSQUERYI:
11679     case OP_NOTPOSUPTOI:
11680     case OP_TYPESTAR:
11681     case OP_TYPEMINSTAR:
11682     case OP_TYPEPLUS:
11683     case OP_TYPEMINPLUS:
11684     case OP_TYPEQUERY:
11685     case OP_TYPEMINQUERY:
11686     case OP_TYPEUPTO:
11687     case OP_TYPEMINUPTO:
11688     case OP_TYPEEXACT:
11689     case OP_TYPEPOSSTAR:
11690     case OP_TYPEPOSPLUS:
11691     case OP_TYPEPOSQUERY:
11692     case OP_TYPEPOSUPTO:
11693     case OP_CLASS:
11694     case OP_NCLASS:
11695 #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
11696     case OP_XCLASS:
11697 #endif
11698     compile_iterator_backtrackingpath(common, current);
11699     break;
11700
11701     case OP_REF:
11702     case OP_REFI:
11703     case OP_DNREF:
11704     case OP_DNREFI:
11705     compile_ref_iterator_backtrackingpath(common, current);
11706     break;
11707
11708     case OP_RECURSE:
11709     compile_recurse_backtrackingpath(common, current);
11710     break;
11711
11712     case OP_ASSERT:
11713     case OP_ASSERT_NOT:
11714     case OP_ASSERTBACK:
11715     case OP_ASSERTBACK_NOT:
11716     compile_assert_backtrackingpath(common, current);
11717     break;
11718
11719     case OP_ONCE:
11720     case OP_BRA:
11721     case OP_CBRA:
11722     case OP_COND:
11723     case OP_SBRA:
11724     case OP_SCBRA:
11725     case OP_SCOND:
11726     compile_bracket_backtrackingpath(common, current);
11727     break;
11728
11729     case OP_BRAZERO:
11730     if (current->cc[1] > OP_ASSERTBACK_NOT)
11731       compile_bracket_backtrackingpath(common, current);
11732     else
11733       compile_assert_backtrackingpath(common, current);
11734     break;
11735
11736     case OP_BRAPOS:
11737     case OP_CBRAPOS:
11738     case OP_SBRAPOS:
11739     case OP_SCBRAPOS:
11740     case OP_BRAPOSZERO:
11741     compile_bracketpos_backtrackingpath(common, current);
11742     break;
11743
11744     case OP_BRAMINZERO:
11745     compile_braminzero_backtrackingpath(common, current);
11746     break;
11747
11748     case OP_MARK:
11749     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
11750     if (common->has_skip_arg)
11751       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11752     free_stack(common, common->has_skip_arg ? 5 : 1);
11753     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
11754     if (common->has_skip_arg)
11755       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
11756     break;
11757
11758     case OP_THEN:
11759     case OP_THEN_ARG:
11760     case OP_PRUNE:
11761     case OP_PRUNE_ARG:
11762     case OP_SKIP:
11763     case OP_SKIP_ARG:
11764     compile_control_verb_backtrackingpath(common, current);
11765     break;
11766
11767     case OP_COMMIT:
11768     case OP_COMMIT_ARG:
11769     if (!common->local_quit_available)
11770       OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
11771     if (common->quit_label == NULL)
11772       add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
11773     else
11774       JUMPTO(SLJIT_JUMP, common->quit_label);
11775     break;
11776
11777     case OP_CALLOUT:
11778     case OP_CALLOUT_STR:
11779     case OP_FAIL:
11780     case OP_ACCEPT:
11781     case OP_ASSERT_ACCEPT:
11782     set_jumps(current->topbacktracks, LABEL());
11783     break;
11784
11785     case OP_THEN_TRAP:
11786     /* A virtual opcode for then traps. */
11787     compile_then_trap_backtrackingpath(common, current);
11788     break;
11789
11790     default:
11791     SLJIT_UNREACHABLE();
11792     break;
11793     }
11794   current = current->prev;
11795   }
11796 common->then_trap = save_then_trap;
11797 }
11798
11799 static SLJIT_INLINE void compile_recurse(compiler_common *common)
11800 {
11801 DEFINE_COMPILER;
11802 PCRE2_SPTR cc = common->start + common->currententry->start;
11803 PCRE2_SPTR ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
11804 PCRE2_SPTR ccend = bracketend(cc) - (1 + LINK_SIZE);
11805 BOOL needs_control_head;
11806 BOOL has_quit;
11807 BOOL has_accept;
11808 int private_data_size = get_recurse_data_length(common, ccbegin, ccend, &needs_control_head, &has_quit, &has_accept);
11809 int alt_count, alt_max, local_size;
11810 backtrack_common altbacktrack;
11811 jump_list *match = NULL;
11812 sljit_uw *next_update_addr = NULL;
11813 struct sljit_jump *alt1 = NULL;
11814 struct sljit_jump *alt2 = NULL;
11815 struct sljit_jump *accept_exit = NULL;
11816 struct sljit_label *quit;
11817
11818 /* Recurse captures then. */
11819 common->then_trap = NULL;
11820
11821 SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
11822
11823 alt_max = no_alternatives(cc);
11824 alt_count = 0;
11825
11826 /* Matching path. */
11827 SLJIT_ASSERT(common->currententry->entry_label == NULL && common->recursive_head_ptr != 0);
11828 common->currententry->entry_label = LABEL();
11829 set_jumps(common->currententry->entry_calls, common->currententry->entry_label);
11830
11831 sljit_emit_fast_enter(compiler, TMP2, 0);
11832 count_match(common);
11833
11834 local_size = (alt_max > 1) ? 2 : 1;
11835
11836 /* (Reversed) stack layout:
11837    [private data][return address][optional: str ptr] ... [optional: alternative index][recursive_head_ptr] */
11838
11839 allocate_stack(common, private_data_size + local_size);
11840 /* Save return address. */
11841 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP2, 0);
11842
11843 copy_recurse_data(common, ccbegin, ccend, recurse_copy_from_global, local_size, private_data_size + local_size, has_quit);
11844
11845 /* This variable is saved and restored all time when we enter or exit from a recursive context. */
11846 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
11847
11848 if (needs_control_head)
11849   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
11850
11851 if (alt_max > 1)
11852   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
11853
11854 memset(&altbacktrack, 0, sizeof(backtrack_common));
11855 common->quit_label = NULL;
11856 common->accept_label = NULL;
11857 common->quit = NULL;
11858 common->accept = NULL;
11859 altbacktrack.cc = ccbegin;
11860 cc += GET(cc, 1);
11861 while (1)
11862   {
11863   altbacktrack.top = NULL;
11864   altbacktrack.topbacktracks = NULL;
11865
11866   if (altbacktrack.cc != ccbegin)
11867     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11868
11869   compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
11870   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
11871     return;
11872
11873   allocate_stack(common, (alt_max > 1 || has_accept) ? 2 : 1);
11874   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
11875
11876   if (alt_max > 1 || has_accept)
11877     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
11878
11879   add_jump(compiler, &match, JUMP(SLJIT_JUMP));
11880
11881   if (alt_count == 0)
11882     {
11883     /* Backtracking path entry. */
11884     SLJIT_ASSERT(common->currententry->backtrack_label == NULL);
11885     common->currententry->backtrack_label = LABEL();
11886     set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label);
11887
11888     sljit_emit_fast_enter(compiler, TMP1, 0);
11889
11890     if (has_accept)
11891       accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_max * sizeof (sljit_sw));
11892
11893     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
11894     /* Save return address. */
11895     OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), STACK(local_size - 1), TMP1, 0);
11896
11897     copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, has_quit);
11898
11899     if (alt_max > 1)
11900       {
11901       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
11902       free_stack(common, 2);
11903
11904       if (alt_max > 4)
11905         {
11906           /* Table jump if alt_max is greater than 4. */
11907           next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
11908           if (SLJIT_UNLIKELY(next_update_addr == NULL))
11909             return;
11910           sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
11911           add_label_addr(common, next_update_addr++);
11912         }
11913       else
11914         {
11915         if (alt_max == 4)
11916           alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
11917         alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
11918         }
11919       }
11920     else
11921       free_stack(common, has_accept ? 2 : 1);
11922     }
11923   else if (alt_max > 4)
11924     add_label_addr(common, next_update_addr++);
11925   else
11926     {
11927     if (alt_count != 2 * sizeof(sljit_uw))
11928       {
11929       JUMPHERE(alt1);
11930       if (alt_max == 3 && alt_count == sizeof(sljit_uw))
11931         alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
11932       }
11933     else
11934       {
11935       JUMPHERE(alt2);
11936       if (alt_max == 4)
11937         alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
11938       }
11939     }
11940
11941   alt_count += sizeof(sljit_uw);
11942
11943   compile_backtrackingpath(common, altbacktrack.top);
11944   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
11945     return;
11946   set_jumps(altbacktrack.topbacktracks, LABEL());
11947
11948   if (*cc != OP_ALT)
11949     break;
11950
11951   altbacktrack.cc = cc + 1 + LINK_SIZE;
11952   cc += GET(cc, 1);
11953   }
11954
11955 /* No alternative is matched. */
11956
11957 quit = LABEL();
11958
11959 copy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_size, private_data_size + local_size, has_quit);
11960
11961 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
11962 free_stack(common, private_data_size + local_size);
11963 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
11964 sljit_emit_fast_return(compiler, TMP2, 0);
11965
11966 if (common->quit != NULL)
11967   {
11968   SLJIT_ASSERT(has_quit);
11969
11970   set_jumps(common->quit, LABEL());
11971   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
11972   copy_recurse_data(common, ccbegin, ccend, recurse_copy_shared_to_global, local_size, private_data_size + local_size, has_quit);
11973   JUMPTO(SLJIT_JUMP, quit);
11974   }
11975
11976 if (has_accept)
11977   {
11978   JUMPHERE(accept_exit);
11979   free_stack(common, 2);
11980
11981   /* Save return address. */
11982   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1), TMP1, 0);
11983
11984   copy_recurse_data(common, ccbegin, ccend, recurse_copy_kept_shared_to_global, local_size, private_data_size + local_size, has_quit);
11985
11986   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(local_size - 1));
11987   free_stack(common, private_data_size + local_size);
11988   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
11989   sljit_emit_fast_return(compiler, TMP2, 0);
11990   }
11991
11992 if (common->accept != NULL)
11993   {
11994   SLJIT_ASSERT(has_accept);
11995
11996   set_jumps(common->accept, LABEL());
11997
11998   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
11999   OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0);
12000
12001   allocate_stack(common, 2);
12002   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
12003   }
12004
12005 set_jumps(match, LABEL());
12006
12007 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
12008
12009 copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, has_quit);
12010
12011 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), STACK(local_size - 1));
12012 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 1);
12013 sljit_emit_fast_return(compiler, TMP2, 0);
12014 }
12015
12016 #undef COMPILE_BACKTRACKINGPATH
12017 #undef CURRENT_AS
12018
12019 static int jit_compile(pcre2_code *code, sljit_u32 mode)
12020 {
12021 pcre2_real_code *re = (pcre2_real_code *)code;
12022 struct sljit_compiler *compiler;
12023 backtrack_common rootbacktrack;
12024 compiler_common common_data;
12025 compiler_common *common = &common_data;
12026 const sljit_u8 *tables = re->tables;
12027 void *allocator_data = &re->memctl;
12028 int private_data_size;
12029 PCRE2_SPTR ccend;
12030 executable_functions *functions;
12031 void *executable_func;
12032 sljit_uw executable_size;
12033 sljit_uw total_length;
12034 label_addr_list *label_addr;
12035 struct sljit_label *mainloop_label = NULL;
12036 struct sljit_label *continue_match_label;
12037 struct sljit_label *empty_match_found_label = NULL;
12038 struct sljit_label *empty_match_backtrack_label = NULL;
12039 struct sljit_label *reset_match_label;
12040 struct sljit_label *quit_label;
12041 struct sljit_jump *jump;
12042 struct sljit_jump *minlength_check_failed = NULL;
12043 struct sljit_jump *reqbyte_notfound = NULL;
12044 struct sljit_jump *empty_match = NULL;
12045 struct sljit_jump *end_anchor_failed = NULL;
12046
12047 SLJIT_ASSERT(tables);
12048
12049 memset(&rootbacktrack, 0, sizeof(backtrack_common));
12050 memset(common, 0, sizeof(compiler_common));
12051 common->re = re;
12052 common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code));
12053 rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size;
12054
12055 common->start = rootbacktrack.cc;
12056 common->read_only_data_head = NULL;
12057 common->fcc = tables + fcc_offset;
12058 common->lcc = (sljit_sw)(tables + lcc_offset);
12059 common->mode = mode;
12060 common->might_be_empty = re->minlength == 0;
12061 common->nltype = NLTYPE_FIXED;
12062 switch(re->newline_convention)
12063   {
12064   case PCRE2_NEWLINE_CR: common->newline = CHAR_CR; break;
12065   case PCRE2_NEWLINE_LF: common->newline = CHAR_NL; break;
12066   case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
12067   case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
12068   case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
12069   default: return PCRE2_ERROR_INTERNAL;
12070   }
12071 common->nlmax = READ_CHAR_MAX;
12072 common->nlmin = 0;
12073 if (re->bsr_convention == PCRE2_BSR_UNICODE)
12074   common->bsr_nltype = NLTYPE_ANY;
12075 else if (re->bsr_convention == PCRE2_BSR_ANYCRLF)
12076   common->bsr_nltype = NLTYPE_ANYCRLF;
12077 else
12078   {
12079 #ifdef BSR_ANYCRLF
12080   common->bsr_nltype = NLTYPE_ANYCRLF;
12081 #else
12082   common->bsr_nltype = NLTYPE_ANY;
12083 #endif
12084   }
12085 common->bsr_nlmax = READ_CHAR_MAX;
12086 common->bsr_nlmin = 0;
12087 common->endonly = (re->overall_options & PCRE2_DOLLAR_ENDONLY) != 0;
12088 common->ctypes = (sljit_sw)(tables + ctypes_offset);
12089 common->name_count = re->name_count;
12090 common->name_entry_size = re->name_entry_size;
12091 common->unset_backref = (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) != 0;
12092 common->alt_circumflex = (re->overall_options & PCRE2_ALT_CIRCUMFLEX) != 0;
12093 #ifdef SUPPORT_UNICODE
12094 /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
12095 common->utf = (re->overall_options & PCRE2_UTF) != 0;
12096 common->use_ucp = (re->overall_options & PCRE2_UCP) != 0;
12097 if (common->utf)
12098   {
12099   if (common->nltype == NLTYPE_ANY)
12100     common->nlmax = 0x2029;
12101   else if (common->nltype == NLTYPE_ANYCRLF)
12102     common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
12103   else
12104     {
12105     /* We only care about the first newline character. */
12106     common->nlmax = common->newline & 0xff;
12107     }
12108
12109   if (common->nltype == NLTYPE_FIXED)
12110     common->nlmin = common->newline & 0xff;
12111   else
12112     common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
12113
12114   if (common->bsr_nltype == NLTYPE_ANY)
12115     common->bsr_nlmax = 0x2029;
12116   else
12117     common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
12118   common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
12119   }
12120 #endif /* SUPPORT_UNICODE */
12121 ccend = bracketend(common->start);
12122
12123 /* Calculate the local space size on the stack. */
12124 common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
12125 common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, allocator_data);
12126 if (!common->optimized_cbracket)
12127   return PCRE2_ERROR_NOMEMORY;
12128 #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
12129 memset(common->optimized_cbracket, 0, re->top_bracket + 1);
12130 #else
12131 memset(common->optimized_cbracket, 1, re->top_bracket + 1);
12132 #endif
12133
12134 SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
12135 #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
12136 common->capture_last_ptr = common->ovector_start;
12137 common->ovector_start += sizeof(sljit_sw);
12138 #endif
12139 if (!check_opcode_types(common, common->start, ccend))
12140   {
12141   SLJIT_FREE(common->optimized_cbracket, allocator_data);
12142   return PCRE2_ERROR_NOMEMORY;
12143   }
12144
12145 /* Checking flags and updating ovector_start. */
12146 if (mode == PCRE2_JIT_COMPLETE && (re->flags & PCRE2_LASTSET) != 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
12147   {
12148   common->req_char_ptr = common->ovector_start;
12149   common->ovector_start += sizeof(sljit_sw);
12150   }
12151 if (mode != PCRE2_JIT_COMPLETE)
12152   {
12153   common->start_used_ptr = common->ovector_start;
12154   common->ovector_start += sizeof(sljit_sw);
12155   if (mode == PCRE2_JIT_PARTIAL_SOFT)
12156     {
12157     common->hit_start = common->ovector_start;
12158     common->ovector_start += sizeof(sljit_sw);
12159     }
12160   }
12161 if ((re->overall_options & (PCRE2_FIRSTLINE | PCRE2_USE_OFFSET_LIMIT)) != 0)
12162   {
12163   common->match_end_ptr = common->ovector_start;
12164   common->ovector_start += sizeof(sljit_sw);
12165   }
12166 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
12167 common->control_head_ptr = 1;
12168 #endif
12169 if (common->control_head_ptr != 0)
12170   {
12171   common->control_head_ptr = common->ovector_start;
12172   common->ovector_start += sizeof(sljit_sw);
12173   }
12174 if (common->has_set_som)
12175   {
12176   /* Saving the real start pointer is necessary. */
12177   common->start_ptr = common->ovector_start;
12178   common->ovector_start += sizeof(sljit_sw);
12179   }
12180
12181 /* Aligning ovector to even number of sljit words. */
12182 if ((common->ovector_start & sizeof(sljit_sw)) != 0)
12183   common->ovector_start += sizeof(sljit_sw);
12184
12185 if (common->start_ptr == 0)
12186   common->start_ptr = OVECTOR(0);
12187
12188 /* Capturing brackets cannot be optimized if callouts are allowed. */
12189 if (common->capture_last_ptr != 0)
12190   memset(common->optimized_cbracket, 0, re->top_bracket + 1);
12191
12192 SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
12193 common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
12194
12195 total_length = ccend - common->start;
12196 common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), allocator_data);
12197 if (!common->private_data_ptrs)
12198   {
12199   SLJIT_FREE(common->optimized_cbracket, allocator_data);
12200   return PCRE2_ERROR_NOMEMORY;
12201   }
12202 memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));
12203
12204 private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
12205 set_private_data_ptrs(common, &private_data_size, ccend);
12206 if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
12207   {
12208   if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back)
12209     detect_fast_fail(common, common->start, &private_data_size, 4);
12210   }
12211
12212 SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr);
12213
12214 if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
12215   {
12216   SLJIT_FREE(common->private_data_ptrs, allocator_data);
12217   SLJIT_FREE(common->optimized_cbracket, allocator_data);
12218   return PCRE2_ERROR_NOMEMORY;
12219   }
12220
12221 if (common->has_then)
12222   {
12223   common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length);
12224   memset(common->then_offsets, 0, total_length);
12225   set_then_offsets(common, common->start, NULL);
12226   }
12227
12228 compiler = sljit_create_compiler(allocator_data);
12229 if (!compiler)
12230   {
12231   SLJIT_FREE(common->optimized_cbracket, allocator_data);
12232   SLJIT_FREE(common->private_data_ptrs, allocator_data);
12233   return PCRE2_ERROR_NOMEMORY;
12234   }
12235 common->compiler = compiler;
12236
12237 /* Main pcre_jit_exec entry. */
12238 sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
12239
12240 /* Register init. */
12241 reset_ovector(common, (re->top_bracket + 1) * 2);
12242 if (common->req_char_ptr != 0)
12243   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);
12244
12245 OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);
12246 OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);
12247 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
12248 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
12249 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
12250 OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
12251 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
12252 OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
12253 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
12254 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
12255
12256 if (common->fast_fail_start_ptr < common->fast_fail_end_ptr)
12257   reset_fast_fail(common);
12258
12259 if (mode == PCRE2_JIT_PARTIAL_SOFT)
12260   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
12261 if (common->mark_ptr != 0)
12262   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
12263 if (common->control_head_ptr != 0)
12264   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
12265
12266 /* Main part of the matching */
12267 if ((re->overall_options & PCRE2_ANCHORED) == 0)
12268   {
12269   mainloop_label = mainloop_entry(common);
12270   continue_match_label = LABEL();
12271   /* Forward search if possible. */
12272   if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
12273     {
12274     if (mode == PCRE2_JIT_COMPLETE && fast_forward_first_n_chars(common))
12275       ;
12276     else if ((re->flags & PCRE2_FIRSTSET) != 0)
12277       fast_forward_first_char(common);
12278     else if ((re->flags & PCRE2_STARTLINE) != 0)
12279       fast_forward_newline(common);
12280     else if ((re->flags & PCRE2_FIRSTMAPSET) != 0)
12281       fast_forward_start_bits(common);
12282     }
12283   }
12284 else
12285   continue_match_label = LABEL();
12286
12287 if (mode == PCRE2_JIT_COMPLETE && re->minlength > 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
12288   {
12289   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
12290   OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(re->minlength));
12291   minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);
12292   }
12293 if (common->req_char_ptr != 0)
12294   reqbyte_notfound = search_requested_char(common, (PCRE2_UCHAR)(re->last_codeunit), (re->flags & PCRE2_LASTCASELESS) != 0, (re->flags & PCRE2_FIRSTSET) != 0);
12295
12296 /* Store the current STR_PTR in OVECTOR(0). */
12297 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
12298 /* Copy the limit of allowed recursions. */
12299 OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);
12300 if (common->capture_last_ptr != 0)
12301   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, 0);
12302 if (common->fast_forward_bc_ptr != NULL)
12303   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0);
12304
12305 if (common->start_ptr != OVECTOR(0))
12306   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);
12307
12308 /* Copy the beginning of the string. */
12309 if (mode == PCRE2_JIT_PARTIAL_SOFT)
12310   {
12311   jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
12312   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
12313   JUMPHERE(jump);
12314   }
12315 else if (mode == PCRE2_JIT_PARTIAL_HARD)
12316   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
12317
12318 compile_matchingpath(common, common->start, ccend, &rootbacktrack);
12319 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
12320   {
12321   sljit_free_compiler(compiler);
12322   SLJIT_FREE(common->optimized_cbracket, allocator_data);
12323   SLJIT_FREE(common->private_data_ptrs, allocator_data);
12324   PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
12325   return PCRE2_ERROR_NOMEMORY;
12326   }
12327
12328 if ((re->overall_options & PCRE2_ENDANCHORED) != 0)
12329   end_anchor_failed = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0);
12330
12331 if (common->might_be_empty)
12332   {
12333   empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
12334   empty_match_found_label = LABEL();
12335   }
12336
12337 common->accept_label = LABEL();
12338 if (common->accept != NULL)
12339   set_jumps(common->accept, common->accept_label);
12340
12341 /* This means we have a match. Update the ovector. */
12342 copy_ovector(common, re->top_bracket + 1);
12343 common->quit_label = common->abort_label = LABEL();
12344 if (common->quit != NULL)
12345   set_jumps(common->quit, common->quit_label);
12346 if (common->abort != NULL)
12347   set_jumps(common->abort, common->abort_label);
12348 if (minlength_check_failed != NULL)
12349   SET_LABEL(minlength_check_failed, common->abort_label);
12350 sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
12351
12352 if (common->failed_match != NULL)
12353   {
12354   SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
12355   set_jumps(common->failed_match, LABEL());
12356   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
12357   JUMPTO(SLJIT_JUMP, common->abort_label);
12358   }
12359
12360 if ((re->overall_options & PCRE2_ENDANCHORED) != 0)
12361   JUMPHERE(end_anchor_failed);
12362
12363 if (mode != PCRE2_JIT_COMPLETE)
12364   {
12365   common->partialmatchlabel = LABEL();
12366   set_jumps(common->partialmatch, common->partialmatchlabel);
12367   return_with_partial_match(common, common->quit_label);
12368   }
12369
12370 if (common->might_be_empty)
12371   empty_match_backtrack_label = LABEL();
12372 compile_backtrackingpath(common, rootbacktrack.top);
12373 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
12374   {
12375   sljit_free_compiler(compiler);
12376   SLJIT_FREE(common->optimized_cbracket, allocator_data);
12377   SLJIT_FREE(common->private_data_ptrs, allocator_data);
12378   PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
12379   return PCRE2_ERROR_NOMEMORY;
12380   }
12381
12382 SLJIT_ASSERT(rootbacktrack.prev == NULL);
12383 reset_match_label = LABEL();
12384
12385 if (mode == PCRE2_JIT_PARTIAL_SOFT)
12386   {
12387   /* Update hit_start only in the first time. */
12388   jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
12389   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
12390   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
12391   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);
12392   JUMPHERE(jump);
12393   }
12394
12395 /* Check we have remaining characters. */
12396 if ((re->overall_options & PCRE2_ANCHORED) == 0 && common->match_end_ptr != 0)
12397   {
12398   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
12399   }
12400
12401 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),
12402     (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr);
12403
12404 if ((re->overall_options & PCRE2_ANCHORED) == 0)
12405   {
12406   if (common->ff_newline_shortcut != NULL)
12407     {
12408     /* There cannot be more newlines if PCRE2_FIRSTLINE is set. */
12409     if ((re->overall_options & PCRE2_FIRSTLINE) == 0)
12410       {
12411       if (common->match_end_ptr != 0)
12412         {
12413         OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
12414         OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
12415         CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut);
12416         OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
12417         }
12418       else
12419         CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
12420       }
12421     }
12422   else
12423     CMPTO(SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label);
12424   }
12425
12426 /* No more remaining characters. */
12427 if (reqbyte_notfound != NULL)
12428   JUMPHERE(reqbyte_notfound);
12429
12430 if (mode == PCRE2_JIT_PARTIAL_SOFT)
12431   CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
12432
12433 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH);
12434 JUMPTO(SLJIT_JUMP, common->quit_label);
12435
12436 flush_stubs(common);
12437
12438 if (common->might_be_empty)
12439   {
12440   JUMPHERE(empty_match);
12441   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
12442   OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
12443   OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
12444   JUMPTO(SLJIT_NOT_ZERO, empty_match_backtrack_label);
12445   OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
12446   JUMPTO(SLJIT_ZERO, empty_match_found_label);
12447   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
12448   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
12449   JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
12450   }
12451
12452 common->fast_forward_bc_ptr = NULL;
12453 common->fast_fail_start_ptr = 0;
12454 common->fast_fail_end_ptr = 0;
12455 common->currententry = common->entries;
12456 common->local_quit_available = TRUE;
12457 quit_label = common->quit_label;
12458 while (common->currententry != NULL)
12459   {
12460   /* Might add new entries. */
12461   compile_recurse(common);
12462   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
12463     {
12464     sljit_free_compiler(compiler);
12465     SLJIT_FREE(common->optimized_cbracket, allocator_data);
12466     SLJIT_FREE(common->private_data_ptrs, allocator_data);
12467     PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
12468     return PCRE2_ERROR_NOMEMORY;
12469     }
12470   flush_stubs(common);
12471   common->currententry = common->currententry->next;
12472   }
12473 common->local_quit_available = FALSE;
12474 common->quit_label = quit_label;
12475
12476 /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
12477 /* This is a (really) rare case. */
12478 set_jumps(common->stackalloc, LABEL());
12479 /* RETURN_ADDR is not a saved register. */
12480 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
12481
12482 SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
12483
12484 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
12485 OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
12486 OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
12487 OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
12488 OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
12489
12490 sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
12491
12492 jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
12493 OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
12494 OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
12495 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
12496 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
12497 sljit_emit_fast_return(compiler, TMP1, 0);
12498
12499 /* Allocation failed. */
12500 JUMPHERE(jump);
12501 /* We break the return address cache here, but this is a really rare case. */
12502 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_JIT_STACKLIMIT);
12503 JUMPTO(SLJIT_JUMP, common->quit_label);
12504
12505 /* Call limit reached. */
12506 set_jumps(common->calllimit, LABEL());
12507 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_MATCHLIMIT);
12508 JUMPTO(SLJIT_JUMP, common->quit_label);
12509
12510 if (common->revertframes != NULL)
12511   {
12512   set_jumps(common->revertframes, LABEL());
12513   do_revertframes(common);
12514   }
12515 if (common->wordboundary != NULL)
12516   {
12517   set_jumps(common->wordboundary, LABEL());
12518   check_wordboundary(common);
12519   }
12520 if (common->anynewline != NULL)
12521   {
12522   set_jumps(common->anynewline, LABEL());
12523   check_anynewline(common);
12524   }
12525 if (common->hspace != NULL)
12526   {
12527   set_jumps(common->hspace, LABEL());
12528   check_hspace(common);
12529   }
12530 if (common->vspace != NULL)
12531   {
12532   set_jumps(common->vspace, LABEL());
12533   check_vspace(common);
12534   }
12535 if (common->casefulcmp != NULL)
12536   {
12537   set_jumps(common->casefulcmp, LABEL());
12538   do_casefulcmp(common);
12539   }
12540 if (common->caselesscmp != NULL)
12541   {
12542   set_jumps(common->caselesscmp, LABEL());
12543   do_caselesscmp(common);
12544   }
12545 if (common->reset_match != NULL)
12546   {
12547   set_jumps(common->reset_match, LABEL());
12548   do_reset_match(common, (re->top_bracket + 1) * 2);
12549   CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
12550   OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
12551   JUMPTO(SLJIT_JUMP, reset_match_label);
12552   }
12553 #ifdef SUPPORT_UNICODE
12554 #if PCRE2_CODE_UNIT_WIDTH == 8
12555 if (common->utfreadchar != NULL)
12556   {
12557   set_jumps(common->utfreadchar, LABEL());
12558   do_utfreadchar(common);
12559   }
12560 if (common->utfreadchar16 != NULL)
12561   {
12562   set_jumps(common->utfreadchar16, LABEL());
12563   do_utfreadchar16(common);
12564   }
12565 if (common->utfreadtype8 != NULL)
12566   {
12567   set_jumps(common->utfreadtype8, LABEL());
12568   do_utfreadtype8(common);
12569   }
12570 #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
12571 if (common->getucd != NULL)
12572   {
12573   set_jumps(common->getucd, LABEL());
12574   do_getucd(common);
12575   }
12576 #endif /* SUPPORT_UNICODE */
12577
12578 SLJIT_FREE(common->optimized_cbracket, allocator_data);
12579 SLJIT_FREE(common->private_data_ptrs, allocator_data);
12580
12581 executable_func = sljit_generate_code(compiler);
12582 executable_size = sljit_get_generated_code_size(compiler);
12583 label_addr = common->label_addrs;
12584 while (label_addr != NULL)
12585   {
12586   *label_addr->update_addr = sljit_get_label_addr(label_addr->label);
12587   label_addr = label_addr->next;
12588   }
12589 sljit_free_compiler(compiler);
12590 if (executable_func == NULL)
12591   {
12592   PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
12593   return PCRE2_ERROR_NOMEMORY;
12594   }
12595
12596 /* Reuse the function descriptor if possible. */
12597 if (re->executable_jit != NULL)
12598   functions = (executable_functions *)re->executable_jit;
12599 else
12600   {
12601   functions = SLJIT_MALLOC(sizeof(executable_functions), allocator_data);
12602   if (functions == NULL)
12603     {
12604     /* This case is highly unlikely since we just recently
12605     freed a lot of memory. Not impossible though. */
12606     sljit_free_code(executable_func);
12607     PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
12608     return PCRE2_ERROR_NOMEMORY;
12609     }
12610   memset(functions, 0, sizeof(executable_functions));
12611   functions->top_bracket = re->top_bracket + 1;
12612   functions->limit_match = re->limit_match;
12613   re->executable_jit = functions;
12614   }
12615
12616 /* Turn mode into an index. */
12617 if (mode == PCRE2_JIT_COMPLETE)
12618   mode = 0;
12619 else
12620   mode = (mode == PCRE2_JIT_PARTIAL_SOFT) ? 1 : 2;
12621
12622 SLJIT_ASSERT(mode < JIT_NUMBER_OF_COMPILE_MODES);
12623 functions->executable_funcs[mode] = executable_func;
12624 functions->read_only_data_heads[mode] = common->read_only_data_head;
12625 functions->executable_sizes[mode] = executable_size;
12626 return 0;
12627 }
12628
12629 #endif
12630
12631 /*************************************************
12632 *        JIT compile a Regular Expression        *
12633 *************************************************/
12634
12635 /* This function used JIT to convert a previously-compiled pattern into machine
12636 code.
12637
12638 Arguments:
12639   code          a compiled pattern
12640   options       JIT option bits
12641
12642 Returns:        0: success or (*NOJIT) was used
12643                <0: an error code
12644 */
12645
12646 #define PUBLIC_JIT_COMPILE_OPTIONS \
12647   (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD)
12648
12649 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
12650 pcre2_jit_compile(pcre2_code *code, uint32_t options)
12651 {
12652 #ifndef SUPPORT_JIT
12653
12654 (void)code;
12655 (void)options;
12656 return PCRE2_ERROR_JIT_BADOPTION;
12657
12658 #else  /* SUPPORT_JIT */
12659
12660 pcre2_real_code *re = (pcre2_real_code *)code;
12661 executable_functions *functions;
12662 int result;
12663
12664 if (code == NULL)
12665   return PCRE2_ERROR_NULL;
12666
12667 if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0)
12668   return PCRE2_ERROR_JIT_BADOPTION;
12669
12670 if ((re->flags & PCRE2_NOJIT) != 0) return 0;
12671
12672 functions = (executable_functions *)re->executable_jit;
12673
12674 if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL
12675     || functions->executable_funcs[0] == NULL)) {
12676   result = jit_compile(code, PCRE2_JIT_COMPLETE);
12677   if (result != 0)
12678     return result;
12679   }
12680
12681 if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL
12682     || functions->executable_funcs[1] == NULL)) {
12683   result = jit_compile(code, PCRE2_JIT_PARTIAL_SOFT);
12684   if (result != 0)
12685     return result;
12686   }
12687
12688 if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL
12689     || functions->executable_funcs[2] == NULL)) {
12690   result = jit_compile(code, PCRE2_JIT_PARTIAL_HARD);
12691   if (result != 0)
12692     return result;
12693   }
12694
12695 return 0;
12696
12697 #endif  /* SUPPORT_JIT */
12698 }
12699
12700 /* JIT compiler uses an all-in-one approach. This improves security,
12701    since the code generator functions are not exported. */
12702
12703 #define INCLUDED_FROM_PCRE2_JIT_COMPILE
12704
12705 #include "pcre2_jit_match.c"
12706 #include "pcre2_jit_misc.c"
12707
12708 /* End of pcre2_jit_compile.c */