1 /*************************************************
2 * Perl-Compatible Regular Expressions *
3 *************************************************/
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.
8 Written by Philip Hazel
9 Copyright (c) 1997-2013 University of Cambridge
11 The machine code generator part (this module) was written by Zoltan Herczeg
12 Copyright (c) 2010-2013
14 -----------------------------------------------------------------------------
15 Redistribution and use in source and binary forms, with or without
16 modification, are permitted provided that the following conditions are met:
18 * Redistributions of source code must retain the above copyright notice,
19 this list of conditions and the following disclaimer.
21 * Redistributions in binary form must reproduce the above copyright
22 notice, this list of conditions and the following disclaimer in the
23 documentation and/or other materials provided with the distribution.
25 * Neither the name of the University of Cambridge nor the names of its
26 contributors may be used to endorse or promote products derived from
27 this software without specific prior written permission.
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
40 -----------------------------------------------------------------------------
47 #include "pcre_internal.h"
49 #if defined SUPPORT_JIT
51 /* All-in-one: Since we use the JIT compiler only from here,
52 we just include it. This way we don't need to touch the build
55 #define SLJIT_MALLOC(size, allocator_data) (PUBL(malloc))(size)
56 #define SLJIT_FREE(ptr, allocator_data) (PUBL(free))(ptr)
57 #define SLJIT_CONFIG_AUTO 1
58 #define SLJIT_CONFIG_STATIC 1
59 #define SLJIT_VERBOSE 0
62 #include "sljit/sljitLir.c"
64 #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65 #error Unsupported architecture
68 /* Defines for debugging purposes. */
70 /* 1 - Use unoptimized capturing brackets.
71 2 - Enable capture_last_ptr (includes option 1). */
72 /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
74 /* 1 - Always have a control head. */
75 /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
77 /* Allocate memory for the regex stack on the real machine stack.
78 Fast, but limited size. */
79 #define MACHINE_STACK_SIZE 32768
81 /* Growth rate for stack allocated by the OS. Should be the multiply
83 #define STACK_GROWTH_RATE 8192
85 /* Enable to check that the allocation could destroy temporaries. */
86 #if defined SLJIT_DEBUG && SLJIT_DEBUG
87 #define DESTROY_REGISTERS 1
91 Short summary about the backtracking mechanism empolyed by the jit code generator:
93 The code generator follows the recursive nature of the PERL compatible regular
94 expressions. The basic blocks of regular expressions are condition checkers
95 whose execute different commands depending on the result of the condition check.
96 The relationship between the operators can be horizontal (concatenation) and
97 vertical (sub-expression) (See struct backtrack_common for more details).
99 'ab' - 'a' and 'b' regexps are concatenated
100 'a+' - 'a' is the sub-expression of the '+' operator
102 The condition checkers are boolean (true/false) checkers. Machine code is generated
103 for the checker itself and for the actions depending on the result of the checker.
104 The 'true' case is called as the matching path (expected path), and the other is called as
105 the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
106 branches on the matching path.
108 Greedy star operator (*) :
109 Matching path: match happens.
110 Backtrack path: match failed.
111 Non-greedy star operator (*?) :
112 Matching path: no need to perform a match.
113 Backtrack path: match is required.
115 The following example shows how the code generated for a capturing bracket
116 with two alternatives. Let A, B, C, D are arbirary regular expressions, and
117 we have the following regular expression:
121 The generated code will be the following:
124 '(' matching path (pushing arguments to the stack)
126 ')' matching path (pushing arguments to the stack)
128 return with successful match
131 ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
134 jump to D matching path
138 Notice, that the order of backtrack code paths are the opposite of the fast
139 code paths. In this way the topmost value on the stack is always belong
140 to the current backtrack code path. The backtrack path must check
141 whether there is a next alternative. If so, it needs to jump back to
142 the matching path eventually. Otherwise it needs to clear out its own stack
143 frame and continue the execution on the backtrack code paths.
149 Atomic blocks and asserts require reloading the values of private data
150 when the backtrack mechanism performed. Because of OP_RECURSE, the data
151 are not necessarly known in compile time, thus we need a dynamic restore
154 The stack frames are stored in a chain list, and have the following format:
155 ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
157 Thus we can restore the private data to a particular point in the stack.
160 typedef struct jit_arguments {
161 /* Pointers first. */
162 struct sljit_stack *stack;
163 const pcre_uchar *str;
164 const pcre_uchar *begin;
165 const pcre_uchar *end;
167 pcre_uchar *uchar_ptr;
168 pcre_uchar *mark_ptr;
170 /* Everything else after. */
171 sljit_u32 limit_match;
172 int real_offset_count;
177 sljit_u8 notempty_atstart;
180 typedef struct executable_functions {
181 void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182 void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
183 sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
184 PUBL(jit_callback) callback;
186 sljit_u32 top_bracket;
187 sljit_u32 limit_match;
188 } executable_functions;
190 typedef struct jump_list {
191 struct sljit_jump *jump;
192 struct jump_list *next;
195 typedef struct stub_list {
196 struct sljit_jump *start;
197 struct sljit_label *quit;
198 struct stub_list *next;
201 typedef struct label_addr_list {
202 struct sljit_label *label;
203 sljit_uw *update_addr;
204 struct label_addr_list *next;
217 typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
219 /* The following structure is the key data type for the recursive
220 code generator. It is allocated by compile_matchingpath, and contains
221 the arguments for compile_backtrackingpath. Must be the first member
222 of its descendants. */
223 typedef struct backtrack_common {
224 /* Concatenation stack. */
225 struct backtrack_common *prev;
226 jump_list *nextbacktracks;
227 /* Internal stack (for component operators). */
228 struct backtrack_common *top;
229 jump_list *topbacktracks;
230 /* Opcode pointer. */
234 typedef struct assert_backtrack {
235 backtrack_common common;
236 jump_list *condfailed;
237 /* Less than 0 if a frame is not needed. */
239 /* Points to our private memory word on the stack. */
240 int private_data_ptr;
242 struct sljit_label *matchingpath;
245 typedef struct bracket_backtrack {
246 backtrack_common common;
247 /* Where to coninue if an alternative is successfully matched. */
248 struct sljit_label *alternative_matchingpath;
249 /* For rmin and rmax iterators. */
250 struct sljit_label *recursive_matchingpath;
251 /* For greedy ? operator. */
252 struct sljit_label *zero_matchingpath;
253 /* Contains the branches of a failed condition. */
255 /* Both for OP_COND, OP_SCOND. */
256 jump_list *condfailed;
257 assert_backtrack *assert;
258 /* For OP_ONCE. Less than 0 if not needed. */
261 /* Points to our private memory word on the stack. */
262 int private_data_ptr;
265 typedef struct bracketpos_backtrack {
266 backtrack_common common;
267 /* Points to our private memory word on the stack. */
268 int private_data_ptr;
269 /* Reverting stack is needed. */
271 /* Allocated stack size. */
273 } bracketpos_backtrack;
275 typedef struct braminzero_backtrack {
276 backtrack_common common;
277 struct sljit_label *matchingpath;
278 } braminzero_backtrack;
280 typedef struct char_iterator_backtrack {
281 backtrack_common common;
282 /* Next iteration. */
283 struct sljit_label *matchingpath;
285 jump_list *backtracks;
287 unsigned int othercasebit;
292 } char_iterator_backtrack;
294 typedef struct ref_iterator_backtrack {
295 backtrack_common common;
296 /* Next iteration. */
297 struct sljit_label *matchingpath;
298 } ref_iterator_backtrack;
300 typedef struct recurse_entry {
301 struct recurse_entry *next;
302 /* Contains the function entry. */
303 struct sljit_label *entry;
304 /* Collects the calls until the function is not created. */
306 /* Points to the starting opcode. */
310 typedef struct recurse_backtrack {
311 backtrack_common common;
312 BOOL inlined_pattern;
315 #define OP_THEN_TRAP OP_TABLE_LENGTH
317 typedef struct then_trap_backtrack {
318 backtrack_common common;
319 /* If then_trap is not NULL, this structure contains the real
320 then_trap for the backtracking path. */
321 struct then_trap_backtrack *then_trap;
322 /* Points to the starting opcode. */
324 /* Exit point for the then opcodes of this alternative. */
326 /* Frame size of the current alternative. */
328 } then_trap_backtrack;
330 #define MAX_RANGE_SIZE 4
332 typedef struct compiler_common {
333 /* The sljit ceneric compiler. */
334 struct sljit_compiler *compiler;
335 /* First byte code. */
337 /* Maps private data offset to each opcode. */
338 sljit_s32 *private_data_ptrs;
339 /* Chain list of read-only data ptrs. */
340 void *read_only_data_head;
341 /* Tells whether the capturing bracket is optimized. */
342 sljit_u8 *optimized_cbracket;
343 /* Tells whether the starting offset is a target of then. */
344 sljit_u8 *then_offsets;
345 /* Current position where a THEN must jump. */
346 then_trap_backtrack *then_trap;
347 /* Starting offset of private data for capturing brackets. */
349 /* Output vector starting point. Must be divisible by 2. */
350 sljit_s32 ovector_start;
351 /* Points to the starting character of the current match. */
353 /* Last known position of the requested byte. */
354 sljit_s32 req_char_ptr;
355 /* Head of the last recursion. */
356 sljit_s32 recursive_head_ptr;
357 /* First inspected character for partial matching.
358 (Needed for avoiding zero length partial matches.) */
359 sljit_s32 start_used_ptr;
360 /* Starting pointer for partial soft matches. */
362 /* Pointer of the match end position. */
363 sljit_s32 match_end_ptr;
364 /* Points to the marked string. */
366 /* Recursive control verb management chain. */
367 sljit_s32 control_head_ptr;
368 /* Points to the last matched capture block index. */
369 sljit_s32 capture_last_ptr;
370 /* Fast forward skipping byte code pointer. */
371 pcre_uchar *fast_forward_bc_ptr;
372 /* Locals used by fast fail optimization. */
373 sljit_s32 fast_fail_start_ptr;
374 sljit_s32 fast_fail_end_ptr;
376 /* Flipped and lower case tables. */
379 /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
381 /* TRUE, when minlength is greater than 0. */
383 /* \K is found in the pattern. */
385 /* (*SKIP:arg) is found in the pattern. */
387 /* (*THEN) is found in the pattern. */
389 /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
390 BOOL has_skip_in_assert_back;
391 /* Currently in recurse or negative assert. */
393 /* Currently in a positive assert. */
394 BOOL positive_assert;
395 /* Newline control. */
403 /* Dollar endonly. */
407 /* Named capturing brackets. */
408 pcre_uchar *name_table;
410 sljit_sw name_entry_size;
412 /* Labels and jump lists. */
413 struct sljit_label *partialmatchlabel;
414 struct sljit_label *quit_label;
415 struct sljit_label *forced_quit_label;
416 struct sljit_label *accept_label;
417 struct sljit_label *ff_newline_shortcut;
419 label_addr_list *label_addrs;
420 recurse_entry *entries;
421 recurse_entry *currententry;
422 jump_list *partialmatch;
424 jump_list *positive_assert_quit;
425 jump_list *forced_quit;
427 jump_list *calllimit;
428 jump_list *stackalloc;
429 jump_list *revertframes;
430 jump_list *wordboundary;
431 jump_list *anynewline;
434 jump_list *casefulcmp;
435 jump_list *caselesscmp;
436 jump_list *reset_match;
445 jump_list *utfreadchar;
446 jump_list *utfreadchar16;
447 jump_list *utfreadtype8;
449 #endif /* SUPPORT_UTF */
452 /* For byte_sequence_compare. */
454 typedef struct compare_context {
457 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
462 #if defined COMPILE_PCRE8
464 sljit_u8 asuchars[4];
465 #elif defined COMPILE_PCRE16
466 sljit_u16 asuchars[2];
467 #elif defined COMPILE_PCRE32
468 sljit_u32 asuchars[1];
474 #if defined COMPILE_PCRE8
476 sljit_u8 asuchars[4];
477 #elif defined COMPILE_PCRE16
478 sljit_u16 asuchars[2];
479 #elif defined COMPILE_PCRE32
480 sljit_u32 asuchars[1];
486 /* Undefine sljit macros. */
489 /* Used for accessing the elements of the stack. */
490 #define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw))
492 #define TMP1 SLJIT_R0
493 #define TMP2 SLJIT_R2
494 #define TMP3 SLJIT_R3
495 #define STR_PTR SLJIT_S0
496 #define STR_END SLJIT_S1
497 #define STACK_TOP SLJIT_R1
498 #define STACK_LIMIT SLJIT_S2
499 #define COUNT_MATCH SLJIT_S3
500 #define ARGUMENTS SLJIT_S4
501 #define RETURN_ADDR SLJIT_R4
503 /* Local space layout. */
504 /* These two locals can be used by the current opcode. */
505 #define LOCALS0 (0 * sizeof(sljit_sw))
506 #define LOCALS1 (1 * sizeof(sljit_sw))
507 /* Two local variables for possessive quantifiers (char1 cannot use them). */
508 #define POSSESSIVE0 (2 * sizeof(sljit_sw))
509 #define POSSESSIVE1 (3 * sizeof(sljit_sw))
510 /* Max limit of recursions. */
511 #define LIMIT_MATCH (4 * sizeof(sljit_sw))
512 /* The output vector is stored on the stack, and contains pointers
513 to characters. The vector data is divided into two groups: the first
514 group contains the start / end character pointers, and the second is
515 the start pointers when the end of the capturing group has not yet reached. */
516 #define OVECTOR_START (common->ovector_start)
517 #define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
518 #define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
519 #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
521 #if defined COMPILE_PCRE8
522 #define MOV_UCHAR SLJIT_MOV_U8
523 #define MOVU_UCHAR SLJIT_MOVU_U8
524 #elif defined COMPILE_PCRE16
525 #define MOV_UCHAR SLJIT_MOV_U16
526 #define MOVU_UCHAR SLJIT_MOVU_U16
527 #elif defined COMPILE_PCRE32
528 #define MOV_UCHAR SLJIT_MOV_U32
529 #define MOVU_UCHAR SLJIT_MOVU_U32
531 #error Unsupported compiling mode
535 #define DEFINE_COMPILER \
536 struct sljit_compiler *compiler = common->compiler
537 #define OP1(op, dst, dstw, src, srcw) \
538 sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
539 #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
540 sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
542 sljit_emit_label(compiler)
544 sljit_emit_jump(compiler, (type))
545 #define JUMPTO(type, label) \
546 sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
547 #define JUMPHERE(jump) \
548 sljit_set_label((jump), sljit_emit_label(compiler))
549 #define SET_LABEL(jump, label) \
550 sljit_set_label((jump), (label))
551 #define CMP(type, src1, src1w, src2, src2w) \
552 sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
553 #define CMPTO(type, src1, src1w, src2, src2w, label) \
554 sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
555 #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
556 sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
557 #define GET_LOCAL_BASE(dst, dstw, offset) \
558 sljit_get_local_base(compiler, (dst), (dstw), (offset))
560 #define READ_CHAR_MAX 0x7fffffff
562 static pcre_uchar *bracketend(pcre_uchar *cc)
564 SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
565 do cc += GET(cc, 1); while (*cc == OP_ALT);
566 SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
571 static int no_alternatives(pcre_uchar *cc)
574 SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
580 while (*cc == OP_ALT);
581 SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
585 /* Functions whose might need modification for all new supported opcodes:
588 set_private_data_ptrs
591 get_private_data_copy_length
594 compile_backtrackingpath
597 static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
599 SLJIT_UNUSED_ARG(common);
605 case OP_NOT_WORD_BOUNDARY:
606 case OP_WORD_BOUNDARY:
609 case OP_NOT_WHITESPACE:
611 case OP_NOT_WORDCHAR:
658 case OP_ASSERTBACK_NOT:
685 case OP_ASSERT_ACCEPT:
688 return cc + PRIV(OP_lengths)[*cc];
738 case OP_NOTMINQUERYI:
744 case OP_NOTPOSQUERYI:
746 cc += PRIV(OP_lengths)[*cc];
748 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
758 case OP_TYPEMINQUERY:
764 case OP_TYPEPOSQUERY:
766 return cc + PRIV(OP_lengths)[*cc] - 1;
770 if (common->utf) return NULL;
774 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
776 return cc + GET(cc, 1);
783 return cc + 1 + 2 + cc[1];
786 /* All opcodes are supported now! */
792 static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
796 pcre_uchar *assert_back_end = cc - 1;
798 /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
804 common->has_set_som = TRUE;
805 common->might_be_empty = TRUE;
811 common->optimized_cbracket[GET2(cc, 1)] = 0;
817 common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
818 cc += 1 + LINK_SIZE + IMM2_SIZE;
823 /* Only AUTO_CALLOUT can insert this opcode. We do
824 not intend to support this case. */
825 if (cc[1 + LINK_SIZE] == OP_CALLOUT)
831 common->optimized_cbracket[GET2(cc, 1)] = 0;
838 count = GET2(cc, 1 + IMM2_SIZE);
839 slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
842 common->optimized_cbracket[GET2(slot, 0)] = 0;
843 slot += common->name_entry_size;
845 cc += 1 + 2 * IMM2_SIZE;
849 /* Set its value only once. */
850 if (common->recursive_head_ptr == 0)
852 common->recursive_head_ptr = common->ovector_start;
853 common->ovector_start += sizeof(sljit_sw);
859 if (common->capture_last_ptr == 0)
861 common->capture_last_ptr = common->ovector_start;
862 common->ovector_start += sizeof(sljit_sw);
864 cc += 2 + 2 * LINK_SIZE;
868 slot = bracketend(cc);
869 if (slot > assert_back_end)
870 assert_back_end = slot;
875 common->has_then = TRUE;
876 common->control_head_ptr = 1;
881 if (common->mark_ptr == 0)
883 common->mark_ptr = common->ovector_start;
884 common->ovector_start += sizeof(sljit_sw);
890 common->has_then = TRUE;
891 common->control_head_ptr = 1;
896 if (cc < assert_back_end)
897 common->has_skip_in_assert_back = TRUE;
902 common->control_head_ptr = 1;
903 common->has_skip_arg = TRUE;
904 if (cc < assert_back_end)
905 common->has_skip_in_assert_back = TRUE;
910 cc = next_opcode(common, cc);
919 static BOOL is_accelerated_repeat(pcre_uchar *cc)
929 return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI);
962 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
964 cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(pcre_uchar)));
966 cc += (1 + (32 / sizeof(pcre_uchar)));
984 static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start)
986 pcre_uchar *cc = common->start;
989 /* Skip not repeated brackets. */
997 case OP_NOT_WORD_BOUNDARY:
998 case OP_WORD_BOUNDARY:
1005 /* Zero width assertions. */
1010 if (*cc != OP_BRA && *cc != OP_CBRA)
1013 end = cc + GET(cc, 1);
1014 if (*end != OP_KET || PRIVATE_DATA(end) != 0)
1018 if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1022 cc += 1 + LINK_SIZE;
1025 if (is_accelerated_repeat(cc))
1027 common->fast_forward_bc_ptr = cc;
1028 common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
1029 *private_data_start += sizeof(sljit_sw);
1035 static SLJIT_INLINE void detect_fast_fail(compiler_common *common, pcre_uchar *cc, int *private_data_start, sljit_s32 depth)
1037 pcre_uchar *next_alt;
1039 SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA);
1041 if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1044 next_alt = bracketend(cc) - (1 + LINK_SIZE);
1045 if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0)
1050 next_alt = cc + GET(cc, 1);
1052 cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
1061 case OP_NOT_WORD_BOUNDARY:
1062 case OP_WORD_BOUNDARY:
1069 /* Zero width assertions. */
1076 if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA))
1077 detect_fast_fail(common, cc, private_data_start, depth - 1);
1079 if (is_accelerated_repeat(cc))
1081 common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
1083 if (common->fast_fail_start_ptr == 0)
1084 common->fast_fail_start_ptr = *private_data_start;
1086 *private_data_start += sizeof(sljit_sw);
1087 common->fast_fail_end_ptr = *private_data_start;
1089 if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
1095 while (*cc == OP_ALT);
1098 static int get_class_iterator_size(pcre_uchar *cc)
1117 max = GET2(cc, 1 + IMM2_SIZE);
1119 return (*cc == OP_CRRANGE) ? 2 : 1;
1130 static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
1132 pcre_uchar *end = bracketend(begin);
1134 pcre_uchar *next_end;
1135 pcre_uchar *max_end;
1137 sljit_sw length = end - begin;
1140 /* Detect fixed iterations first. */
1141 if (end[-(1 + LINK_SIZE)] != OP_KET)
1144 /* Already detected repeat. */
1145 if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
1152 if (*next != *begin)
1154 next_end = bracketend(next);
1155 if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
1166 if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
1171 if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
1173 next_end = bracketend(next + 2 + LINK_SIZE);
1174 if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
1180 if (next[0] == type && next[1] == *begin && max >= 1)
1182 next_end = bracketend(next + 1);
1183 if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
1185 for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
1186 if (*next_end != OP_KET)
1191 common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
1192 common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
1193 /* +2 the original and the last. */
1194 common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
1198 max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
1206 common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
1207 common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
1208 common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
1215 #define CASE_ITERATOR_PRIVATE_DATA_1 \
1223 case OP_MINQUERYI: \
1224 case OP_NOTMINSTAR: \
1225 case OP_NOTMINPLUS: \
1227 case OP_NOTMINQUERY: \
1228 case OP_NOTMINSTARI: \
1229 case OP_NOTMINPLUSI: \
1230 case OP_NOTQUERYI: \
1231 case OP_NOTMINQUERYI:
1233 #define CASE_ITERATOR_PRIVATE_DATA_2A \
1243 #define CASE_ITERATOR_PRIVATE_DATA_2B \
1249 case OP_NOTMINUPTO: \
1251 case OP_NOTMINUPTOI:
1253 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1254 case OP_TYPEMINSTAR: \
1255 case OP_TYPEMINPLUS: \
1256 case OP_TYPEQUERY: \
1257 case OP_TYPEMINQUERY:
1259 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1263 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1265 case OP_TYPEMINUPTO:
1267 static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1269 pcre_uchar *cc = common->start;
1270 pcre_uchar *alternative;
1271 pcre_uchar *end = NULL;
1272 int private_data_ptr = *private_data_start;
1273 int space, size, bracketlen;
1274 BOOL repeat_check = TRUE;
1281 if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1284 if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
1286 if (detect_repeat(common, cc))
1288 /* These brackets are converted to repeats, so no global
1289 based single character repeat is allowed. */
1291 end = bracketend(cc);
1294 repeat_check = TRUE;
1299 if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1301 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1302 private_data_ptr += sizeof(sljit_sw);
1303 cc += common->private_data_ptrs[cc + 1 - common->start];
1305 cc += 1 + LINK_SIZE;
1311 case OP_ASSERTBACK_NOT:
1318 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1319 private_data_ptr += sizeof(sljit_sw);
1320 bracketlen = 1 + LINK_SIZE;
1325 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1326 private_data_ptr += sizeof(sljit_sw);
1327 bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1331 /* Might be a hidden SCOND. */
1332 alternative = cc + GET(cc, 1);
1333 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1335 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1336 private_data_ptr += sizeof(sljit_sw);
1338 bracketlen = 1 + LINK_SIZE;
1342 bracketlen = 1 + LINK_SIZE;
1347 bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1353 repeat_check = FALSE;
1357 CASE_ITERATOR_PRIVATE_DATA_1
1362 CASE_ITERATOR_PRIVATE_DATA_2A
1367 CASE_ITERATOR_PRIVATE_DATA_2B
1369 size = -(2 + IMM2_SIZE);
1372 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1377 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1378 if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1384 if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1386 size = 1 + IMM2_SIZE;
1389 case OP_TYPEMINUPTO:
1391 size = 1 + IMM2_SIZE;
1396 space = get_class_iterator_size(cc + size);
1397 size = 1 + 32 / sizeof(pcre_uchar);
1400 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1402 space = get_class_iterator_size(cc + size);
1408 cc = next_opcode(common, cc);
1409 SLJIT_ASSERT(cc != NULL);
1413 /* Character iterators, which are not inside a repeated bracket,
1414 gets a private slot instead of allocating it on the stack. */
1415 if (space > 0 && cc >= end)
1417 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1418 private_data_ptr += sizeof(sljit_sw) * space;
1427 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1438 end = bracketend(cc);
1439 if (end[-1 - LINK_SIZE] == OP_KET)
1445 *private_data_start = private_data_ptr;
1448 /* Returns with a frame_types (always < 0) if no need for frame. */
1449 static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL *needs_control_head)
1453 BOOL stack_restore = FALSE;
1454 BOOL setsom_found = recursive;
1455 BOOL setmark_found = recursive;
1456 /* The last capture is a local variable even for recursions. */
1457 BOOL capture_last_found = FALSE;
1459 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1460 SLJIT_ASSERT(common->control_head_ptr != 0);
1461 *needs_control_head = TRUE;
1463 *needs_control_head = FALSE;
1468 ccend = bracketend(cc) - (1 + LINK_SIZE);
1469 if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1471 possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1472 /* This is correct regardless of common->capture_last_ptr. */
1473 capture_last_found = TRUE;
1475 cc = next_opcode(common, cc);
1478 SLJIT_ASSERT(cc != NULL);
1483 SLJIT_ASSERT(common->has_set_som);
1484 stack_restore = TRUE;
1488 setsom_found = TRUE;
1496 SLJIT_ASSERT(common->mark_ptr != 0);
1497 stack_restore = TRUE;
1501 setmark_found = TRUE;
1503 if (common->control_head_ptr != 0)
1504 *needs_control_head = TRUE;
1505 cc += 1 + 2 + cc[1];
1509 stack_restore = TRUE;
1510 if (common->has_set_som && !setsom_found)
1513 setsom_found = TRUE;
1515 if (common->mark_ptr != 0 && !setmark_found)
1518 setmark_found = TRUE;
1520 if (common->capture_last_ptr != 0 && !capture_last_found)
1523 capture_last_found = TRUE;
1525 cc += 1 + LINK_SIZE;
1532 stack_restore = TRUE;
1533 if (common->capture_last_ptr != 0 && !capture_last_found)
1536 capture_last_found = TRUE;
1539 cc += 1 + LINK_SIZE + IMM2_SIZE;
1543 stack_restore = TRUE;
1544 if (common->control_head_ptr != 0)
1545 *needs_control_head = TRUE;
1550 stack_restore = TRUE;
1553 case OP_NOT_WORD_BOUNDARY:
1554 case OP_WORD_BOUNDARY:
1557 case OP_NOT_WHITESPACE:
1559 case OP_NOT_WORDCHAR:
1598 case OP_NOTPOSQUERY:
1602 case OP_NOTPOSSTARI:
1603 case OP_NOTPOSPLUSI:
1604 case OP_NOTPOSQUERYI:
1605 case OP_NOTPOSUPTOI:
1608 case OP_TYPEPOSSTAR:
1609 case OP_TYPEPOSPLUS:
1610 case OP_TYPEPOSQUERY:
1611 case OP_TYPEPOSUPTO:
1618 cc = next_opcode(common, cc);
1619 SLJIT_ASSERT(cc != NULL);
1623 /* Possessive quantifiers can use a special case. */
1624 if (SLJIT_UNLIKELY(possessive == length))
1625 return stack_restore ? no_frame : no_stack;
1629 return stack_restore ? no_frame : no_stack;
1632 static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1635 BOOL setsom_found = recursive;
1636 BOOL setmark_found = recursive;
1637 /* The last capture is a local variable even for recursions. */
1638 BOOL capture_last_found = FALSE;
1641 /* >= 1 + shortest item size (2) */
1642 SLJIT_UNUSED_ARG(stacktop);
1643 SLJIT_ASSERT(stackpos >= stacktop + 2);
1645 stackpos = STACK(stackpos);
1648 ccend = bracketend(cc) - (1 + LINK_SIZE);
1649 if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1650 cc = next_opcode(common, cc);
1653 SLJIT_ASSERT(cc != NULL);
1658 SLJIT_ASSERT(common->has_set_som);
1661 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1662 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1663 stackpos += (int)sizeof(sljit_sw);
1664 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1665 stackpos += (int)sizeof(sljit_sw);
1666 setsom_found = TRUE;
1674 SLJIT_ASSERT(common->mark_ptr != 0);
1677 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1678 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1679 stackpos += (int)sizeof(sljit_sw);
1680 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1681 stackpos += (int)sizeof(sljit_sw);
1682 setmark_found = TRUE;
1684 cc += 1 + 2 + cc[1];
1688 if (common->has_set_som && !setsom_found)
1690 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1691 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1692 stackpos += (int)sizeof(sljit_sw);
1693 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1694 stackpos += (int)sizeof(sljit_sw);
1695 setsom_found = TRUE;
1697 if (common->mark_ptr != 0 && !setmark_found)
1699 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1700 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1701 stackpos += (int)sizeof(sljit_sw);
1702 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1703 stackpos += (int)sizeof(sljit_sw);
1704 setmark_found = TRUE;
1706 if (common->capture_last_ptr != 0 && !capture_last_found)
1708 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1709 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1710 stackpos += (int)sizeof(sljit_sw);
1711 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1712 stackpos += (int)sizeof(sljit_sw);
1713 capture_last_found = TRUE;
1715 cc += 1 + LINK_SIZE;
1722 if (common->capture_last_ptr != 0 && !capture_last_found)
1724 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1725 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1726 stackpos += (int)sizeof(sljit_sw);
1727 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1728 stackpos += (int)sizeof(sljit_sw);
1729 capture_last_found = TRUE;
1731 offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1732 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1733 stackpos += (int)sizeof(sljit_sw);
1734 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
1735 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
1736 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1737 stackpos += (int)sizeof(sljit_sw);
1738 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1739 stackpos += (int)sizeof(sljit_sw);
1741 cc += 1 + LINK_SIZE + IMM2_SIZE;
1745 cc = next_opcode(common, cc);
1746 SLJIT_ASSERT(cc != NULL);
1750 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1751 SLJIT_ASSERT(stackpos == STACK(stacktop));
1754 static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1756 int private_data_length = needs_control_head ? 3 : 2;
1758 pcre_uchar *alternative;
1759 /* Calculate the sum of the private machine words. */
1766 if (PRIVATE_DATA(cc) != 0)
1768 private_data_length++;
1769 SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
1770 cc += PRIVATE_DATA(cc + 1);
1772 cc += 1 + LINK_SIZE;
1778 case OP_ASSERTBACK_NOT:
1785 private_data_length++;
1786 SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
1787 cc += 1 + LINK_SIZE;
1792 if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1793 private_data_length++;
1794 cc += 1 + LINK_SIZE + IMM2_SIZE;
1799 private_data_length += 2;
1800 cc += 1 + LINK_SIZE + IMM2_SIZE;
1804 /* Might be a hidden SCOND. */
1805 alternative = cc + GET(cc, 1);
1806 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1807 private_data_length++;
1808 cc += 1 + LINK_SIZE;
1811 CASE_ITERATOR_PRIVATE_DATA_1
1812 if (PRIVATE_DATA(cc))
1813 private_data_length++;
1816 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1820 CASE_ITERATOR_PRIVATE_DATA_2A
1821 if (PRIVATE_DATA(cc))
1822 private_data_length += 2;
1825 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1829 CASE_ITERATOR_PRIVATE_DATA_2B
1830 if (PRIVATE_DATA(cc))
1831 private_data_length += 2;
1832 cc += 2 + IMM2_SIZE;
1834 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1838 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1839 if (PRIVATE_DATA(cc))
1840 private_data_length++;
1844 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1845 if (PRIVATE_DATA(cc))
1846 private_data_length += 2;
1850 CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1851 if (PRIVATE_DATA(cc))
1852 private_data_length += 2;
1853 cc += 1 + IMM2_SIZE;
1858 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1860 size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1862 size = 1 + 32 / (int)sizeof(pcre_uchar);
1864 if (PRIVATE_DATA(cc))
1865 private_data_length += get_class_iterator_size(cc + size);
1870 cc = next_opcode(common, cc);
1871 SLJIT_ASSERT(cc != NULL);
1875 SLJIT_ASSERT(cc == ccend);
1876 return private_data_length;
1879 static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1880 BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1885 BOOL tmp1next = TRUE;
1886 BOOL tmp1empty = TRUE;
1887 BOOL tmp2empty = TRUE;
1888 pcre_uchar *alternative;
1895 status = save ? start : loop;
1896 stackptr = STACK(stackptr - 2);
1897 stacktop = STACK(stacktop - 1);
1901 stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1902 if (stackptr < stacktop)
1904 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1905 stackptr += sizeof(sljit_sw);
1908 if (stackptr < stacktop)
1910 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1911 stackptr += sizeof(sljit_sw);
1914 /* The tmp1next must be TRUE in either way. */
1923 SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1925 srcw[0] = common->recursive_head_ptr;
1926 if (needs_control_head)
1928 SLJIT_ASSERT(common->control_head_ptr != 0);
1930 srcw[1] = common->control_head_ptr;
1945 if (PRIVATE_DATA(cc) != 0)
1948 srcw[0] = PRIVATE_DATA(cc);
1949 SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
1950 cc += PRIVATE_DATA(cc + 1);
1952 cc += 1 + LINK_SIZE;
1958 case OP_ASSERTBACK_NOT:
1966 srcw[0] = PRIVATE_DATA(cc);
1967 SLJIT_ASSERT(srcw[0] != 0);
1968 cc += 1 + LINK_SIZE;
1973 if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1976 srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1978 cc += 1 + LINK_SIZE + IMM2_SIZE;
1984 srcw[0] = PRIVATE_DATA(cc);
1985 srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1986 SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1987 cc += 1 + LINK_SIZE + IMM2_SIZE;
1991 /* Might be a hidden SCOND. */
1992 alternative = cc + GET(cc, 1);
1993 if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1996 srcw[0] = PRIVATE_DATA(cc);
1997 SLJIT_ASSERT(srcw[0] != 0);
1999 cc += 1 + LINK_SIZE;
2002 CASE_ITERATOR_PRIVATE_DATA_1
2003 if (PRIVATE_DATA(cc))
2006 srcw[0] = PRIVATE_DATA(cc);
2010 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2014 CASE_ITERATOR_PRIVATE_DATA_2A
2015 if (PRIVATE_DATA(cc))
2018 srcw[0] = PRIVATE_DATA(cc);
2019 srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
2023 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2027 CASE_ITERATOR_PRIVATE_DATA_2B
2028 if (PRIVATE_DATA(cc))
2031 srcw[0] = PRIVATE_DATA(cc);
2032 srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
2034 cc += 2 + IMM2_SIZE;
2036 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2040 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2041 if (PRIVATE_DATA(cc))
2044 srcw[0] = PRIVATE_DATA(cc);
2049 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2050 if (PRIVATE_DATA(cc))
2053 srcw[0] = PRIVATE_DATA(cc);
2054 srcw[1] = srcw[0] + sizeof(sljit_sw);
2059 CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2060 if (PRIVATE_DATA(cc))
2063 srcw[0] = PRIVATE_DATA(cc);
2064 srcw[1] = srcw[0] + sizeof(sljit_sw);
2066 cc += 1 + IMM2_SIZE;
2071 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2073 size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
2075 size = 1 + 32 / (int)sizeof(pcre_uchar);
2077 if (PRIVATE_DATA(cc))
2078 switch(get_class_iterator_size(cc + size))
2082 srcw[0] = PRIVATE_DATA(cc);
2087 srcw[0] = PRIVATE_DATA(cc);
2088 srcw[1] = srcw[0] + sizeof(sljit_sw);
2092 SLJIT_ASSERT_STOP();
2099 cc = next_opcode(common, cc);
2100 SLJIT_ASSERT(cc != NULL);
2106 SLJIT_ASSERT_STOP();
2119 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
2120 stackptr += sizeof(sljit_sw);
2122 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
2130 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
2131 stackptr += sizeof(sljit_sw);
2133 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
2142 SLJIT_ASSERT(!tmp1empty);
2143 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0);
2144 tmp1empty = stackptr >= stacktop;
2147 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
2148 stackptr += sizeof(sljit_sw);
2154 SLJIT_ASSERT(!tmp2empty);
2155 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0);
2156 tmp2empty = stackptr >= stacktop;
2159 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
2160 stackptr += sizeof(sljit_sw);
2167 while (status != end);
2175 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
2176 stackptr += sizeof(sljit_sw);
2180 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
2181 stackptr += sizeof(sljit_sw);
2188 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
2189 stackptr += sizeof(sljit_sw);
2193 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
2194 stackptr += sizeof(sljit_sw);
2198 SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
2201 static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, sljit_u8 *current_offset)
2203 pcre_uchar *end = bracketend(cc);
2204 BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
2206 /* Assert captures then. */
2207 if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
2208 current_offset = NULL;
2209 /* Conditional block does not. */
2210 if (*cc == OP_COND || *cc == OP_SCOND)
2211 has_alternatives = FALSE;
2213 cc = next_opcode(common, cc);
2214 if (has_alternatives)
2215 current_offset = common->then_offsets + (cc - common->start);
2219 if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
2220 cc = set_then_offsets(common, cc, current_offset);
2223 if (*cc == OP_ALT && has_alternatives)
2224 current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
2225 if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
2226 *current_offset = 1;
2227 cc = next_opcode(common, cc);
2234 #undef CASE_ITERATOR_PRIVATE_DATA_1
2235 #undef CASE_ITERATOR_PRIVATE_DATA_2A
2236 #undef CASE_ITERATOR_PRIVATE_DATA_2B
2237 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2238 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2239 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2241 static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
2243 return (value & (value - 1)) == 0;
2246 static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
2250 /* sljit_set_label is clever enough to do nothing
2251 if either the jump or the label is NULL. */
2252 SET_LABEL(list->jump, label);
2257 static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)
2259 jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
2262 list_item->next = *list;
2263 list_item->jump = jump;
2268 static void add_stub(compiler_common *common, struct sljit_jump *start)
2271 stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
2275 list_item->start = start;
2276 list_item->quit = LABEL();
2277 list_item->next = common->stubs;
2278 common->stubs = list_item;
2282 static void flush_stubs(compiler_common *common)
2285 stub_list *list_item = common->stubs;
2289 JUMPHERE(list_item->start);
2290 add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
2291 JUMPTO(SLJIT_JUMP, list_item->quit);
2292 list_item = list_item->next;
2294 common->stubs = NULL;
2297 static void add_label_addr(compiler_common *common, sljit_uw *update_addr)
2300 label_addr_list *label_addr;
2302 label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
2303 if (label_addr == NULL)
2305 label_addr->label = LABEL();
2306 label_addr->update_addr = update_addr;
2307 label_addr->next = common->label_addrs;
2308 common->label_addrs = label_addr;
2311 static SLJIT_INLINE void count_match(compiler_common *common)
2315 OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
2316 add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
2319 static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
2321 /* May destroy all locals and registers except TMP2. */
2324 SLJIT_ASSERT(size > 0);
2325 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2326 #ifdef DESTROY_REGISTERS
2327 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
2328 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2329 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2330 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
2331 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
2333 add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
2336 static SLJIT_INLINE void free_stack(compiler_common *common, int size)
2340 SLJIT_ASSERT(size > 0);
2341 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2344 static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
2349 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
2352 result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
2353 if (SLJIT_UNLIKELY(result == NULL))
2355 sljit_set_compiler_memory_error(compiler);
2359 *(void**)result = common->read_only_data_head;
2360 common->read_only_data_head = (void *)result;
2364 static void free_read_only_data(void *current, void *allocator_data)
2368 SLJIT_UNUSED_ARG(allocator_data);
2370 while (current != NULL)
2372 next = *(void**)current;
2373 SLJIT_FREE(current, allocator_data);
2378 static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
2381 struct sljit_label *loop;
2384 /* At this point we can freely use all temporary registers. */
2385 SLJIT_ASSERT(length > 1);
2386 /* TMP1 returns with begin - 1. */
2387 OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2390 for (i = 1; i < length; i++)
2391 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
2395 GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
2396 OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
2398 OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
2399 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
2400 JUMPTO(SLJIT_NOT_ZERO, loop);
2404 static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
2409 SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);
2411 OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2412 for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
2413 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
2416 static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2419 struct sljit_label *loop;
2422 SLJIT_ASSERT(length > 1);
2423 /* OVECTOR(1) contains the "string begin - 1" constant. */
2425 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
2428 for (i = 2; i < length; i++)
2429 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
2433 GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2434 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2436 OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2437 OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2438 JUMPTO(SLJIT_NOT_ZERO, loop);
2441 OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2442 if (common->mark_ptr != 0)
2443 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
2444 if (common->control_head_ptr != 0)
2445 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
2446 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2447 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
2448 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2451 static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2453 while (current != NULL)
2455 switch (current[-2])
2457 case type_then_trap:
2461 if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2466 SLJIT_ASSERT_STOP();
2469 SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
2470 current = (sljit_sw*)current[-1];
2475 static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2478 struct sljit_label *loop;
2479 struct sljit_jump *early_quit;
2481 /* At this point we can freely use all registers. */
2482 OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
2483 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
2485 OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
2486 if (common->mark_ptr != 0)
2487 OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
2488 OP1(SLJIT_MOV_S32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offset_count));
2489 if (common->mark_ptr != 0)
2490 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
2491 OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2492 OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
2493 GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
2494 /* Unlikely, but possible */
2495 early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
2497 OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
2498 OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
2499 /* Copy the integer value to the output buffer */
2500 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2501 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
2503 OP1(SLJIT_MOVU_S32, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0);
2504 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2505 JUMPTO(SLJIT_NOT_ZERO, loop);
2506 JUMPHERE(early_quit);
2508 /* Calculate the return value, which is the maximum ovector value. */
2511 GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
2512 OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
2514 /* OVECTOR(0) is never equal to SLJIT_S2. */
2516 OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
2517 OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2518 CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
2519 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
2522 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
2525 static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
2528 struct sljit_jump *jump;
2530 SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2);
2531 SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2532 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2534 OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
2535 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2536 OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2537 CMPTO(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit);
2539 /* Store match begin and end. */
2540 OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
2541 OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, offsets));
2543 jump = CMP(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 3);
2544 OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_S0, 0);
2545 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2546 OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
2548 OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R1), 2 * sizeof(int), SLJIT_R2, 0);
2551 OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
2552 OP2(SLJIT_SUB, SLJIT_S1, 0, STR_END, 0, SLJIT_S0, 0);
2553 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2554 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
2556 OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R1), sizeof(int), SLJIT_S1, 0);
2558 OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0);
2559 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2560 OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
2562 OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R2, 0);
2564 JUMPTO(SLJIT_JUMP, quit);
2567 static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
2569 /* May destroy TMP1. */
2571 struct sljit_jump *jump;
2573 if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2575 /* The value of -1 must be kept for start_used_ptr! */
2576 OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);
2577 /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
2578 is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
2579 jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
2580 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2583 else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
2585 jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2586 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2591 static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar *cc)
2593 /* Detects if the character has an othercase. */
2603 return c != UCD_OTHERCASE(c);
2608 #ifndef COMPILE_PCRE8
2609 return common->fcc[c] != c;
2615 return MAX_255(c) ? common->fcc[c] != c : FALSE;
2618 static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
2620 /* Returns with the othercase. */
2622 if (common->utf && c > 127)
2625 return UCD_OTHERCASE(c);
2631 return TABLE_GET(c, common->fcc, c);
2634 static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar *cc)
2636 /* Detects if the character and its othercase has only 1 bit difference. */
2637 unsigned int c, oc, bit;
2638 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2647 oc = common->fcc[c];
2651 oc = UCD_OTHERCASE(c);
2660 oc = TABLE_GET(c, common->fcc, c);
2664 oc = TABLE_GET(c, common->fcc, c);
2667 SLJIT_ASSERT(c != oc);
2670 /* Optimized for English alphabet. */
2671 if (c <= 127 && bit == 0x20)
2672 return (0 << 8) | 0x20;
2674 /* Since c != oc, they must have at least 1 bit difference. */
2675 if (!is_powerof2(bit))
2678 #if defined COMPILE_PCRE8
2681 if (common->utf && c > 127)
2683 n = GET_EXTRALEN(*cc);
2684 while ((bit & 0x3f) == 0)
2689 return (n << 8) | bit;
2691 #endif /* SUPPORT_UTF */
2692 return (0 << 8) | bit;
2694 #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2697 if (common->utf && c > 65535)
2699 if (bit >= (1 << 10))
2702 return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
2704 #endif /* SUPPORT_UTF */
2705 return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
2707 #endif /* COMPILE_PCRE[8|16|32] */
2710 static void check_partial(compiler_common *common, BOOL force)
2712 /* Checks whether a partial matching is occurred. Does not modify registers. */
2714 struct sljit_jump *jump = NULL;
2716 SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2718 if (common->mode == JIT_COMPILE)
2722 jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2723 else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2724 jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
2726 if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2727 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
2730 if (common->partialmatchlabel != NULL)
2731 JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2733 add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2740 static void check_str_end(compiler_common *common, jump_list **end_reached)
2742 /* Does not affect registers. Usually used in a tight spot. */
2744 struct sljit_jump *jump;
2746 if (common->mode == JIT_COMPILE)
2748 add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2752 jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
2753 if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2755 add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
2756 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
2757 add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
2761 add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
2762 if (common->partialmatchlabel != NULL)
2763 JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2765 add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2770 static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2773 struct sljit_jump *jump;
2775 if (common->mode == JIT_COMPILE)
2777 add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2781 /* Partial matching mode. */
2782 jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
2783 add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
2784 if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2786 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
2787 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2791 if (common->partialmatchlabel != NULL)
2792 JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2794 add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2799 static void peek_char(compiler_common *common, sljit_u32 max)
2801 /* Reads the character into TMP1, keeps STR_PTR.
2802 Does not check STR_END. TMP2 Destroyed. */
2804 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2805 struct sljit_jump *jump;
2808 SLJIT_UNUSED_ARG(max);
2810 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2811 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2814 if (max < 128) return;
2816 jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2817 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2818 add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2819 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2822 #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2824 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2827 if (max < 0xd800) return;
2829 OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2830 jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2831 /* TMP2 contains the high surrogate. */
2832 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2833 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2834 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2835 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2836 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2842 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2844 static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass)
2846 /* Tells whether the character codes below 128 are enough
2847 to determine a match. */
2848 const sljit_u8 value = nclass ? 0xff : 0;
2849 const sljit_u8 *end = bitset + 32;
2854 if (*bitset++ != value)
2857 while (bitset < end);
2861 static void read_char7_type(compiler_common *common, BOOL full_read)
2863 /* Reads the precise character type of a character into TMP1, if the character
2864 is less than 128. Otherwise it returns with zero. Does not check STR_END. The
2865 full_read argument tells whether characters above max are accepted or not. */
2867 struct sljit_jump *jump;
2869 SLJIT_ASSERT(common->utf);
2871 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2872 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2874 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2878 jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2879 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2880 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2885 #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2887 static void read_char_range(compiler_common *common, sljit_u32 min, sljit_u32 max, BOOL update_str_ptr)
2889 /* Reads the precise value of a character into TMP1, if the character is
2890 between min and max (c >= min && c <= max). Otherwise it returns with a value
2891 outside the range. Does not check STR_END. */
2893 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2894 struct sljit_jump *jump;
2896 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2897 struct sljit_jump *jump2;
2900 SLJIT_UNUSED_ARG(update_str_ptr);
2901 SLJIT_UNUSED_ARG(min);
2902 SLJIT_UNUSED_ARG(max);
2903 SLJIT_ASSERT(min <= max);
2905 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2906 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2908 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2911 if (max < 128 && !update_str_ptr) return;
2913 jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2916 OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
2918 OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2919 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2920 jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
2921 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2922 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2923 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2924 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2925 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2926 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2927 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2928 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2929 if (!update_str_ptr)
2930 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2931 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2932 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2933 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2936 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2938 else if (min >= 0x800 && max <= 0xffff)
2940 OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
2942 OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2943 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2944 jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
2945 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2946 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2947 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2948 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2949 if (!update_str_ptr)
2950 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2951 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2952 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2953 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2956 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2958 else if (max >= 0x800)
2959 add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2962 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2963 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2967 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2968 if (!update_str_ptr)
2969 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2971 OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2972 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2973 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2974 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2975 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2977 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2983 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2988 OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2989 jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2990 /* TMP2 contains the high surrogate. */
2991 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2992 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2993 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2994 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2995 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2996 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3001 if (max < 0xd800 && !update_str_ptr) return;
3003 /* Skip low surrogate if necessary. */
3004 OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3005 jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
3007 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3009 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
3015 static SLJIT_INLINE void read_char(compiler_common *common)
3017 read_char_range(common, 0, READ_CHAR_MAX, TRUE);
3020 static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
3022 /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
3024 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3025 struct sljit_jump *jump;
3027 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3028 struct sljit_jump *jump2;
3031 SLJIT_UNUSED_ARG(update_str_ptr);
3033 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
3034 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3036 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3039 /* This can be an extra read in some situations, but hopefully
3040 it is needed in most cases. */
3041 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3042 jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
3043 if (!update_str_ptr)
3045 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3046 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3047 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3048 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3049 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3050 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
3051 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3052 jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
3053 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3057 add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
3061 #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
3063 #if !defined COMPILE_PCRE8
3064 /* The ctypes array contains only 256 values. */
3065 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3066 jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
3068 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3069 #if !defined COMPILE_PCRE8
3073 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
3074 if (common->utf && update_str_ptr)
3076 /* Skip low surrogate if necessary. */
3077 OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
3078 jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
3079 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3082 #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
3085 static void skip_char_back(compiler_common *common)
3087 /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
3089 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3090 #if defined COMPILE_PCRE8
3091 struct sljit_label *label;
3096 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
3097 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3098 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
3099 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
3102 #elif defined COMPILE_PCRE16
3105 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
3106 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3107 /* Skip low surrogate if necessary. */
3108 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3109 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
3110 OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3111 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3112 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3115 #endif /* COMPILE_PCRE[8|16] */
3116 #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
3117 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3120 static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
3122 /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
3124 struct sljit_jump *jump;
3126 if (nltype == NLTYPE_ANY)
3128 add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3129 add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
3131 else if (nltype == NLTYPE_ANYCRLF)
3135 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
3136 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3140 jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3141 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3147 SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
3148 add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3154 #if defined COMPILE_PCRE8
3155 static void do_utfreadchar(compiler_common *common)
3157 /* Fast decoding a UTF-8 character. TMP1 contains the first byte
3158 of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
3160 struct sljit_jump *jump;
3162 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3163 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3164 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3165 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3166 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3167 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3169 /* Searching for the first zero. */
3170 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
3171 jump = JUMP(SLJIT_NOT_ZERO);
3172 /* Two byte sequence. */
3173 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3174 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
3175 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3178 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3179 OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
3180 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3181 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3182 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3184 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
3185 jump = JUMP(SLJIT_NOT_ZERO);
3186 /* Three byte sequence. */
3187 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3188 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
3189 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3191 /* Four byte sequence. */
3193 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
3194 OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
3195 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3196 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
3197 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3198 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3199 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
3200 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3203 static void do_utfreadchar16(compiler_common *common)
3205 /* Fast decoding a UTF-8 character. TMP1 contains the first byte
3206 of the character (>= 0xc0). Return value in TMP1. */
3208 struct sljit_jump *jump;
3210 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3211 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3212 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3213 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3214 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3215 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3217 /* Searching for the first zero. */
3218 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
3219 jump = JUMP(SLJIT_NOT_ZERO);
3220 /* Two byte sequence. */
3221 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3222 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3225 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
3226 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO);
3227 /* This code runs only in 8 bit mode. No need to shift the value. */
3228 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3229 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3230 OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
3231 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3232 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3233 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3234 /* Three byte sequence. */
3235 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3236 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3239 static void do_utfreadtype8(compiler_common *common)
3241 /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
3242 of the character (>= 0xc0). Return value in TMP1. */
3244 struct sljit_jump *jump;
3245 struct sljit_jump *compare;
3247 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3249 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
3250 jump = JUMP(SLJIT_NOT_ZERO);
3251 /* Two byte sequence. */
3252 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3253 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3254 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
3255 /* The upper 5 bits are known at this point. */
3256 compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
3257 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3258 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3259 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
3260 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3261 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3264 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3265 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3267 /* We only have types for characters less than 256. */
3269 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3270 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3271 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3272 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3275 #endif /* COMPILE_PCRE8 */
3277 #endif /* SUPPORT_UTF */
3281 /* UCD_BLOCK_SIZE must be 128 (see the assert below). */
3282 #define UCD_BLOCK_MASK 127
3283 #define UCD_BLOCK_SHIFT 7
3285 static void do_getucd(compiler_common *common)
3287 /* Search the UCD record for the character comes in TMP1.
3288 Returns chartype in TMP1 and UCD offset in TMP2. */
3291 SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
3293 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3294 OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
3295 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
3296 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
3297 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
3298 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
3299 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
3300 OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
3301 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
3302 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
3303 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3307 static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf)
3310 struct sljit_label *mainloop;
3311 struct sljit_label *newlinelabel = NULL;
3312 struct sljit_jump *start;
3313 struct sljit_jump *end = NULL;
3314 struct sljit_jump *end2 = NULL;
3315 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3316 struct sljit_jump *singlechar;
3318 jump_list *newline = NULL;
3319 BOOL newlinecheck = FALSE;
3320 BOOL readuchar = FALSE;
3322 if (!(hascrorlf || (common->match_end_ptr != 0)) &&
3323 (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
3324 newlinecheck = TRUE;
3326 if (common->match_end_ptr != 0)
3328 /* Search for the end of the first line. */
3329 OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
3331 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3334 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3335 end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3336 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3337 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3338 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
3339 CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
3341 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3345 end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3347 /* Continual stores does not cause data dependency. */
3348 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
3349 read_char_range(common, common->nlmin, common->nlmax, TRUE);
3350 check_newlinechar(common, common->nltype, &newline, TRUE);
3351 CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
3353 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0);
3354 set_jumps(newline, LABEL());
3357 OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3360 start = JUMP(SLJIT_JUMP);
3364 newlinelabel = LABEL();
3365 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3366 end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3367 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3368 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
3369 OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3370 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3371 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3373 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3374 end2 = JUMP(SLJIT_JUMP);
3379 /* Increasing the STR_PTR here requires one less jump in the most common case. */
3381 if (common->utf) readuchar = TRUE;
3383 if (newlinecheck) readuchar = TRUE;
3386 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3389 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
3391 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3392 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3393 #if defined COMPILE_PCRE8
3396 singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3397 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3398 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3399 JUMPHERE(singlechar);
3401 #elif defined COMPILE_PCRE16
3404 singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3405 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3406 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3407 OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3408 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3409 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3410 JUMPHERE(singlechar);
3412 #endif /* COMPILE_PCRE[8|16] */
3413 #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
3425 #define MAX_N_CHARS 16
3426 #define MAX_DIFF_CHARS 6
3428 static SLJIT_INLINE void add_prefix_char(pcre_uchar chr, pcre_uchar *chars)
3443 for (i = len; i > 0; i--)
3444 if (chars[i] == chr)
3447 if (len >= MAX_DIFF_CHARS - 1)
3458 static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uchar *chars, int max_chars, sljit_u32 *rec_count)
3460 /* Recursive function, which scans prefix literals. */
3461 BOOL last, any, class, caseless;
3462 int len, repeat, len_save, consumed = 0;
3463 sljit_u32 chr; /* Any unicode character. */
3464 sljit_u8 *bytes, *bytes_end, byte;
3465 pcre_uchar *alternative, *cc_save, *oc;
3466 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3467 pcre_uchar othercase[8];
3468 #elif defined SUPPORT_UTF && defined COMPILE_PCRE16
3469 pcre_uchar othercase[2];
3471 pcre_uchar othercase[1];
3477 if (*rec_count == 0)
3498 case OP_NOT_WORD_BOUNDARY:
3499 case OP_WORD_BOUNDARY:
3506 /* Zero width assertions. */
3513 case OP_ASSERTBACK_NOT:
3514 cc = bracketend(cc);
3530 repeat = GET2(cc, 1);
3532 cc += 1 + IMM2_SIZE;
3545 if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3547 max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count);
3554 cc += 1 + LINK_SIZE;
3567 alternative = cc + GET(cc, 1);
3568 while (*alternative == OP_ALT)
3570 max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count);
3573 alternative += GET(alternative, 1);
3576 if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3578 cc += 1 + LINK_SIZE;
3582 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3583 if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE))
3590 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3591 if (common->utf) return consumed;
3596 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3598 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3599 if (common->utf) return consumed;
3607 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3608 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
3616 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3617 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))
3625 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3626 if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))
3638 case OP_NOT_WHITESPACE:
3639 case OP_NOT_WORDCHAR:
3642 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3643 if (common->utf) return consumed;
3652 #ifndef COMPILE_PCRE32
3653 if (common->utf) return consumed;
3661 repeat = GET2(cc, 1);
3662 cc += 1 + IMM2_SIZE;
3667 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3668 if (common->utf) return consumed;
3671 repeat = GET2(cc, 1);
3672 cc += 1 + IMM2_SIZE + 1;
3686 if (--max_chars == 0)
3688 chars += MAX_DIFF_CHARS;
3690 while (--repeat > 0);
3698 bytes = (sljit_u8*) (cc + 1);
3699 cc += 1 + 32 / sizeof(pcre_uchar);
3709 max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count);
3723 repeat = GET2(cc, 1);
3731 if (bytes[31] & 0x80)
3733 else if (chars[0] != 255)
3735 bytes_end = bytes + 32;
3740 SLJIT_ASSERT((chr & 0x7) == 0);
3747 if ((byte & 0x1) != 0)
3748 add_prefix_char(chr, chars);
3753 chr = (chr + 7) & ~7;
3756 while (chars[0] != 255 && bytes < bytes_end);
3757 bytes = bytes_end - 32;
3761 if (--max_chars == 0)
3763 chars += MAX_DIFF_CHARS;
3765 while (--repeat > 0);
3783 if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE))
3785 cc += 1 + 2 * IMM2_SIZE;
3795 if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3798 if (caseless && char_has_othercase(common, cc))
3804 if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
3811 othercase[0] = TABLE_GET(chr, common->fcc, chr);
3817 othercase[0] = 0; /* Stops compiler warning - PH */
3828 add_prefix_char(*cc, chars);
3831 add_prefix_char(*oc, chars);
3835 if (--max_chars == 0)
3837 chars += MAX_DIFF_CHARS;
3856 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
3858 static sljit_s32 character_to_int32(pcre_uchar chr)
3860 sljit_s32 value = (sljit_s32)chr;
3861 #if defined COMPILE_PCRE8
3862 #define SSE2_COMPARE_TYPE_INDEX 0
3863 return (value << 24) | (value << 16) | (value << 8) | value;
3864 #elif defined COMPILE_PCRE16
3865 #define SSE2_COMPARE_TYPE_INDEX 1
3866 return (value << 16) | value;
3867 #elif defined COMPILE_PCRE32
3868 #define SSE2_COMPARE_TYPE_INDEX 2
3871 #error "Unsupported unit width"
3875 static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, pcre_uchar char1, pcre_uchar char2)
3878 struct sljit_label *start;
3879 struct sljit_jump *quit[3];
3880 struct sljit_jump *nomatch;
3881 sljit_u8 instruction[8];
3882 sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
3883 sljit_s32 tmp2_ind = sljit_get_register_index(TMP2);
3884 sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
3885 BOOL load_twice = FALSE;
3888 bit = char1 ^ char2;
3889 if (!is_powerof2(bit))
3892 if ((char1 != char2) && bit == 0)
3895 quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3897 /* First part (unaligned start) */
3899 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
3901 SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
3903 /* MOVD xmm, r/m32 */
3904 instruction[0] = 0x66;
3905 instruction[1] = 0x0f;
3906 instruction[2] = 0x6e;
3907 instruction[3] = 0xc0 | (2 << 3) | tmp1_ind;
3908 sljit_emit_op_custom(compiler, instruction, 4);
3912 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
3914 /* MOVD xmm, r/m32 */
3915 instruction[3] = 0xc0 | (3 << 3) | tmp1_ind;
3916 sljit_emit_op_custom(compiler, instruction, 4);
3919 /* PSHUFD xmm1, xmm2/m128, imm8 */
3920 instruction[2] = 0x70;
3921 instruction[3] = 0xc0 | (2 << 3) | 2;
3923 sljit_emit_op_custom(compiler, instruction, 5);
3927 /* PSHUFD xmm1, xmm2/m128, imm8 */
3928 instruction[3] = 0xc0 | (3 << 3) | 3;
3930 sljit_emit_op_custom(compiler, instruction, 5);
3933 OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf);
3934 OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
3936 /* MOVDQA xmm1, xmm2/m128 */
3937 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
3939 if (str_ptr_ind < 8)
3941 instruction[2] = 0x6f;
3942 instruction[3] = (0 << 3) | str_ptr_ind;
3943 sljit_emit_op_custom(compiler, instruction, 4);
3947 instruction[3] = (1 << 3) | str_ptr_ind;
3948 sljit_emit_op_custom(compiler, instruction, 4);
3953 instruction[1] = 0x41;
3954 instruction[2] = 0x0f;
3955 instruction[3] = 0x6f;
3956 instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
3957 sljit_emit_op_custom(compiler, instruction, 5);
3961 instruction[4] = (1 << 3) | str_ptr_ind;
3962 sljit_emit_op_custom(compiler, instruction, 5);
3964 instruction[1] = 0x0f;
3969 instruction[2] = 0x6f;
3970 instruction[3] = (0 << 3) | str_ptr_ind;
3971 sljit_emit_op_custom(compiler, instruction, 4);
3975 instruction[3] = (1 << 3) | str_ptr_ind;
3976 sljit_emit_op_custom(compiler, instruction, 4);
3983 /* POR xmm1, xmm2/m128 */
3984 instruction[2] = 0xeb;
3985 instruction[3] = 0xc0 | (0 << 3) | 3;
3986 sljit_emit_op_custom(compiler, instruction, 4);
3989 /* PCMPEQB/W/D xmm1, xmm2/m128 */
3990 instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
3991 instruction[3] = 0xc0 | (0 << 3) | 2;
3992 sljit_emit_op_custom(compiler, instruction, 4);
3996 instruction[3] = 0xc0 | (1 << 3) | 3;
3997 sljit_emit_op_custom(compiler, instruction, 4);
4000 /* PMOVMSKB reg, xmm */
4001 instruction[2] = 0xd7;
4002 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
4003 sljit_emit_op_custom(compiler, instruction, 4);
4007 OP1(SLJIT_MOV, TMP3, 0, TMP2, 0);
4008 instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
4009 sljit_emit_op_custom(compiler, instruction, 4);
4011 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4012 OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);
4015 OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0);
4017 /* BSF r32, r/m32 */
4018 instruction[0] = 0x0f;
4019 instruction[1] = 0xbc;
4020 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
4021 sljit_emit_op_custom(compiler, instruction, 3);
4023 nomatch = JUMP(SLJIT_ZERO);
4025 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4026 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4027 quit[1] = JUMP(SLJIT_JUMP);
4032 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
4033 quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4035 /* Second part (aligned) */
4037 instruction[0] = 0x66;
4038 instruction[1] = 0x0f;
4040 /* MOVDQA xmm1, xmm2/m128 */
4041 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
4043 if (str_ptr_ind < 8)
4045 instruction[2] = 0x6f;
4046 instruction[3] = (0 << 3) | str_ptr_ind;
4047 sljit_emit_op_custom(compiler, instruction, 4);
4051 instruction[3] = (1 << 3) | str_ptr_ind;
4052 sljit_emit_op_custom(compiler, instruction, 4);
4057 instruction[1] = 0x41;
4058 instruction[2] = 0x0f;
4059 instruction[3] = 0x6f;
4060 instruction[4] = (0 << 3) | (str_ptr_ind & 0x7);
4061 sljit_emit_op_custom(compiler, instruction, 5);
4065 instruction[4] = (1 << 3) | str_ptr_ind;
4066 sljit_emit_op_custom(compiler, instruction, 5);
4068 instruction[1] = 0x0f;
4073 instruction[2] = 0x6f;
4074 instruction[3] = (0 << 3) | str_ptr_ind;
4075 sljit_emit_op_custom(compiler, instruction, 4);
4079 instruction[3] = (1 << 3) | str_ptr_ind;
4080 sljit_emit_op_custom(compiler, instruction, 4);
4087 /* POR xmm1, xmm2/m128 */
4088 instruction[2] = 0xeb;
4089 instruction[3] = 0xc0 | (0 << 3) | 3;
4090 sljit_emit_op_custom(compiler, instruction, 4);
4093 /* PCMPEQB/W/D xmm1, xmm2/m128 */
4094 instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
4095 instruction[3] = 0xc0 | (0 << 3) | 2;
4096 sljit_emit_op_custom(compiler, instruction, 4);
4100 instruction[3] = 0xc0 | (1 << 3) | 3;
4101 sljit_emit_op_custom(compiler, instruction, 4);
4104 /* PMOVMSKB reg, xmm */
4105 instruction[2] = 0xd7;
4106 instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
4107 sljit_emit_op_custom(compiler, instruction, 4);
4111 instruction[3] = 0xc0 | (tmp2_ind << 3) | 1;
4112 sljit_emit_op_custom(compiler, instruction, 4);
4114 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4117 /* BSF r32, r/m32 */
4118 instruction[0] = 0x0f;
4119 instruction[1] = 0xbc;
4120 instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
4121 sljit_emit_op_custom(compiler, instruction, 3);
4123 JUMPTO(SLJIT_ZERO, start);
4125 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4128 SET_LABEL(quit[0], start);
4129 SET_LABEL(quit[1], start);
4130 SET_LABEL(quit[2], start);
4133 #undef SSE2_COMPARE_TYPE_INDEX
4137 static void fast_forward_first_char2(compiler_common *common, pcre_uchar char1, pcre_uchar char2, sljit_s32 offset)
4140 struct sljit_label *start;
4141 struct sljit_jump *quit;
4142 struct sljit_jump *found;
4144 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4145 struct sljit_label *utf_start = NULL;
4146 struct sljit_jump *utf_quit = NULL;
4148 BOOL has_match_end = (common->match_end_ptr != 0);
4151 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4155 OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
4157 OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, SLJIT_IMM, IN_UCHARS(offset + 1));
4158 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
4159 if (sljit_x86_is_cmov_available())
4161 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0);
4162 sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0);
4166 quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0);
4167 OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4172 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4173 if (common->utf && offset > 0)
4174 utf_start = LABEL();
4177 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
4179 /* SSE2 accelerated first character search. */
4181 if (sljit_x86_is_sse2_available())
4183 fast_forward_first_char2_sse2(common, char1, char2);
4185 SLJIT_ASSERT(common->mode == JIT_COMPILE || offset == 0);
4186 if (common->mode == JIT_COMPILE)
4188 /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */
4189 SLJIT_ASSERT(common->forced_quit_label == NULL);
4190 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
4191 add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4193 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4194 if (common->utf && offset > 0)
4196 SLJIT_ASSERT(common->mode == JIT_COMPILE);
4198 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
4199 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4200 #if defined COMPILE_PCRE8
4201 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
4202 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
4203 #elif defined COMPILE_PCRE16
4204 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4205 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
4207 #error "Unknown code width"
4209 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4214 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4216 else if (sljit_x86_is_cmov_available())
4218 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
4219 sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0);
4223 quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
4224 OP1(SLJIT_MOV, STR_PTR, 0, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0);
4229 OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4235 quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4238 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4241 found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1);
4244 mask = char1 ^ char2;
4245 if (is_powerof2(mask))
4247 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
4248 found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask);
4252 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1);
4253 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
4254 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2);
4255 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4256 found = JUMP(SLJIT_NOT_ZERO);
4260 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4261 CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start);
4263 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4264 if (common->utf && offset > 0)
4265 utf_quit = JUMP(SLJIT_JUMP);
4270 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4271 if (common->utf && offset > 0)
4273 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
4274 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4275 #if defined COMPILE_PCRE8
4276 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
4277 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start);
4278 #elif defined COMPILE_PCRE16
4279 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4280 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start);
4282 #error "Unknown code width"
4284 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4293 quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
4294 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4296 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4298 OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4302 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
4305 static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)
4308 struct sljit_label *start;
4309 struct sljit_jump *quit;
4310 struct sljit_jump *match;
4311 /* bytes[0] represent the number of characters between 0
4312 and MAX_N_BYTES - 1, 255 represents any character. */
4313 pcre_uchar chars[MAX_N_CHARS * MAX_DIFF_CHARS];
4316 pcre_uchar *char_set, *char_set_end;
4318 int range_right = -1, range_len;
4319 sljit_u8 *update_table = NULL;
4321 sljit_u32 rec_count;
4323 for (i = 0; i < MAX_N_CHARS; i++)
4324 chars[i * MAX_DIFF_CHARS] = 0;
4327 max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);
4333 /* Prevent compiler "uninitialized" warning */
4335 range_len = 4 /* minimum length */ - 1;
4336 for (i = 0; i <= max; i++)
4338 if (in_range && (i - from) > range_len && (chars[(i - 1) * MAX_DIFF_CHARS] < 255))
4340 range_len = i - from;
4341 range_right = i - 1;
4344 if (i < max && chars[i * MAX_DIFF_CHARS] < 255)
4346 SLJIT_ASSERT(chars[i * MAX_DIFF_CHARS] > 0);
4357 if (range_right >= 0)
4359 update_table = (sljit_u8 *)allocate_read_only_data(common, 256);
4360 if (update_table == NULL)
4362 memset(update_table, IN_UCHARS(range_len), 256);
4364 for (i = 0; i < range_len; i++)
4366 char_set = chars + ((range_right - i) * MAX_DIFF_CHARS);
4367 SLJIT_ASSERT(char_set[0] > 0 && char_set[0] < 255);
4368 char_set_end = char_set + char_set[0];
4370 while (char_set <= char_set_end)
4372 if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))
4373 update_table[(*char_set) & 0xff] = IN_UCHARS(i);
4381 for (i = 0; i < max; i++)
4385 if (chars[i * MAX_DIFF_CHARS] <= 2)
4388 else if (chars[offset * MAX_DIFF_CHARS] == 2 && chars[i * MAX_DIFF_CHARS] <= 2)
4390 if (chars[i * MAX_DIFF_CHARS] == 1)
4394 mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2];
4395 if (!is_powerof2(mask))
4397 mask = chars[i * MAX_DIFF_CHARS + 1] ^ chars[i * MAX_DIFF_CHARS + 2];
4398 if (is_powerof2(mask))
4405 if (range_right < 0)
4409 SLJIT_ASSERT(chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2);
4410 /* Works regardless the value is 1 or 2. */
4411 mask = chars[offset * MAX_DIFF_CHARS + chars[offset * MAX_DIFF_CHARS]];
4412 fast_forward_first_char2(common, chars[offset * MAX_DIFF_CHARS + 1], mask, offset);
4416 if (range_right == offset)
4419 SLJIT_ASSERT(offset == -1 || (chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2));
4422 SLJIT_ASSERT(max > 0);
4423 if (common->match_end_ptr != 0)
4425 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4426 OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
4427 OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
4428 quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0);
4429 OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
4433 OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
4435 SLJIT_ASSERT(range_right >= 0);
4437 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
4438 OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
4442 quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4444 #if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
4445 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
4447 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
4450 #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
4451 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
4453 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
4455 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4456 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
4460 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset));
4461 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4463 if (chars[offset * MAX_DIFF_CHARS] == 1)
4464 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1], start);
4467 mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2];
4468 if (is_powerof2(mask))
4470 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask);
4471 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1] | mask, start);
4475 match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1]);
4476 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 2], start);
4482 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
4483 if (common->utf && offset != 0)
4487 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4488 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4491 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4492 #if defined COMPILE_PCRE8
4493 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
4494 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, start);
4495 #elif defined COMPILE_PCRE16
4496 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4497 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, start);
4499 #error "Unknown code width"
4502 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4507 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4511 if (common->match_end_ptr != 0)
4513 if (range_right >= 0)
4514 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4515 OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4516 if (range_right >= 0)
4518 quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
4519 OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
4524 OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
4529 #undef MAX_DIFF_CHARS
4531 static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless)
4538 oc = TABLE_GET(first_char, common->fcc, first_char);
4539 #if defined SUPPORT_UCP && !defined COMPILE_PCRE8
4540 if (first_char > 127 && common->utf)
4541 oc = UCD_OTHERCASE(first_char);
4545 fast_forward_first_char2(common, first_char, oc, 0);
4548 static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
4551 struct sljit_label *loop;
4552 struct sljit_jump *lastchar;
4553 struct sljit_jump *firstchar;
4554 struct sljit_jump *quit;
4555 struct sljit_jump *foundcr = NULL;
4556 struct sljit_jump *notfoundnl;
4557 jump_list *newline = NULL;
4559 if (common->match_end_ptr != 0)
4561 OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
4562 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4565 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4567 lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4568 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4569 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
4570 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4571 firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
4573 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
4574 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
4575 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL);
4576 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4577 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
4579 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4582 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4583 quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4584 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4585 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4586 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
4587 CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
4590 JUMPHERE(firstchar);
4593 if (common->match_end_ptr != 0)
4594 OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4598 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4599 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
4600 firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
4601 skip_char_back(common);
4604 common->ff_newline_shortcut = loop;
4606 read_char_range(common, common->nlmin, common->nlmax, TRUE);
4607 lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4608 if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
4609 foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
4610 check_newlinechar(common, common->nltype, &newline, FALSE);
4611 set_jumps(newline, loop);
4613 if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
4615 quit = JUMP(SLJIT_JUMP);
4617 notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4618 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4619 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
4620 OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
4621 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4622 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
4624 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4625 JUMPHERE(notfoundnl);
4629 JUMPHERE(firstchar);
4631 if (common->match_end_ptr != 0)
4632 OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
4635 static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
4637 static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_u8 *start_bits)
4640 struct sljit_label *start;
4641 struct sljit_jump *quit;
4642 struct sljit_jump *found = NULL;
4643 jump_list *matches = NULL;
4644 #ifndef COMPILE_PCRE8
4645 struct sljit_jump *jump;
4648 if (common->match_end_ptr != 0)
4650 OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
4651 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
4655 quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4656 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4659 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4662 if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
4664 #ifndef COMPILE_PCRE8
4665 jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255);
4666 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
4669 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4670 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4671 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
4672 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4673 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4674 found = JUMP(SLJIT_NOT_ZERO);
4679 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
4681 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4683 #if defined COMPILE_PCRE8
4686 CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
4687 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4688 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4690 #elif defined COMPILE_PCRE16
4693 CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
4694 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4695 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4696 OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
4697 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4698 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4700 #endif /* COMPILE_PCRE[8|16] */
4701 #endif /* SUPPORT_UTF */
4702 JUMPTO(SLJIT_JUMP, start);
4705 if (matches != NULL)
4706 set_jumps(matches, LABEL());
4709 if (common->match_end_ptr != 0)
4710 OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
4713 static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
4716 struct sljit_label *loop;
4717 struct sljit_jump *toolong;
4718 struct sljit_jump *alreadyfound;
4719 struct sljit_jump *found;
4720 struct sljit_jump *foundoc = NULL;
4721 struct sljit_jump *notfound;
4724 SLJIT_ASSERT(common->req_char_ptr != 0);
4725 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
4726 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
4727 toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0);
4728 alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
4731 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4733 OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
4736 notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0);
4738 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
4742 oc = TABLE_GET(req_char, common->fcc, req_char);
4743 #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
4744 if (req_char > 127 && common->utf)
4745 oc = UCD_OTHERCASE(req_char);
4749 found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
4752 bit = req_char ^ oc;
4753 if (is_powerof2(bit))
4755 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
4756 found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
4760 found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
4761 foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
4764 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
4765 JUMPTO(SLJIT_JUMP, loop);
4770 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
4771 JUMPHERE(alreadyfound);
4776 static void do_revertframes(compiler_common *common)
4779 struct sljit_jump *jump;
4780 struct sljit_label *mainloop;
4782 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
4783 OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
4784 GET_LOCAL_BASE(TMP3, 0, 0);
4786 /* Drop frames until we reach STACK_TOP. */
4788 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
4789 OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
4790 jump = JUMP(SLJIT_SIG_LESS_EQUAL);
4792 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
4793 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
4794 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
4795 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
4796 JUMPTO(SLJIT_JUMP, mainloop);
4799 jump = JUMP(SLJIT_SIG_LESS);
4800 /* End of dropping frames. */
4801 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4804 OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
4805 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
4806 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
4807 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
4808 JUMPTO(SLJIT_JUMP, mainloop);
4811 static void check_wordboundary(compiler_common *common)
4814 struct sljit_jump *skipread;
4815 jump_list *skipread_list = NULL;
4816 #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
4817 struct sljit_jump *jump;
4820 SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
4822 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
4823 /* Get type of the previous char, and put it to LOCALS1. */
4824 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4825 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4826 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0);
4827 skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
4828 skip_char_back(common);
4829 check_start_used_ptr(common);
4832 /* Testing char type. */
4834 if (common->use_ucp)
4836 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
4837 jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
4838 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4839 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
4840 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4841 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
4842 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
4843 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4844 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
4846 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
4851 #ifndef COMPILE_PCRE8
4852 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4853 #elif defined SUPPORT_UTF
4854 /* Here LOCALS1 has already been zeroed. */
4857 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4858 #endif /* COMPILE_PCRE8 */
4859 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
4860 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
4861 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4862 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
4863 #ifndef COMPILE_PCRE8
4865 #elif defined SUPPORT_UTF
4868 #endif /* COMPILE_PCRE8 */
4872 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
4873 check_str_end(common, &skipread_list);
4874 peek_char(common, READ_CHAR_MAX);
4876 /* Testing char type. This is a code duplication. */
4878 if (common->use_ucp)
4880 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
4881 jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
4882 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4883 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
4884 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4885 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
4886 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
4887 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4888 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
4894 #ifndef COMPILE_PCRE8
4895 /* TMP2 may be destroyed by peek_char. */
4896 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
4897 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4898 #elif defined SUPPORT_UTF
4899 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
4902 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4904 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
4905 OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
4906 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
4907 #ifndef COMPILE_PCRE8
4909 #elif defined SUPPORT_UTF
4912 #endif /* COMPILE_PCRE8 */
4914 set_jumps(skipread_list, LABEL());
4916 OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
4917 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
4920 static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
4922 /* May destroy TMP1. */
4924 int ranges[MAX_RANGE_SIZE];
4925 sljit_u8 bit, cbit, all;
4926 int i, byte, length = 0;
4928 bit = bits[0] & 0x1;
4929 /* All bits will be zero or one (since bit is zero or one). */
4932 for (i = 0; i < 256; )
4935 if ((i & 0x7) == 0 && bits[byte] == all)
4939 cbit = (bits[byte] >> (i & 0x7)) & 0x1;
4942 if (length >= MAX_RANGE_SIZE)
4953 if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
4955 if (length >= MAX_RANGE_SIZE)
4957 ranges[length] = 256;
4961 if (length < 0 || length > 4)
4964 bit = bits[0] & 0x1;
4965 if (invert) bit ^= 0x1;
4967 /* No character is accepted. */
4968 if (length == 0 && bit == 0)
4969 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4974 /* When bit != 0, all characters are accepted. */
4978 add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4982 if (ranges[0] + 1 != ranges[1])
4984 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4985 add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4988 add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4994 add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
4995 if (ranges[0] + 1 != ranges[1])
4997 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4998 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5001 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
5005 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
5006 if (ranges[1] + 1 != ranges[2])
5008 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
5009 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
5012 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
5016 if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
5017 && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
5018 && (ranges[1] & (ranges[2] - ranges[0])) == 0
5019 && is_powerof2(ranges[2] - ranges[0]))
5021 SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
5022 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
5023 if (ranges[2] + 1 != ranges[3])
5025 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
5026 add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
5029 add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
5036 if (ranges[0] + 1 != ranges[1])
5038 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
5039 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5043 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
5045 if (ranges[2] + 1 != ranges[3])
5047 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
5048 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
5051 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
5055 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
5056 add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
5057 if (ranges[1] + 1 != ranges[2])
5059 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
5060 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
5063 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
5067 SLJIT_ASSERT_STOP();
5072 static void check_anynewline(compiler_common *common)
5074 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
5077 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5079 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
5080 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
5081 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5082 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
5083 #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5084 #ifdef COMPILE_PCRE8
5088 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5089 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
5090 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
5091 #ifdef COMPILE_PCRE8
5094 #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
5095 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5096 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5099 static void check_hspace(compiler_common *common)
5101 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
5104 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5106 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
5107 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5108 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
5109 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5110 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
5111 #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5112 #ifdef COMPILE_PCRE8
5116 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5117 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
5118 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5119 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
5120 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5121 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
5122 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
5123 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5124 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
5125 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5126 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
5127 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5128 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
5129 #ifdef COMPILE_PCRE8
5132 #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
5133 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5135 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5138 static void check_vspace(compiler_common *common)
5140 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
5143 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5145 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
5146 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
5147 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5148 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
5149 #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5150 #ifdef COMPILE_PCRE8
5154 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5155 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
5156 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
5157 #ifdef COMPILE_PCRE8
5160 #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
5161 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5163 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5166 #define CHAR1 STR_END
5167 #define CHAR2 STACK_TOP
5169 static void do_casefulcmp(compiler_common *common)
5172 struct sljit_jump *jump;
5173 struct sljit_label *label;
5175 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5176 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
5177 OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
5178 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
5179 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
5180 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5183 OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
5184 OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
5185 jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
5186 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
5187 JUMPTO(SLJIT_NOT_ZERO, label);
5190 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5191 OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
5192 OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
5193 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5196 #define LCC_TABLE STACK_LIMIT
5198 static void do_caselesscmp(compiler_common *common)
5201 struct sljit_jump *jump;
5202 struct sljit_label *label;
5204 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
5205 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
5207 OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
5208 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
5209 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
5210 OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
5211 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
5212 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5215 OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
5216 OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
5217 #ifndef COMPILE_PCRE8
5218 jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
5220 OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
5221 #ifndef COMPILE_PCRE8
5223 jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
5225 OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
5226 #ifndef COMPILE_PCRE8
5229 jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
5230 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
5231 JUMPTO(SLJIT_NOT_ZERO, label);
5234 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5235 OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
5236 OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
5237 OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
5238 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
5245 #if defined SUPPORT_UTF && defined SUPPORT_UCP
5247 static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
5249 /* This function would be ineffective to do in JIT level. */
5251 const pcre_uchar *src2 = args->uchar_ptr;
5252 const pcre_uchar *end2 = args->end;
5253 const ucd_record *ur;
5254 const sljit_u32 *pp;
5259 return (pcre_uchar*)1;
5260 GETCHARINC(c1, src1);
5261 GETCHARINC(c2, src2);
5263 if (c1 != c2 && c1 != c2 + ur->other_case)
5265 pp = PRIV(ucd_caseless_sets) + ur->caseset;
5268 if (c1 < *pp) return NULL;
5269 if (c1 == *pp++) break;
5276 #endif /* SUPPORT_UTF && SUPPORT_UCP */
5278 static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
5279 compare_context *context, jump_list **backtracks)
5282 unsigned int othercasebit = 0;
5283 pcre_uchar *othercasechar = NULL;
5288 if (caseless && char_has_othercase(common, cc))
5290 othercasebit = char_get_othercase_bit(common, cc);
5291 SLJIT_ASSERT(othercasebit);
5292 /* Extracting bit difference info. */
5293 #if defined COMPILE_PCRE8
5294 othercasechar = cc + (othercasebit >> 8);
5295 othercasebit &= 0xff;
5296 #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5297 /* Note that this code only handles characters in the BMP. If there
5298 ever are characters outside the BMP whose othercase differs in only one
5299 bit from itself (there currently are none), this code will need to be
5300 revised for COMPILE_PCRE32. */
5301 othercasechar = cc + (othercasebit >> 9);
5302 if ((othercasebit & 0x100) != 0)
5303 othercasebit = (othercasebit & 0xff) << 8;
5305 othercasebit &= 0xff;
5306 #endif /* COMPILE_PCRE[8|16|32] */
5309 if (context->sourcereg == -1)
5311 #if defined COMPILE_PCRE8
5312 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
5313 if (context->length >= 4)
5314 OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
5315 else if (context->length >= 2)
5316 OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
5319 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
5320 #elif defined COMPILE_PCRE16
5321 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
5322 if (context->length >= 4)
5323 OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
5326 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
5327 #elif defined COMPILE_PCRE32
5328 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
5329 #endif /* COMPILE_PCRE[8|16|32] */
5330 context->sourcereg = TMP2;
5335 if (common->utf && HAS_EXTRALEN(*cc))
5336 utflength += GET_EXTRALEN(*cc);
5342 context->length -= IN_UCHARS(1);
5343 #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
5345 /* Unaligned read is supported. */
5346 if (othercasebit != 0 && othercasechar == cc)
5348 context->c.asuchars[context->ucharptr] = *cc | othercasebit;
5349 context->oc.asuchars[context->ucharptr] = othercasebit;
5353 context->c.asuchars[context->ucharptr] = *cc;
5354 context->oc.asuchars[context->ucharptr] = 0;
5356 context->ucharptr++;
5358 #if defined COMPILE_PCRE8
5359 if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
5361 if (context->ucharptr >= 2 || context->length == 0)
5364 if (context->length >= 4)
5365 OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
5366 else if (context->length >= 2)
5367 OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
5368 #if defined COMPILE_PCRE8
5369 else if (context->length >= 1)
5370 OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
5371 #endif /* COMPILE_PCRE8 */
5372 context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
5374 switch(context->ucharptr)
5376 case 4 / sizeof(pcre_uchar):
5377 if (context->oc.asint != 0)
5378 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
5379 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
5382 case 2 / sizeof(pcre_uchar):
5383 if (context->oc.asushort != 0)
5384 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
5385 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
5388 #ifdef COMPILE_PCRE8
5390 if (context->oc.asbyte != 0)
5391 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
5392 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
5397 SLJIT_ASSERT_STOP();
5400 context->ucharptr = 0;
5405 /* Unaligned read is unsupported or in 32 bit mode. */
5406 if (context->length >= 1)
5407 OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
5409 context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
5411 if (othercasebit != 0 && othercasechar == cc)
5413 OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
5414 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
5417 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
5425 while (utflength > 0);
5431 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
5433 #define SET_TYPE_OFFSET(value) \
5434 if ((value) != typeoffset) \
5436 if ((value) < typeoffset) \
5437 OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
5439 OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
5441 typeoffset = (value);
5443 #define SET_CHAR_OFFSET(value) \
5444 if ((value) != charoffset) \
5446 if ((value) < charoffset) \
5447 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
5449 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
5451 charoffset = (value);
5453 static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks, BOOL check_str_ptr);
5455 static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
5458 jump_list *found = NULL;
5459 jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
5460 sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
5461 struct sljit_jump *jump = NULL;
5462 pcre_uchar *ccbegin;
5463 int compares, invertcmp, numberofcmps;
5464 #if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
5465 BOOL utf = common->utf;
5469 BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
5470 BOOL charsaved = FALSE;
5472 const sljit_u32 *other_cases;
5473 sljit_uw typeoffset;
5476 /* Scanning the necessary info. */
5480 if (cc[-1] & XCL_MAP)
5483 cc += 32 / sizeof(pcre_uchar);
5486 while (*cc != XCL_END)
5489 if (*cc == XCL_SINGLE)
5492 GETCHARINCTEST(c, cc);
5493 if (c > max) max = c;
5494 if (c < min) min = c;
5499 else if (*cc == XCL_RANGE)
5502 GETCHARINCTEST(c, cc);
5503 if (c < min) min = c;
5504 GETCHARINCTEST(c, cc);
5505 if (c > max) max = c;
5513 SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
5515 if (*cc == PT_CLIST)
5517 other_cases = PRIV(ucd_caseless_sets) + cc[1];
5518 while (*other_cases != NOTACHAR)
5520 if (*other_cases > max) max = *other_cases;
5521 if (*other_cases < min) min = *other_cases;
5527 max = READ_CHAR_MAX;
5534 /* Any either accepts everything or ignored. */
5535 if (cc[-1] == XCL_PROP)
5537 compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE);
5538 if (list == backtracks)
5539 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
5571 SLJIT_ASSERT_STOP();
5578 SLJIT_ASSERT(compares > 0);
5580 /* We are not necessary in utf mode even in 8 bit mode. */
5582 read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
5584 if ((cc[-1] & XCL_HASPROP) == 0)
5586 if ((cc[-1] & XCL_MAP) != 0)
5588 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5589 if (!check_class_ranges(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found))
5591 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
5592 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
5593 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
5594 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5595 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
5596 add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
5599 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
5602 cc += 32 / sizeof(pcre_uchar);
5606 OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
5607 add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));
5610 else if ((cc[-1] & XCL_MAP) != 0)
5612 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
5616 if (!check_class_ranges(common, (const sljit_u8 *)cc, FALSE, TRUE, list))
5618 #ifdef COMPILE_PCRE8
5622 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5624 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
5625 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
5626 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
5627 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5628 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
5629 add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
5631 #ifdef COMPILE_PCRE8
5637 OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
5638 cc += 32 / sizeof(pcre_uchar);
5642 if (needstype || needsscript)
5644 if (needschar && !charsaved)
5645 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
5647 OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
5648 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
5649 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
5650 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
5651 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5652 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
5653 OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
5655 /* Before anything else, we deal with scripts. */
5658 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
5659 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
5663 while (*cc != XCL_END)
5665 if (*cc == XCL_SINGLE)
5668 GETCHARINCTEST(c, cc);
5670 else if (*cc == XCL_RANGE)
5673 GETCHARINCTEST(c, cc);
5674 GETCHARINCTEST(c, cc);
5678 SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
5683 invertcmp = (compares == 0 && list != backtracks);
5684 if (cc[-1] == XCL_NOTPROP)
5686 jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]);
5687 add_jump(compiler, compares > 0 ? list : backtracks, jump);
5698 OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
5705 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
5706 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
5710 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
5711 OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
5712 typereg = RETURN_ADDR;
5718 /* Generating code. */
5725 while (*cc != XCL_END)
5728 invertcmp = (compares == 0 && list != backtracks);
5731 if (*cc == XCL_SINGLE)
5734 GETCHARINCTEST(c, cc);
5736 if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
5738 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5739 OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL);
5742 else if (numberofcmps > 0)
5744 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5745 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5746 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5751 jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5755 else if (*cc == XCL_RANGE)
5758 GETCHARINCTEST(c, cc);
5760 GETCHARINCTEST(c, cc);
5762 if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
5764 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5765 OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
5768 else if (numberofcmps > 0)
5770 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5771 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5772 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5777 jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5784 SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
5785 if (*cc == XCL_NOTPROP)
5792 jump = JUMP(SLJIT_JUMP);
5796 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
5797 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5798 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
5799 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5800 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
5801 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5802 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5806 c = PRIV(ucp_typerange)[(int)cc[1] * 2];
5808 jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
5812 jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
5823 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
5824 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5826 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
5827 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5829 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
5830 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5832 SET_TYPE_OFFSET(ucp_Zl);
5833 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
5834 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5835 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5839 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
5840 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5844 SET_TYPE_OFFSET(ucp_Ll);
5845 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
5846 OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
5847 SET_TYPE_OFFSET(ucp_Nd);
5848 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
5849 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5850 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5854 other_cases = PRIV(ucd_caseless_sets) + cc[1];
5856 /* At least three characters are required.
5857 Otherwise this case would be handled by the normal code path. */
5858 SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
5859 SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
5861 /* Optimizing character pairs, if their difference is power of 2. */
5862 if (is_powerof2(other_cases[1] ^ other_cases[0]))
5864 if (charoffset == 0)
5865 OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
5868 OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
5869 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
5871 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
5872 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5875 else if (is_powerof2(other_cases[2] ^ other_cases[1]))
5877 if (charoffset == 0)
5878 OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
5881 OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
5882 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
5884 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
5885 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5887 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
5888 OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5894 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
5895 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5898 while (*other_cases != NOTACHAR)
5900 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
5901 OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5903 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5907 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
5908 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5909 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
5910 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5911 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
5912 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5914 SET_CHAR_OFFSET(0xa0);
5915 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
5916 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5918 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
5919 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL);
5920 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5924 /* C and Z groups are the farthest two groups. */
5925 SET_TYPE_OFFSET(ucp_Ll);
5926 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
5927 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
5929 jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
5931 /* In case of ucp_Cf, we overwrite the result. */
5932 SET_CHAR_OFFSET(0x2066);
5933 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
5934 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5936 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
5937 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5939 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
5940 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5943 jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
5947 /* C and Z groups are the farthest two groups. */
5948 SET_TYPE_OFFSET(ucp_Ll);
5949 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
5950 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
5952 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
5953 OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
5955 jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
5957 /* In case of ucp_Cf, we overwrite the result. */
5958 SET_CHAR_OFFSET(0x2066);
5959 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
5960 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5962 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
5963 OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5966 jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
5970 SET_TYPE_OFFSET(ucp_Sc);
5971 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
5972 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5975 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
5976 OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5978 SET_TYPE_OFFSET(ucp_Pc);
5979 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
5980 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5981 jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5985 SLJIT_ASSERT_STOP();
5993 add_jump(compiler, compares > 0 ? list : backtracks, jump);
5997 set_jumps(found, LABEL());
6000 #undef SET_TYPE_OFFSET
6001 #undef SET_CHAR_OFFSET
6005 static pcre_uchar *compile_simple_assertion_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
6009 struct sljit_jump *jump[4];
6011 struct sljit_label *label;
6012 #endif /* SUPPORT_UTF */
6017 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6018 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
6019 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
6023 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6024 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6025 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
6028 case OP_NOT_WORD_BOUNDARY:
6029 case OP_WORD_BOUNDARY:
6030 add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
6031 add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
6035 /* Requires rather complex checks. */
6036 jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
6037 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
6039 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
6040 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
6041 if (common->mode == JIT_COMPILE)
6042 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
6045 jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
6046 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
6047 OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS);
6048 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
6049 OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
6050 add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
6051 check_partial(common, TRUE);
6052 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6055 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6056 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
6057 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
6059 else if (common->nltype == NLTYPE_FIXED)
6061 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6062 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
6063 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
6064 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
6068 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
6069 jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
6070 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
6071 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
6072 jump[2] = JUMP(SLJIT_GREATER);
6073 add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
6075 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6076 jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
6077 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6080 if (common->nltype == NLTYPE_ANYCRLF)
6082 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6083 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));
6084 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
6088 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
6089 read_char_range(common, common->nlmin, common->nlmax, TRUE);
6090 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
6091 add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
6092 add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
6093 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
6099 check_partial(common, FALSE);
6103 add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
6104 check_partial(common, FALSE);
6108 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
6109 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
6110 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6112 if (!common->endonly)
6113 compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
6116 add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
6117 check_partial(common, FALSE);
6122 jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
6123 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
6124 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
6125 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6126 check_partial(common, FALSE);
6127 jump[0] = JUMP(SLJIT_JUMP);
6130 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
6132 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
6133 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
6134 if (common->mode == JIT_COMPILE)
6135 add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));
6138 jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
6139 /* STR_PTR = STR_END - IN_UCHARS(1) */
6140 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
6141 check_partial(common, TRUE);
6142 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6146 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
6147 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
6148 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
6152 peek_char(common, common->nlmax);
6153 check_newlinechar(common, common->nltype, backtracks, FALSE);
6159 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
6160 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
6161 add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
6162 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
6163 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6167 OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
6168 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
6169 jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);
6170 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
6171 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6172 jump[0] = JUMP(SLJIT_JUMP);
6175 add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
6176 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
6178 OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
6179 add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0));
6180 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
6181 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
6182 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
6183 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
6187 skip_char_back(common);
6188 read_char_range(common, common->nlmin, common->nlmax, TRUE);
6189 check_newlinechar(common, common->nltype, backtracks, FALSE);
6195 length = GET(cc, 0);
6197 return cc + LINK_SIZE;
6198 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6202 OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
6203 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
6205 add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
6206 skip_char_back(common);
6207 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
6208 JUMPTO(SLJIT_NOT_ZERO, label);
6213 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
6214 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
6215 add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));
6217 check_start_used_ptr(common);
6218 return cc + LINK_SIZE;
6220 SLJIT_ASSERT_STOP();
6224 static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks, BOOL check_str_ptr)
6228 unsigned int c, oc, bit;
6229 compare_context context;
6230 struct sljit_jump *jump[3];
6231 jump_list *end_list;
6233 struct sljit_label *label;
6235 pcre_uchar propdata[5];
6237 #endif /* SUPPORT_UTF */
6243 /* Digits are usually 0-9, so it is worth to optimize them. */
6245 detect_partial_match(common, backtracks);
6246 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6247 if (common->utf && is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
6248 read_char7_type(common, type == OP_NOT_DIGIT);
6251 read_char8_type(common, type == OP_NOT_DIGIT);
6252 /* Flip the starting bit in the negative case. */
6253 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
6254 add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
6257 case OP_NOT_WHITESPACE:
6260 detect_partial_match(common, backtracks);
6261 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6262 if (common->utf && is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE))
6263 read_char7_type(common, type == OP_NOT_WHITESPACE);
6266 read_char8_type(common, type == OP_NOT_WHITESPACE);
6267 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
6268 add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
6271 case OP_NOT_WORDCHAR:
6274 detect_partial_match(common, backtracks);
6275 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6276 if (common->utf && is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE))
6277 read_char7_type(common, type == OP_NOT_WORDCHAR);
6280 read_char8_type(common, type == OP_NOT_WORDCHAR);
6281 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
6282 add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
6287 detect_partial_match(common, backtracks);
6288 read_char_range(common, common->nlmin, common->nlmax, TRUE);
6289 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
6291 jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
6293 if (common->mode != JIT_PARTIAL_HARD_COMPILE)
6294 add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
6296 check_str_end(common, &end_list);
6298 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
6299 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
6300 set_jumps(end_list, LABEL());
6304 check_newlinechar(common, common->nltype, backtracks, TRUE);
6309 detect_partial_match(common, backtracks);
6313 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
6314 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6315 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
6316 #if defined COMPILE_PCRE8
6317 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
6318 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
6319 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
6320 #elif defined COMPILE_PCRE16
6321 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
6322 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
6323 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
6324 OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
6325 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6326 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
6329 #endif /* COMPILE_PCRE[8|16] */
6333 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6338 detect_partial_match(common, backtracks);
6339 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6346 propdata[0] = XCL_HASPROP;
6347 propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
6348 propdata[2] = cc[0];
6349 propdata[3] = cc[1];
6350 propdata[4] = XCL_END;
6352 detect_partial_match(common, backtracks);
6353 compile_xclass_matchingpath(common, propdata, backtracks);
6360 detect_partial_match(common, backtracks);
6361 read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
6362 jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
6363 /* We don't need to handle soft partial matching case. */
6365 if (common->mode != JIT_PARTIAL_HARD_COMPILE)
6366 add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
6368 check_str_end(common, &end_list);
6369 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
6370 jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
6371 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6372 jump[2] = JUMP(SLJIT_JUMP);
6374 check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
6375 set_jumps(end_list, LABEL());
6383 detect_partial_match(common, backtracks);
6384 read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
6385 add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
6386 add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
6392 detect_partial_match(common, backtracks);
6393 read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
6394 add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
6395 add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
6401 detect_partial_match(common, backtracks);
6403 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
6404 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
6405 /* Optimize register allocation: use a real register. */
6406 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
6407 OP1(SLJIT_MOV_U8, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
6410 jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
6411 OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
6413 add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
6414 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
6415 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
6417 OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
6418 OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
6419 OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
6420 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
6421 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
6422 JUMPTO(SLJIT_NOT_ZERO, label);
6424 OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
6426 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6428 if (common->mode == JIT_PARTIAL_HARD_COMPILE)
6430 jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
6431 /* Since we successfully read a char above, partial matching must occure. */
6432 check_partial(common, TRUE);
6442 if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
6444 if (common->mode == JIT_COMPILE && check_str_ptr
6445 && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
6447 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
6448 add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
6450 context.length = IN_UCHARS(length);
6451 context.sourcereg = -1;
6452 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
6453 context.ucharptr = 0;
6455 return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
6459 detect_partial_match(common, backtracks);
6469 if (type == OP_CHAR || !char_has_othercase(common, cc))
6471 read_char_range(common, c, c, FALSE);
6472 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
6475 oc = char_othercase(common, c);
6476 read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
6478 if (is_powerof2(bit))
6480 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
6481 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
6484 jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);
6485 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
6492 detect_partial_match(common, backtracks);
6497 #ifdef COMPILE_PCRE8
6501 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
6502 if (type == OP_NOT || !char_has_othercase(common, cc))
6503 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
6506 /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
6507 OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
6508 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
6510 /* Skip the variable-length character. */
6511 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
6512 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
6513 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
6514 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
6519 #endif /* COMPILE_PCRE8 */
6521 GETCHARLEN(c, cc, length);
6525 #endif /* SUPPORT_UTF */
6528 if (type == OP_NOT || !char_has_othercase(common, cc))
6530 read_char_range(common, c, c, TRUE);
6531 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
6535 oc = char_othercase(common, c);
6536 read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
6538 if (is_powerof2(bit))
6540 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
6541 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
6545 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
6546 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
6554 detect_partial_match(common, backtracks);
6556 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6557 bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255;
6558 read_char_range(common, 0, bit, type == OP_NCLASS);
6560 read_char_range(common, 0, 255, type == OP_NCLASS);
6563 if (check_class_ranges(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks))
6564 return cc + 32 / sizeof(pcre_uchar);
6566 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6570 jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);
6571 if (type == OP_CLASS)
6573 add_jump(compiler, backtracks, jump[0]);
6577 #elif !defined COMPILE_PCRE8
6578 jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
6579 if (type == OP_CLASS)
6581 add_jump(compiler, backtracks, jump[0]);
6584 #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
6586 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
6587 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
6588 OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
6589 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
6590 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
6591 add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
6593 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6594 if (jump[0] != NULL)
6597 return cc + 32 / sizeof(pcre_uchar);
6599 #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
6602 detect_partial_match(common, backtracks);
6603 compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
6604 return cc + GET(cc, 0) - 1;
6607 SLJIT_ASSERT_STOP();
6611 static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
6613 /* This function consumes at least one input character. */
6614 /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
6616 pcre_uchar *ccbegin = cc;
6617 compare_context context;
6630 if (common->utf && HAS_EXTRALEN(cc[1]))
6631 size += GET_EXTRALEN(cc[1]);
6634 else if (*cc == OP_CHARI)
6640 if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
6642 else if (HAS_EXTRALEN(cc[1]))
6643 size += GET_EXTRALEN(cc[1]);
6647 if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
6654 context.length += IN_UCHARS(size);
6656 while (size > 0 && context.length <= 128);
6659 if (context.length > 0)
6661 /* We have a fixed-length byte sequence. */
6662 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
6663 add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
6665 context.sourcereg = -1;
6666 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
6667 context.ucharptr = 0;
6669 do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
6673 /* A non-fixed length character will be checked if length == 0. */
6674 return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);
6677 /* Forward definitions. */
6678 static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
6679 static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
6681 #define PUSH_BACKTRACK(size, ccstart, error) \
6684 backtrack = sljit_alloc_memory(compiler, (size)); \
6685 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6687 memset(backtrack, 0, size); \
6688 backtrack->prev = parent->top; \
6689 backtrack->cc = (ccstart); \
6690 parent->top = backtrack; \
6694 #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
6697 backtrack = sljit_alloc_memory(compiler, (size)); \
6698 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6700 memset(backtrack, 0, size); \
6701 backtrack->prev = parent->top; \
6702 backtrack->cc = (ccstart); \
6703 parent->top = backtrack; \
6707 #define BACKTRACK_AS(type) ((type *)backtrack)
6709 static void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
6711 /* The OVECTOR offset goes to TMP2. */
6713 int count = GET2(cc, 1 + IMM2_SIZE);
6714 pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
6715 unsigned int offset;
6716 jump_list *found = NULL;
6718 SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
6720 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
6725 offset = GET2(slot, 0) << 1;
6726 GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
6727 add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
6728 slot += common->name_entry_size;
6731 offset = GET2(slot, 0) << 1;
6732 GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
6733 if (backtracks != NULL && !common->jscript_compat)
6734 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
6736 set_jumps(found, LABEL());
6739 static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
6742 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
6744 struct sljit_jump *jump = NULL;
6745 struct sljit_jump *partial;
6746 struct sljit_jump *nopartial;
6750 offset = GET2(cc, 1) << 1;
6751 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
6752 /* OVECTOR(1) contains the "string begin - 1" constant. */
6753 if (withchecks && !common->jscript_compat)
6754 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
6757 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
6759 #if defined SUPPORT_UTF && defined SUPPORT_UCP
6760 if (common->utf && *cc == OP_REFI)
6762 SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
6764 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
6766 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
6769 jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
6771 /* Needed to save important temporary registers. */
6772 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
6773 OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
6774 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
6775 sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
6776 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6777 if (common->mode == JIT_COMPILE)
6778 add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
6781 add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
6782 nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
6783 check_partial(common, FALSE);
6784 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6785 JUMPHERE(nopartial);
6787 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
6790 #endif /* SUPPORT_UTF && SUPPORT_UCP */
6793 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
6795 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
6798 jump = JUMP(SLJIT_ZERO);
6800 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
6801 partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
6802 if (common->mode == JIT_COMPILE)
6803 add_jump(compiler, backtracks, partial);
6805 add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
6806 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6808 if (common->mode != JIT_COMPILE)
6810 nopartial = JUMP(SLJIT_JUMP);
6812 /* TMP2 -= STR_END - STR_PTR */
6813 OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
6814 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
6815 partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);
6816 OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
6817 add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
6818 add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6820 check_partial(common, FALSE);
6821 add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6822 JUMPHERE(nopartial);
6829 add_jump(compiler, backtracks, jump);
6835 static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6838 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
6839 backtrack_common *backtrack;
6842 struct sljit_label *label;
6843 struct sljit_jump *zerolength;
6844 struct sljit_jump *jump = NULL;
6845 pcre_uchar *ccbegin = cc;
6846 int min = 0, max = 0;
6849 PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL);
6852 offset = GET2(cc, 1) << 1;
6855 type = cc[1 + IMM2_SIZE];
6857 SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
6858 minimize = (type & 0x1) != 0;
6865 cc += 1 + IMM2_SIZE + 1;
6871 cc += 1 + IMM2_SIZE + 1;
6877 cc += 1 + IMM2_SIZE + 1;
6881 min = GET2(cc, 1 + IMM2_SIZE + 1);
6882 max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
6883 cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
6886 SLJIT_ASSERT_STOP();
6894 allocate_stack(common, 2);
6896 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
6897 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6898 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
6899 /* Temporary release of STR_PTR. */
6900 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
6901 /* Handles both invalid and empty cases. Since the minimum repeat,
6902 is zero the invalid case is basically the same as an empty case. */
6904 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
6907 compile_dnref_search(common, ccbegin, NULL);
6908 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
6909 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
6910 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
6912 /* Restore if not zero length. */
6913 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
6917 allocate_stack(common, 1);
6919 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
6920 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6923 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
6924 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
6928 compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
6929 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
6930 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
6931 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
6935 if (min > 1 || max > 1)
6936 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
6940 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
6941 compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
6943 if (min > 1 || max > 1)
6945 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
6946 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6947 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
6949 CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);
6952 jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
6953 allocate_stack(common, 1);
6954 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6955 JUMPTO(SLJIT_JUMP, label);
6962 /* Includes min > 1 case as well. */
6963 allocate_stack(common, 1);
6964 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6965 JUMPTO(SLJIT_JUMP, label);
6968 JUMPHERE(zerolength);
6969 BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
6971 count_match(common);
6975 allocate_stack(common, ref ? 2 : 3);
6977 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
6978 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6979 if (type != OP_CRMINSTAR)
6980 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
6984 /* Handles both invalid and empty cases. Since the minimum repeat,
6985 is zero the invalid case is basically the same as an empty case. */
6987 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
6990 compile_dnref_search(common, ccbegin, NULL);
6991 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
6992 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
6993 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
6995 /* Length is non-zero, we can match real repeats. */
6996 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6997 jump = JUMP(SLJIT_JUMP);
7003 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
7004 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
7008 compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
7009 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
7010 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
7011 zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
7015 BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
7017 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
7020 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7021 compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
7022 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7026 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7027 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7028 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
7029 CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath);
7032 OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
7036 JUMPHERE(zerolength);
7038 count_match(common);
7042 static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7045 backtrack_common *backtrack;
7046 recurse_entry *entry = common->entries;
7047 recurse_entry *prev = NULL;
7048 sljit_sw start = GET(cc, 1);
7049 pcre_uchar *start_cc;
7050 BOOL needs_control_head;
7052 PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
7054 /* Inlining simple patterns. */
7055 if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
7057 start_cc = common->start + start;
7058 compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
7059 BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
7060 return cc + 1 + LINK_SIZE;
7063 while (entry != NULL)
7065 if (entry->start == start)
7068 entry = entry->next;
7073 entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
7074 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7077 entry->entry = NULL;
7078 entry->calls = NULL;
7079 entry->start = start;
7084 common->entries = entry;
7087 if (common->has_set_som && common->mark_ptr != 0)
7089 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
7090 allocate_stack(common, 2);
7091 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
7092 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7093 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
7095 else if (common->has_set_som || common->mark_ptr != 0)
7097 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
7098 allocate_stack(common, 1);
7099 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7102 if (entry->entry == NULL)
7103 add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
7105 JUMPTO(SLJIT_FAST_CALL, entry->entry);
7106 /* Leave if the match is failed. */
7107 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
7108 return cc + 1 + LINK_SIZE;
7111 static int SLJIT_CALL do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
7113 const pcre_uchar *begin = arguments->begin;
7114 int *offset_vector = arguments->offsets;
7115 int offset_count = arguments->offset_count;
7118 if (PUBL(callout) == NULL)
7121 callout_block->version = 2;
7122 callout_block->callout_data = arguments->callout_data;
7124 /* Offsets in subject. */
7125 callout_block->subject_length = arguments->end - arguments->begin;
7126 callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
7127 callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
7128 #if defined COMPILE_PCRE8
7129 callout_block->subject = (PCRE_SPTR)begin;
7130 #elif defined COMPILE_PCRE16
7131 callout_block->subject = (PCRE_SPTR16)begin;
7132 #elif defined COMPILE_PCRE32
7133 callout_block->subject = (PCRE_SPTR32)begin;
7136 /* Convert and copy the JIT offset vector to the offset_vector array. */
7137 callout_block->capture_top = 0;
7138 callout_block->offset_vector = offset_vector;
7139 for (i = 2; i < offset_count; i += 2)
7141 offset_vector[i] = jit_ovector[i] - begin;
7142 offset_vector[i + 1] = jit_ovector[i + 1] - begin;
7143 if (jit_ovector[i] >= begin)
7144 callout_block->capture_top = i;
7147 callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
7148 if (offset_count > 0)
7149 offset_vector[0] = -1;
7150 if (offset_count > 1)
7151 offset_vector[1] = -1;
7152 return (*PUBL(callout))(callout_block);
7155 /* Aligning to 8 byte. */
7156 #define CALLOUT_ARG_SIZE \
7157 (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
7159 #define CALLOUT_ARG_OFFSET(arg) \
7160 (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
7162 static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7165 backtrack_common *backtrack;
7167 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7169 allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
7171 SLJIT_ASSERT(common->capture_last_ptr != 0);
7172 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
7173 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7174 OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
7175 OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
7177 /* These pointer sized fields temporarly stores internal variables. */
7178 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
7179 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
7180 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
7182 if (common->mark_ptr != 0)
7183 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
7184 OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
7185 OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
7186 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
7188 /* Needed to save important temporary registers. */
7189 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
7190 OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
7191 GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
7192 sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
7193 OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
7194 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
7195 free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
7197 /* Check return value. */
7198 OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
7199 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
7200 if (common->forced_quit_label == NULL)
7201 add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS));
7203 JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label);
7204 return cc + 2 + 2 * LINK_SIZE;
7207 #undef CALLOUT_ARG_SIZE
7208 #undef CALLOUT_ARG_OFFSET
7210 static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(pcre_uchar *cc)
7216 case OP_NOT_WORD_BOUNDARY:
7217 case OP_WORD_BOUNDARY:
7224 cc += PRIV(OP_lengths)[*cc];
7236 static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
7241 BOOL needs_control_head;
7242 int private_data_ptr;
7243 backtrack_common altbacktrack;
7244 pcre_uchar *ccbegin;
7246 pcre_uchar bra = OP_BRA;
7247 jump_list *tmp = NULL;
7248 jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
7250 /* Saving previous accept variables. */
7251 BOOL save_local_exit = common->local_exit;
7252 BOOL save_positive_assert = common->positive_assert;
7253 then_trap_backtrack *save_then_trap = common->then_trap;
7254 struct sljit_label *save_quit_label = common->quit_label;
7255 struct sljit_label *save_accept_label = common->accept_label;
7256 jump_list *save_quit = common->quit;
7257 jump_list *save_positive_assert_quit = common->positive_assert_quit;
7258 jump_list *save_accept = common->accept;
7259 struct sljit_jump *jump;
7260 struct sljit_jump *brajump = NULL;
7262 /* Assert captures then. */
7263 common->then_trap = NULL;
7265 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
7267 SLJIT_ASSERT(!conditional);
7271 private_data_ptr = PRIVATE_DATA(cc);
7272 SLJIT_ASSERT(private_data_ptr != 0);
7273 framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
7274 backtrack->framesize = framesize;
7275 backtrack->private_data_ptr = private_data_ptr;
7277 SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
7278 found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
7282 if (bra == OP_BRAMINZERO)
7284 /* This is a braminzero backtrack path. */
7285 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7286 free_stack(common, 1);
7287 brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
7293 if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))
7296 if (needs_control_head)
7299 if (framesize == no_frame)
7300 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
7303 allocate_stack(common, extrasize);
7305 if (needs_control_head)
7306 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
7309 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7311 if (needs_control_head)
7313 SLJIT_ASSERT(extrasize == 2);
7314 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
7315 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
7320 extrasize = needs_control_head ? 3 : 2;
7321 allocate_stack(common, framesize + extrasize);
7323 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7324 OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
7325 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
7326 if (needs_control_head)
7327 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
7328 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7330 if (needs_control_head)
7332 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
7333 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
7334 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
7337 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
7339 init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
7342 memset(&altbacktrack, 0, sizeof(backtrack_common));
7343 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
7345 /* Negative assert is stronger than positive assert. */
7346 common->local_exit = TRUE;
7347 common->quit_label = NULL;
7348 common->quit = NULL;
7349 common->positive_assert = FALSE;
7352 common->positive_assert = TRUE;
7353 common->positive_assert_quit = NULL;
7357 common->accept_label = NULL;
7358 common->accept = NULL;
7359 altbacktrack.top = NULL;
7360 altbacktrack.topbacktracks = NULL;
7362 if (*ccbegin == OP_ALT && extrasize > 0)
7363 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7365 altbacktrack.cc = ccbegin;
7366 compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
7367 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7369 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
7371 common->local_exit = save_local_exit;
7372 common->quit_label = save_quit_label;
7373 common->quit = save_quit;
7375 common->positive_assert = save_positive_assert;
7376 common->then_trap = save_then_trap;
7377 common->accept_label = save_accept_label;
7378 common->positive_assert_quit = save_positive_assert_quit;
7379 common->accept = save_accept;
7382 common->accept_label = LABEL();
7383 if (common->accept != NULL)
7384 set_jumps(common->accept, common->accept_label);
7389 if (framesize == no_frame)
7390 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7391 else if (extrasize > 0)
7392 free_stack(common, extrasize);
7394 if (needs_control_head)
7395 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
7399 if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
7401 /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
7402 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
7403 if (needs_control_head)
7404 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
7408 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7409 if (needs_control_head)
7410 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
7411 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7415 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
7417 /* We know that STR_PTR was stored on the top of the stack. */
7421 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
7423 else if (bra == OP_BRAZERO)
7426 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
7429 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
7430 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
7431 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
7433 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
7434 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7436 else if (framesize >= 0)
7438 /* For OP_BRA and OP_BRAMINZERO. */
7439 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
7442 add_jump(compiler, found, JUMP(SLJIT_JUMP));
7444 compile_backtrackingpath(common, altbacktrack.top);
7445 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7447 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
7449 common->local_exit = save_local_exit;
7450 common->quit_label = save_quit_label;
7451 common->quit = save_quit;
7453 common->positive_assert = save_positive_assert;
7454 common->then_trap = save_then_trap;
7455 common->accept_label = save_accept_label;
7456 common->positive_assert_quit = save_positive_assert_quit;
7457 common->accept = save_accept;
7460 set_jumps(altbacktrack.topbacktracks, LABEL());
7469 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
7471 SLJIT_ASSERT(common->positive_assert_quit == NULL);
7472 /* Makes the check less complicated below. */
7473 common->positive_assert_quit = common->quit;
7476 /* None of them matched. */
7477 if (common->positive_assert_quit != NULL)
7479 jump = JUMP(SLJIT_JUMP);
7480 set_jumps(common->positive_assert_quit, LABEL());
7481 SLJIT_ASSERT(framesize != no_stack);
7483 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
7486 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7487 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7488 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
7493 if (needs_control_head)
7494 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
7496 if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
7498 /* Assert is failed. */
7499 if ((conditional && extrasize > 0) || bra == OP_BRAZERO)
7500 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7504 /* The topmost item should be 0. */
7505 if (bra == OP_BRAZERO)
7508 free_stack(common, 1);
7509 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7511 else if (extrasize > 0)
7512 free_stack(common, extrasize);
7516 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
7517 /* The topmost item should be 0. */
7518 if (bra == OP_BRAZERO)
7520 free_stack(common, framesize + extrasize - 1);
7521 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7524 free_stack(common, framesize + extrasize);
7525 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
7527 jump = JUMP(SLJIT_JUMP);
7528 if (bra != OP_BRAZERO)
7529 add_jump(compiler, target, jump);
7531 /* Assert is successful. */
7532 set_jumps(tmp, LABEL());
7535 /* We know that STR_PTR was stored on the top of the stack. */
7537 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
7539 /* Keep the STR_PTR on the top of the stack. */
7540 if (bra == OP_BRAZERO)
7542 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
7544 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7546 else if (bra == OP_BRAMINZERO)
7548 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
7549 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7556 /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
7557 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
7558 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
7562 /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
7563 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
7566 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7567 if (bra == OP_BRAMINZERO)
7568 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7572 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
7573 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
7578 if (bra == OP_BRAZERO)
7580 backtrack->matchingpath = LABEL();
7581 SET_LABEL(jump, backtrack->matchingpath);
7583 else if (bra == OP_BRAMINZERO)
7585 JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
7589 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7590 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7591 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
7593 set_jumps(backtrack->common.topbacktracks, LABEL());
7598 /* AssertNot is successful. */
7602 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7607 free_stack(common, 1);
7608 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7610 else if (extrasize > 0)
7611 free_stack(common, extrasize);
7615 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7616 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
7617 /* The topmost item should be 0. */
7620 free_stack(common, framesize + extrasize - 1);
7621 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7624 free_stack(common, framesize + extrasize);
7625 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
7628 if (bra == OP_BRAZERO)
7629 backtrack->matchingpath = LABEL();
7630 else if (bra == OP_BRAMINZERO)
7632 JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
7638 SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
7639 set_jumps(backtrack->common.topbacktracks, LABEL());
7640 backtrack->common.topbacktracks = NULL;
7644 if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
7646 common->local_exit = save_local_exit;
7647 common->quit_label = save_quit_label;
7648 common->quit = save_quit;
7650 common->positive_assert = save_positive_assert;
7651 common->then_trap = save_then_trap;
7652 common->accept_label = save_accept_label;
7653 common->positive_assert_quit = save_positive_assert_quit;
7654 common->accept = save_accept;
7655 return cc + 1 + LINK_SIZE;
7658 static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
7665 if (framesize == no_frame)
7666 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7669 stacksize = needs_control_head ? 1 : 0;
7670 if (ket != OP_KET || has_alternatives)
7674 free_stack(common, stacksize);
7677 if (needs_control_head)
7678 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
7680 /* TMP2 which is set here used by OP_KETRMAX below. */
7681 if (ket == OP_KETRMAX)
7682 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7683 else if (ket == OP_KETRMIN)
7685 /* Move the STR_PTR to the private_data_ptr. */
7686 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
7691 stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
7692 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
7693 if (needs_control_head)
7694 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
7696 if (ket == OP_KETRMAX)
7698 /* TMP2 which is set here used by OP_KETRMAX below. */
7699 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7702 if (needs_control_head)
7703 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
7706 static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
7710 if (common->capture_last_ptr != 0)
7712 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
7713 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
7714 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7717 if (common->optimized_cbracket[offset >> 1] == 0)
7719 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
7720 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
7721 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7722 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7723 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
7724 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
7725 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
7732 Handling bracketed expressions is probably the most complex part.
7734 Stack layout naming characters:
7735 S - Push the current STR_PTR
7737 A - Push the current STR_PTR. Needed for restoring the STR_PTR
7738 before the next alternative. Not pushed if there are no alternatives.
7739 M - Any values pushed by the current alternative. Can be empty, or anything.
7740 C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
7741 L - Push the previous local (pointed by localptr) to the stack
7742 () - opional values stored on the stack
7743 ()* - optonal, can be stored multiple times
7745 The following list shows the regular expression templates, their PCRE byte codes
7746 and stack layout supported by pcre-sljit.
7748 (?:) OP_BRA | OP_KET A M
7749 () OP_CBRA | OP_KET C M
7750 (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
7751 OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
7752 (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
7753 OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
7754 ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
7755 OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
7756 ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
7757 OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
7758 (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
7759 (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
7760 ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
7761 ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
7762 (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
7763 OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
7764 (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
7765 OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
7766 ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
7767 OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
7768 ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
7769 OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
7772 Stack layout naming characters:
7773 A - Push the alternative index (starting from 0) on the stack.
7774 Not pushed if there is no alternatives.
7775 M - Any values pushed by the current alternative. Can be empty, or anything.
7777 The next list shows the possible content of a bracket:
7778 (|) OP_*BRA | OP_ALT ... M A
7779 (?()|) OP_*COND | OP_ALT M A
7780 (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
7781 (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A
7782 Or nothing, if trace is unnecessary
7785 static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7788 backtrack_common *backtrack;
7790 int private_data_ptr = 0;
7793 int repeat_ptr = 0, repeat_length = 0;
7794 int repeat_type = 0, repeat_count = 0;
7795 pcre_uchar *ccbegin;
7796 pcre_uchar *matchingpath;
7798 pcre_uchar bra = OP_BRA;
7800 assert_backtrack *assert;
7801 BOOL has_alternatives;
7802 BOOL needs_control_head = FALSE;
7803 struct sljit_jump *jump;
7804 struct sljit_jump *skip;
7805 struct sljit_label *rmax_label = NULL;
7806 struct sljit_jump *braminzero = NULL;
7808 PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
7810 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
7819 matchingpath = bracketend(cc) - 1 - LINK_SIZE;
7820 ket = *matchingpath;
7821 if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
7823 repeat_ptr = PRIVATE_DATA(matchingpath);
7824 repeat_length = PRIVATE_DATA(matchingpath + 1);
7825 repeat_type = PRIVATE_DATA(matchingpath + 2);
7826 repeat_count = PRIVATE_DATA(matchingpath + 3);
7827 SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
7828 if (repeat_type == OP_UPTO)
7830 if (repeat_type == OP_MINUPTO)
7834 if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
7836 /* Drop this bracket_backtrack. */
7837 parent->top = backtrack->prev;
7838 return matchingpath + 1 + LINK_SIZE + repeat_length;
7841 matchingpath = ccbegin + 1 + LINK_SIZE;
7842 SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
7843 SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
7846 has_alternatives = *cc == OP_ALT;
7847 if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
7848 has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL) ? FALSE : TRUE;
7850 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
7852 if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7855 if (opcode == OP_CBRA || opcode == OP_SCBRA)
7857 /* Capturing brackets has a pre-allocated space. */
7858 offset = GET2(ccbegin, 1 + LINK_SIZE);
7859 if (common->optimized_cbracket[offset] == 0)
7861 private_data_ptr = OVECTOR_PRIV(offset);
7867 private_data_ptr = OVECTOR(offset);
7869 BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
7870 matchingpath += IMM2_SIZE;
7872 else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
7874 /* Other brackets simply allocate the next entry. */
7875 private_data_ptr = PRIVATE_DATA(ccbegin);
7876 SLJIT_ASSERT(private_data_ptr != 0);
7877 BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
7878 if (opcode == OP_ONCE)
7879 BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
7882 /* Instructions before the first alternative. */
7884 if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
7886 if (bra == OP_BRAZERO)
7890 allocate_stack(common, stacksize);
7893 if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
7895 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
7899 if (bra == OP_BRAZERO)
7900 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
7902 if (bra == OP_BRAMINZERO)
7904 /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
7905 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7906 if (ket != OP_KETRMIN)
7908 free_stack(common, 1);
7909 braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
7913 if (opcode == OP_ONCE || opcode >= OP_SBRA)
7915 jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
7916 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7917 /* Nothing stored during the first run. */
7918 skip = JUMP(SLJIT_JUMP);
7920 /* Checking zero-length iteration. */
7921 if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
7923 /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
7924 braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7928 /* Except when the whole stack frame must be saved. */
7929 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7930 braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
7936 jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
7937 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7943 if (repeat_type != 0)
7945 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);
7946 if (repeat_type == OP_EXACT)
7947 rmax_label = LABEL();
7950 if (ket == OP_KETRMIN)
7951 BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
7953 if (ket == OP_KETRMAX)
7955 rmax_label = LABEL();
7956 if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
7957 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
7960 /* Handling capturing brackets and alternatives. */
7961 if (opcode == OP_ONCE)
7964 if (needs_control_head)
7966 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
7970 if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
7972 /* Neither capturing brackets nor recursions are found in the block. */
7973 if (ket == OP_KETRMIN)
7976 if (!needs_control_head)
7977 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
7981 if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
7982 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
7983 if (ket == OP_KETRMAX || has_alternatives)
7988 allocate_stack(common, stacksize);
7991 if (needs_control_head)
7994 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7997 if (ket == OP_KETRMIN)
7999 if (needs_control_head)
8000 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8001 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
8002 if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
8003 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
8004 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
8006 else if (ket == OP_KETRMAX || has_alternatives)
8007 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
8011 if (ket != OP_KET || has_alternatives)
8014 stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
8015 allocate_stack(common, stacksize);
8017 if (needs_control_head)
8018 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
8020 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8021 OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
8023 stacksize = needs_control_head ? 1 : 0;
8024 if (ket != OP_KET || has_alternatives)
8026 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
8027 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
8029 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
8033 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
8034 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
8036 init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
8039 else if (opcode == OP_CBRA || opcode == OP_SCBRA)
8041 /* Saving the previous values. */
8042 if (common->optimized_cbracket[offset >> 1] != 0)
8044 SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
8045 allocate_stack(common, 2);
8046 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8047 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));
8048 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
8049 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
8050 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
8054 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8055 allocate_stack(common, 1);
8056 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
8057 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
8060 else if (opcode == OP_SBRA || opcode == OP_SCOND)
8062 /* Saving the previous value. */
8063 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8064 allocate_stack(common, 1);
8065 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
8066 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
8068 else if (has_alternatives)
8070 /* Pushing the starting string pointer. */
8071 allocate_stack(common, 1);
8072 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8075 /* Generating code for the first alternative. */
8076 if (opcode == OP_COND || opcode == OP_SCOND)
8078 if (*matchingpath == OP_CREF)
8080 SLJIT_ASSERT(has_alternatives);
8081 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
8082 CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
8083 matchingpath += 1 + IMM2_SIZE;
8085 else if (*matchingpath == OP_DNCREF)
8087 SLJIT_ASSERT(has_alternatives);
8089 i = GET2(matchingpath, 1 + IMM2_SIZE);
8090 slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
8091 OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
8092 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
8093 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
8094 slot += common->name_entry_size;
8098 OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
8099 OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
8100 slot += common->name_entry_size;
8102 OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
8103 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));
8104 matchingpath += 1 + 2 * IMM2_SIZE;
8106 else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL)
8108 /* Never has other case. */
8109 BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
8110 SLJIT_ASSERT(!has_alternatives);
8112 if (*matchingpath == OP_FAIL)
8114 if (*matchingpath == OP_RREF)
8116 stacksize = GET2(matchingpath, 1);
8117 if (common->currententry == NULL)
8119 else if (stacksize == RREF_ANY)
8121 else if (common->currententry->start == 0)
8122 stacksize = stacksize == 0;
8124 stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
8127 matchingpath += 1 + IMM2_SIZE;
8131 if (common->currententry == NULL || common->currententry->start == 0)
8135 stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
8136 slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
8137 i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
8138 while (stacksize > 0)
8140 if ((int)GET2(slot, 0) == i)
8142 slot += common->name_entry_size;
8148 matchingpath += 1 + 2 * IMM2_SIZE;
8151 /* The stacksize == 0 is a common "else" case. */
8156 matchingpath = cc + 1 + LINK_SIZE;
8165 SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
8166 /* Similar code as PUSH_BACKTRACK macro. */
8167 assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
8168 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8170 memset(assert, 0, sizeof(assert_backtrack));
8171 assert->common.cc = matchingpath;
8172 BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
8173 matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
8177 compile_matchingpath(common, matchingpath, cc, backtrack);
8178 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8181 if (opcode == OP_ONCE)
8182 match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
8185 if (repeat_type == OP_MINUPTO)
8187 /* We need to preserve the counter. TMP2 will be used below. */
8188 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
8191 if (ket != OP_KET || bra != OP_BRA)
8195 if (common->capture_last_ptr != 0)
8197 if (common->optimized_cbracket[offset >> 1] == 0)
8200 if (has_alternatives && opcode != OP_ONCE)
8204 allocate_stack(common, stacksize);
8207 if (repeat_type == OP_MINUPTO)
8209 /* TMP2 was set above. */
8210 OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
8214 if (ket != OP_KET || bra != OP_BRA)
8217 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
8219 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
8224 stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
8226 if (has_alternatives)
8228 if (opcode != OP_ONCE)
8229 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
8230 if (ket != OP_KETRMAX)
8231 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
8234 /* Must be after the matchingpath label. */
8235 if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
8237 SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
8238 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
8241 if (ket == OP_KETRMAX)
8243 if (repeat_type != 0)
8245 if (has_alternatives)
8246 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
8247 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
8248 JUMPTO(SLJIT_NOT_ZERO, rmax_label);
8249 /* Drop STR_PTR for greedy plus quantifier. */
8250 if (opcode != OP_ONCE)
8251 free_stack(common, 1);
8253 else if (opcode == OP_ONCE || opcode >= OP_SBRA)
8255 if (has_alternatives)
8256 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
8257 /* Checking zero-length iteration. */
8258 if (opcode != OP_ONCE)
8260 CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);
8261 /* Drop STR_PTR for greedy plus quantifier. */
8262 if (bra != OP_BRAZERO)
8263 free_stack(common, 1);
8266 /* TMP2 must contain the starting STR_PTR. */
8267 CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
8270 JUMPTO(SLJIT_JUMP, rmax_label);
8271 BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
8274 if (repeat_type == OP_EXACT)
8276 count_match(common);
8277 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
8278 JUMPTO(SLJIT_NOT_ZERO, rmax_label);
8280 else if (repeat_type == OP_UPTO)
8282 /* We need to preserve the counter. */
8283 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
8284 allocate_stack(common, 1);
8285 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
8288 if (bra == OP_BRAZERO)
8289 BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
8291 if (bra == OP_BRAMINZERO)
8293 /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
8294 JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
8295 if (braminzero != NULL)
8297 JUMPHERE(braminzero);
8298 /* We need to release the end pointer to perform the
8299 backtrack for the zero-length iteration. When
8300 framesize is < 0, OP_ONCE will do the release itself. */
8301 if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
8303 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8304 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8306 else if (ket == OP_KETRMIN && opcode != OP_ONCE)
8307 free_stack(common, 1);
8309 /* Continue to the normal backtrack. */
8312 if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
8313 count_match(common);
8315 /* Skip the other alternatives. */
8316 while (*cc == OP_ALT)
8318 cc += 1 + LINK_SIZE;
8320 if (opcode == OP_ONCE)
8322 /* We temporarily encode the needs_control_head in the lowest bit.
8323 Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
8324 the same value for small signed numbers (including negative numbers). */
8325 BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
8327 return cc + repeat_length;
8330 static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
8333 backtrack_common *backtrack;
8335 int private_data_ptr;
8336 int cbraprivptr = 0;
8337 BOOL needs_control_head;
8342 pcre_uchar *ccbegin = NULL;
8343 int stack; /* Also contains the offset of control head. */
8344 struct sljit_label *loop = NULL;
8345 struct jump_list *emptymatch = NULL;
8347 PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
8348 if (*cc == OP_BRAPOSZERO)
8355 private_data_ptr = PRIVATE_DATA(cc);
8356 SLJIT_ASSERT(private_data_ptr != 0);
8357 BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
8362 ccbegin = cc + 1 + LINK_SIZE;
8367 offset = GET2(cc, 1 + LINK_SIZE);
8368 /* This case cannot be optimized in the same was as
8369 normal capturing brackets. */
8370 SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
8371 cbraprivptr = OVECTOR_PRIV(offset);
8373 ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
8377 SLJIT_ASSERT_STOP();
8381 framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
8382 BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
8388 if (common->capture_last_ptr != 0)
8394 if (needs_control_head)
8399 BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
8400 allocate_stack(common, stacksize);
8401 if (framesize == no_frame)
8402 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
8408 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
8409 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
8410 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
8411 if (common->capture_last_ptr != 0)
8412 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
8413 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
8414 if (needs_control_head)
8415 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
8416 if (common->capture_last_ptr != 0)
8418 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
8424 if (needs_control_head)
8425 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
8426 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8430 if (needs_control_head)
8433 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
8434 if (needs_control_head)
8437 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
8442 stacksize = framesize + 1;
8445 if (needs_control_head)
8449 BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
8451 allocate_stack(common, stacksize);
8452 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8453 if (needs_control_head)
8454 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
8455 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
8460 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
8463 if (needs_control_head)
8465 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
8470 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
8473 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
8474 init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
8475 stack -= 1 + (offset == 0);
8479 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
8482 while (*cc != OP_KETRPOS)
8484 backtrack->top = NULL;
8485 backtrack->topbacktracks = NULL;
8488 compile_matchingpath(common, ccbegin, cc, backtrack);
8489 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8494 if (framesize == no_frame)
8495 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8499 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
8500 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
8501 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
8502 if (common->capture_last_ptr != 0)
8503 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
8504 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
8508 if (opcode == OP_SBRAPOS)
8509 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8510 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8513 /* Even if the match is empty, we need to reset the control head. */
8514 if (needs_control_head)
8515 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
8517 if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
8518 add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
8521 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
8527 OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
8528 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
8529 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
8530 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
8531 if (common->capture_last_ptr != 0)
8532 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
8533 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
8537 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8538 OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
8539 if (opcode == OP_SBRAPOS)
8540 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
8541 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
8544 /* Even if the match is empty, we need to reset the control head. */
8545 if (needs_control_head)
8546 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
8548 if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
8549 add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
8554 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
8556 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
8560 JUMPTO(SLJIT_JUMP, loop);
8561 flush_stubs(common);
8563 compile_backtrackingpath(common, backtrack->top);
8564 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8566 set_jumps(backtrack->topbacktracks, LABEL());
8571 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
8573 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8579 /* Last alternative. */
8580 if (*cc == OP_KETRPOS)
8581 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8582 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
8586 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
8587 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
8591 if (*cc == OP_KETRPOS)
8593 ccbegin = cc + 1 + LINK_SIZE;
8596 /* We don't have to restore the control head in case of a failed match. */
8598 backtrack->topbacktracks = NULL;
8602 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
8603 else /* TMP2 is set to [private_data_ptr] above. */
8604 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0));
8607 /* None of them matched. */
8608 set_jumps(emptymatch, LABEL());
8609 count_match(common);
8610 return cc + 1 + LINK_SIZE;
8613 static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, sljit_u32 *max, sljit_u32 *exact, pcre_uchar **end)
8620 if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
8625 else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
8629 *opcode -= OP_STARI - OP_STAR;
8631 else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
8635 *opcode -= OP_NOTSTAR - OP_STAR;
8637 else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
8641 *opcode -= OP_NOTSTARI - OP_STAR;
8643 else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
8646 *opcode -= OP_TYPESTAR - OP_STAR;
8651 SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
8654 class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
8655 *opcode = cc[class_len - 1];
8657 if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
8659 *opcode -= OP_CRSTAR - OP_STAR;
8660 *end = cc + class_len;
8662 if (*opcode == OP_PLUS || *opcode == OP_MINPLUS)
8665 *opcode -= OP_PLUS - OP_STAR;
8668 else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
8670 *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
8671 *end = cc + class_len;
8673 if (*opcode == OP_POSPLUS)
8676 *opcode = OP_POSSTAR;
8681 SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
8682 *max = GET2(cc, (class_len + IMM2_SIZE));
8683 *exact = GET2(cc, class_len);
8687 if (*opcode == OP_CRPOSRANGE)
8688 *opcode = OP_POSSTAR;
8690 *opcode -= OP_CRRANGE - OP_STAR;
8699 if (*opcode == OP_CRPOSRANGE)
8700 *opcode = OP_POSQUERY;
8702 *opcode -= OP_CRRANGE - OP_QUERY;
8706 if (*opcode == OP_CRPOSRANGE)
8707 *opcode = OP_POSUPTO;
8709 *opcode -= OP_CRRANGE - OP_UPTO;
8712 *end = cc + class_len + 2 * IMM2_SIZE;
8720 *exact = GET2(cc, 0);
8727 *opcode -= OP_PLUS - OP_STAR;
8732 *opcode = OP_POSSTAR;
8743 if (*type == OP_END)
8746 *end = next_opcode(common, cc);
8753 if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
8758 static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
8761 backtrack_common *backtrack;
8764 sljit_u32 max = 0, exact;
8766 sljit_s32 fast_str_ptr;
8767 BOOL charpos_enabled;
8768 pcre_uchar charpos_char;
8769 unsigned int charpos_othercasebit;
8771 jump_list *no_match = NULL;
8772 jump_list *no_char1_match = NULL;
8773 struct sljit_jump *jump = NULL;
8774 struct sljit_label *label;
8775 int private_data_ptr = PRIVATE_DATA(cc);
8776 int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
8777 int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
8778 int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
8779 int tmp_base, tmp_offset;
8781 PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL);
8783 fast_str_ptr = PRIVATE_DATA(cc + 1);
8786 SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr);
8788 if (cc == common->fast_forward_bc_ptr)
8790 else if (common->fast_fail_start_ptr == 0)
8793 SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0
8794 || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr));
8796 cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
8798 if (type != OP_EXTUNI)
8805 tmp_base = SLJIT_MEM1(SLJIT_SP);
8806 tmp_offset = POSSESSIVE0;
8809 if (fast_fail && fast_str_ptr != 0)
8810 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr));
8812 /* Handle fixed part first. */
8815 SLJIT_ASSERT(fast_str_ptr == 0);
8816 if (common->mode == JIT_COMPILE
8822 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact));
8823 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0));
8824 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
8826 compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
8827 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8828 JUMPTO(SLJIT_NOT_ZERO, label);
8832 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact);
8834 compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8835 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8836 JUMPTO(SLJIT_NOT_ZERO, label);
8839 else if (exact == 1)
8840 compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8846 SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR);
8848 if (type == OP_ANYNL || type == OP_EXTUNI)
8850 SLJIT_ASSERT(private_data_ptr == 0);
8851 SLJIT_ASSERT(fast_str_ptr == 0);
8853 allocate_stack(common, 2);
8854 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8855 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
8857 if (opcode == OP_UPTO)
8858 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max);
8861 compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
8862 if (opcode == OP_UPTO)
8864 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
8865 OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
8866 jump = JUMP(SLJIT_ZERO);
8867 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
8870 /* We cannot use TMP3 because of this allocate_stack. */
8871 allocate_stack(common, 1);
8872 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8873 JUMPTO(SLJIT_JUMP, label);
8879 charpos_enabled = FALSE;
8881 charpos_othercasebit = 0;
8883 if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))
8885 charpos_enabled = TRUE;
8887 charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);
8889 if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))
8891 charpos_othercasebit = char_get_othercase_bit(common, end + 1);
8892 if (charpos_othercasebit == 0)
8893 charpos_enabled = FALSE;
8896 if (charpos_enabled)
8898 charpos_char = end[1];
8899 /* Consumpe the OP_CHAR opcode. */
8901 #if defined COMPILE_PCRE8
8902 SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
8903 #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
8904 SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);
8905 if ((charpos_othercasebit & 0x100) != 0)
8906 charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
8908 if (charpos_othercasebit != 0)
8909 charpos_char |= charpos_othercasebit;
8911 BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;
8912 BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
8913 BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
8917 if (charpos_enabled)
8919 if (opcode == OP_UPTO)
8920 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);
8922 /* Search the first instance of charpos_char. */
8923 jump = JUMP(SLJIT_JUMP);
8925 if (opcode == OP_UPTO)
8927 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8928 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
8930 compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
8931 if (fast_str_ptr != 0)
8932 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
8935 detect_partial_match(common, &backtrack->topbacktracks);
8936 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
8937 if (charpos_othercasebit != 0)
8938 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
8939 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
8941 if (private_data_ptr == 0)
8942 allocate_stack(common, 2);
8943 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8944 OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
8945 if (opcode == OP_UPTO)
8947 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8948 add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
8951 /* Search the last instance of charpos_char. */
8953 compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
8954 if (fast_str_ptr != 0)
8955 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
8956 detect_partial_match(common, &no_match);
8957 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
8958 if (charpos_othercasebit != 0)
8959 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
8960 if (opcode == OP_STAR)
8962 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
8963 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8967 jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
8968 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8972 if (opcode == OP_UPTO)
8974 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8975 JUMPTO(SLJIT_NOT_ZERO, label);
8978 JUMPTO(SLJIT_JUMP, label);
8980 set_jumps(no_match, LABEL());
8981 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
8982 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
8983 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8985 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
8986 else if (common->utf)
8988 if (private_data_ptr == 0)
8989 allocate_stack(common, 2);
8991 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8992 OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
8994 if (opcode == OP_UPTO)
8995 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
8998 compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
8999 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9001 if (opcode == OP_UPTO)
9003 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
9004 JUMPTO(SLJIT_NOT_ZERO, label);
9007 JUMPTO(SLJIT_JUMP, label);
9009 set_jumps(no_match, LABEL());
9010 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9011 if (fast_str_ptr != 0)
9012 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
9017 if (private_data_ptr == 0)
9018 allocate_stack(common, 2);
9020 OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
9021 if (opcode == OP_UPTO)
9022 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
9025 detect_partial_match(common, &no_match);
9026 compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
9027 if (opcode == OP_UPTO)
9029 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
9030 JUMPTO(SLJIT_NOT_ZERO, label);
9031 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
9034 JUMPTO(SLJIT_JUMP, label);
9036 set_jumps(no_char1_match, LABEL());
9037 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
9038 set_jumps(no_match, LABEL());
9039 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9040 if (fast_str_ptr != 0)
9041 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
9044 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
9048 if (private_data_ptr == 0)
9049 allocate_stack(common, 1);
9050 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9051 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
9052 if (fast_str_ptr != 0)
9053 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
9057 SLJIT_ASSERT(fast_str_ptr == 0);
9058 if (private_data_ptr == 0)
9059 allocate_stack(common, 2);
9060 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9061 OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1);
9062 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
9067 SLJIT_ASSERT(fast_str_ptr == 0);
9068 if (private_data_ptr == 0)
9069 allocate_stack(common, 1);
9070 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9071 if (opcode == OP_QUERY)
9072 compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE);
9073 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
9080 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
9083 OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
9085 compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
9086 OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
9087 JUMPTO(SLJIT_JUMP, label);
9088 set_jumps(no_match, LABEL());
9089 OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
9090 if (fast_str_ptr != 0)
9091 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
9096 detect_partial_match(common, &no_match);
9097 compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
9098 JUMPTO(SLJIT_JUMP, label);
9099 set_jumps(no_char1_match, LABEL());
9100 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
9101 set_jumps(no_match, LABEL());
9102 if (fast_str_ptr != 0)
9103 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
9107 SLJIT_ASSERT(fast_str_ptr == 0);
9108 #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
9111 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
9112 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
9114 compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
9115 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
9116 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
9117 JUMPTO(SLJIT_NOT_ZERO, label);
9118 set_jumps(no_match, LABEL());
9119 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
9123 OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
9125 detect_partial_match(common, &no_match);
9126 compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
9127 OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
9128 JUMPTO(SLJIT_NOT_ZERO, label);
9129 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
9130 set_jumps(no_char1_match, LABEL());
9131 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
9132 set_jumps(no_match, LABEL());
9136 SLJIT_ASSERT(fast_str_ptr == 0);
9137 OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
9138 compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
9139 OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
9140 set_jumps(no_match, LABEL());
9141 OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
9145 SLJIT_ASSERT_STOP();
9149 count_match(common);
9153 static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
9156 backtrack_common *backtrack;
9158 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
9162 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
9166 if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
9168 /* No need to check notempty conditions. */
9169 if (common->accept_label == NULL)
9170 add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
9172 JUMPTO(SLJIT_JUMP, common->accept_label);
9176 if (common->accept_label == NULL)
9177 add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));
9179 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
9180 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9181 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
9182 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
9183 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
9184 if (common->accept_label == NULL)
9185 add_jump(compiler, &common->accept, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
9187 CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
9188 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9189 if (common->accept_label == NULL)
9190 add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
9192 CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
9193 add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
9197 static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
9200 int offset = GET2(cc, 1);
9201 BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
9203 /* Data will be discarded anyway... */
9204 if (common->currententry != NULL)
9205 return cc + 1 + IMM2_SIZE;
9207 if (!optimized_cbracket)
9208 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));
9210 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
9211 if (!optimized_cbracket)
9212 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
9213 return cc + 1 + IMM2_SIZE;
9216 static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
9219 backtrack_common *backtrack;
9220 pcre_uchar opcode = *cc;
9221 pcre_uchar *ccend = cc + 1;
9223 if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
9226 PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
9228 if (opcode == OP_SKIP)
9230 allocate_stack(common, 1);
9231 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
9235 if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
9237 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9238 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
9239 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
9240 OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
9246 static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
9248 static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
9251 backtrack_common *backtrack;
9252 BOOL needs_control_head;
9255 PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
9256 common->then_trap = BACKTRACK_AS(then_trap_backtrack);
9257 BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
9258 BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
9259 BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
9261 size = BACKTRACK_AS(then_trap_backtrack)->framesize;
9262 size = 3 + (size < 0 ? 0 : size);
9264 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
9265 allocate_stack(common, size);
9267 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
9269 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
9270 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
9271 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
9272 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
9274 size = BACKTRACK_AS(then_trap_backtrack)->framesize;
9276 init_frame(common, cc, ccend, size - 1, 0, FALSE);
9279 static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
9282 backtrack_common *backtrack;
9283 BOOL has_then_trap = FALSE;
9284 then_trap_backtrack *save_then_trap = NULL;
9286 SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
9288 if (common->has_then && common->then_offsets[cc - common->start] != 0)
9290 SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
9291 has_then_trap = TRUE;
9292 save_then_trap = common->then_trap;
9293 /* Tail item on backtrack. */
9294 compile_then_trap_matchingpath(common, cc, ccend, parent);
9303 case OP_NOT_WORD_BOUNDARY:
9304 case OP_WORD_BOUNDARY:
9312 cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
9317 case OP_NOT_WHITESPACE:
9319 case OP_NOT_WORDCHAR:
9334 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
9338 PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
9339 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
9340 allocate_stack(common, 1);
9341 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
9342 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
9348 if (common->mode == JIT_COMPILE)
9349 cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
9351 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
9385 case OP_NOTMINQUERY:
9391 case OP_NOTPOSQUERY:
9394 case OP_NOTMINSTARI:
9396 case OP_NOTMINPLUSI:
9398 case OP_NOTMINQUERYI:
9400 case OP_NOTMINUPTOI:
9402 case OP_NOTPOSSTARI:
9403 case OP_NOTPOSPLUSI:
9404 case OP_NOTPOSQUERYI:
9405 case OP_NOTPOSUPTOI:
9407 case OP_TYPEMINSTAR:
9409 case OP_TYPEMINPLUS:
9411 case OP_TYPEMINQUERY:
9413 case OP_TYPEMINUPTO:
9415 case OP_TYPEPOSSTAR:
9416 case OP_TYPEPOSPLUS:
9417 case OP_TYPEPOSQUERY:
9418 case OP_TYPEPOSUPTO:
9419 cc = compile_iterator_matchingpath(common, cc, parent);
9424 if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE)
9425 cc = compile_iterator_matchingpath(common, cc, parent);
9427 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
9430 #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
9432 if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
9433 cc = compile_iterator_matchingpath(common, cc, parent);
9435 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
9441 if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
9442 cc = compile_ref_iterator_matchingpath(common, cc, parent);
9445 compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
9446 cc += 1 + IMM2_SIZE;
9452 if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
9453 cc = compile_ref_iterator_matchingpath(common, cc, parent);
9456 compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
9457 compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
9458 cc += 1 + 2 * IMM2_SIZE;
9463 cc = compile_recurse_matchingpath(common, cc, parent);
9467 cc = compile_callout_matchingpath(common, cc, parent);
9473 case OP_ASSERTBACK_NOT:
9474 PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
9475 cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
9479 PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
9480 cc = bracketend(cc + 1);
9481 if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
9483 allocate_stack(common, 1);
9484 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
9488 allocate_stack(common, 2);
9489 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
9490 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
9492 BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
9493 count_match(common);
9504 cc = compile_bracket_matchingpath(common, cc, parent);
9508 if (cc[1] > OP_ASSERTBACK_NOT)
9509 cc = compile_bracket_matchingpath(common, cc, parent);
9512 PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
9513 cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
9522 cc = compile_bracketpos_matchingpath(common, cc, parent);
9526 PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
9527 SLJIT_ASSERT(common->mark_ptr != 0);
9528 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
9529 allocate_stack(common, common->has_skip_arg ? 5 : 1);
9530 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9531 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
9532 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
9533 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
9534 OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
9535 if (common->has_skip_arg)
9537 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
9538 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
9539 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
9540 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
9541 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
9542 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
9544 cc += 1 + 2 + cc[1];
9554 cc = compile_control_verb_matchingpath(common, cc, parent);
9559 case OP_ASSERT_ACCEPT:
9560 cc = compile_fail_accept_matchingpath(common, cc, parent);
9564 cc = compile_close_matchingpath(common, cc);
9568 cc = bracketend(cc + 1);
9572 SLJIT_ASSERT_STOP();
9581 /* Head item on backtrack. */
9582 PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
9583 BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
9584 BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
9585 common->then_trap = save_then_trap;
9587 SLJIT_ASSERT(cc == ccend);
9590 #undef PUSH_BACKTRACK
9591 #undef PUSH_BACKTRACK_NOVALUE
9594 #define COMPILE_BACKTRACKINGPATH(current) \
9597 compile_backtrackingpath(common, (current)); \
9598 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
9603 #define CURRENT_AS(type) ((type *)current)
9605 static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
9608 pcre_uchar *cc = current->cc;
9611 sljit_u32 max = 0, exact;
9612 struct sljit_label *label = NULL;
9613 struct sljit_jump *jump = NULL;
9614 jump_list *jumplist = NULL;
9616 int private_data_ptr = PRIVATE_DATA(cc);
9617 int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
9618 int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
9619 int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
9621 cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end);
9627 if (type == OP_ANYNL || type == OP_EXTUNI)
9629 SLJIT_ASSERT(private_data_ptr == 0);
9630 set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
9631 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9632 free_stack(common, 1);
9633 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9637 if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled)
9639 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9640 OP1(SLJIT_MOV, TMP2, 0, base, offset1);
9641 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
9643 jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
9645 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
9646 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9647 if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0)
9648 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit);
9649 CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9650 skip_char_back(common);
9651 CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label);
9655 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9656 jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);
9657 skip_char_back(common);
9658 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9659 JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9662 if (private_data_ptr == 0)
9663 free_stack(common, 2);
9668 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9669 compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
9670 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9671 JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9672 set_jumps(jumplist, LABEL());
9673 if (private_data_ptr == 0)
9674 free_stack(common, 1);
9678 OP1(SLJIT_MOV, TMP1, 0, base, offset1);
9679 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9680 OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
9681 add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO));
9683 OP1(SLJIT_MOV, base, offset1, TMP1, 0);
9684 compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
9685 OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
9686 JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9688 set_jumps(jumplist, LABEL());
9689 if (private_data_ptr == 0)
9690 free_stack(common, 2);
9694 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9695 OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
9696 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9697 jump = JUMP(SLJIT_JUMP);
9698 set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL());
9699 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9700 OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
9701 JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9703 if (private_data_ptr == 0)
9704 free_stack(common, 1);
9708 OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
9709 OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
9710 jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
9711 compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
9712 JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
9713 set_jumps(jumplist, LABEL());
9715 if (private_data_ptr == 0)
9716 free_stack(common, 1);
9726 SLJIT_ASSERT_STOP();
9730 set_jumps(current->topbacktracks, LABEL());
9733 static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
9736 pcre_uchar *cc = current->cc;
9737 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
9740 type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
9742 if ((type & 0x1) == 0)
9744 /* Maximize case. */
9745 set_jumps(current->topbacktracks, LABEL());
9746 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9747 free_stack(common, 1);
9748 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
9752 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9753 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath);
9754 set_jumps(current->topbacktracks, LABEL());
9755 free_stack(common, ref ? 2 : 3);
9758 static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
9762 if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
9763 compile_backtrackingpath(common, current->top);
9764 set_jumps(current->topbacktracks, LABEL());
9765 if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
9768 if (common->has_set_som && common->mark_ptr != 0)
9770 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9771 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
9772 free_stack(common, 2);
9773 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0);
9774 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
9776 else if (common->has_set_som || common->mark_ptr != 0)
9778 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9779 free_stack(common, 1);
9780 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
9784 static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
9787 pcre_uchar *cc = current->cc;
9788 pcre_uchar bra = OP_BRA;
9789 struct sljit_jump *brajump = NULL;
9791 SLJIT_ASSERT(*cc != OP_BRAMINZERO);
9792 if (*cc == OP_BRAZERO)
9798 if (bra == OP_BRAZERO)
9800 SLJIT_ASSERT(current->topbacktracks == NULL);
9801 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9804 if (CURRENT_AS(assert_backtrack)->framesize < 0)
9806 set_jumps(current->topbacktracks, LABEL());
9808 if (bra == OP_BRAZERO)
9810 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
9811 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
9812 free_stack(common, 1);
9817 if (bra == OP_BRAZERO)
9819 if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
9821 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
9822 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
9823 free_stack(common, 1);
9826 free_stack(common, 1);
9827 brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
9830 if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
9832 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);
9833 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
9834 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw));
9836 set_jumps(current->topbacktracks, LABEL());
9839 set_jumps(current->topbacktracks, LABEL());
9841 if (bra == OP_BRAZERO)
9843 /* We know there is enough place on the stack. */
9844 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
9845 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
9846 JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
9851 static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
9854 int opcode, stacksize, alt_count, alt_max;
9856 int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
9857 int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
9858 pcre_uchar *cc = current->cc;
9859 pcre_uchar *ccbegin;
9861 pcre_uchar bra = OP_BRA;
9863 assert_backtrack *assert;
9864 sljit_uw *next_update_addr = NULL;
9865 BOOL has_alternatives;
9866 BOOL needs_control_head = FALSE;
9867 struct sljit_jump *brazero = NULL;
9868 struct sljit_jump *alt1 = NULL;
9869 struct sljit_jump *alt2 = NULL;
9870 struct sljit_jump *once = NULL;
9871 struct sljit_jump *cond = NULL;
9872 struct sljit_label *rmin_label = NULL;
9873 struct sljit_label *exact_label = NULL;
9875 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
9882 ccbegin = bracketend(cc) - 1 - LINK_SIZE;
9884 if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
9886 repeat_ptr = PRIVATE_DATA(ccbegin);
9887 repeat_type = PRIVATE_DATA(ccbegin + 2);
9888 repeat_count = PRIVATE_DATA(ccbegin + 3);
9889 SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
9890 if (repeat_type == OP_UPTO)
9892 if (repeat_type == OP_MINUPTO)
9897 has_alternatives = *cc == OP_ALT;
9898 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
9899 has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
9900 if (opcode == OP_CBRA || opcode == OP_SCBRA)
9901 offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
9902 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
9904 if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
9907 alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
9909 /* Decoding the needs_control_head in framesize. */
9910 if (opcode == OP_ONCE)
9912 needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
9913 CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
9916 if (ket != OP_KET && repeat_type != 0)
9918 /* TMP1 is used in OP_KETRMIN below. */
9919 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9920 free_stack(common, 1);
9921 if (repeat_type == OP_UPTO)
9922 OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
9924 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
9927 if (ket == OP_KETRMAX)
9929 if (bra == OP_BRAZERO)
9931 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9932 free_stack(common, 1);
9933 brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
9936 else if (ket == OP_KETRMIN)
9938 if (bra != OP_BRAMINZERO)
9940 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9941 if (repeat_type != 0)
9943 /* TMP1 was set a few lines above. */
9944 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
9945 /* Drop STR_PTR for non-greedy plus quantifier. */
9946 if (opcode != OP_ONCE)
9947 free_stack(common, 1);
9949 else if (opcode >= OP_SBRA || opcode == OP_ONCE)
9951 /* Checking zero-length iteration. */
9952 if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
9953 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
9956 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
9957 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
9959 /* Drop STR_PTR for non-greedy plus quantifier. */
9960 if (opcode != OP_ONCE)
9961 free_stack(common, 1);
9964 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
9966 rmin_label = LABEL();
9967 if (repeat_type != 0)
9968 OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
9970 else if (bra == OP_BRAZERO)
9972 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9973 free_stack(common, 1);
9974 brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
9976 else if (repeat_type == OP_EXACT)
9978 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
9979 exact_label = LABEL();
9984 if (common->capture_last_ptr != 0)
9986 SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
9987 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9988 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
9989 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
9990 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
9991 free_stack(common, 3);
9992 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);
9993 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
9995 else if (common->optimized_cbracket[offset >> 1] == 0)
9997 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
9998 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
9999 free_stack(common, 2);
10000 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
10001 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
10005 if (SLJIT_UNLIKELY(opcode == OP_ONCE))
10007 if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
10009 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
10010 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10012 once = JUMP(SLJIT_JUMP);
10014 else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
10016 if (has_alternatives)
10018 /* Always exactly one alternative. */
10019 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10020 free_stack(common, 1);
10023 alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
10026 else if (has_alternatives)
10028 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10029 free_stack(common, 1);
10033 /* Table jump if alt_max is greater than 4. */
10034 next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
10035 if (SLJIT_UNLIKELY(next_update_addr == NULL))
10037 sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
10038 add_label_addr(common, next_update_addr++);
10043 alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
10044 alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
10048 COMPILE_BACKTRACKINGPATH(current->top);
10049 if (current->topbacktracks)
10050 set_jumps(current->topbacktracks, LABEL());
10052 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
10054 /* Conditional block always has at most one alternative. */
10055 if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
10057 SLJIT_ASSERT(has_alternatives);
10058 assert = CURRENT_AS(bracket_backtrack)->u.assert;
10059 if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
10061 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
10062 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10063 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
10065 cond = JUMP(SLJIT_JUMP);
10066 set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
10068 else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
10070 SLJIT_ASSERT(has_alternatives);
10071 cond = JUMP(SLJIT_JUMP);
10072 set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
10075 SLJIT_ASSERT(!has_alternatives);
10078 if (has_alternatives)
10080 alt_count = sizeof(sljit_uw);
10083 current->top = NULL;
10084 current->topbacktracks = NULL;
10085 current->nextbacktracks = NULL;
10086 /* Conditional blocks always have an additional alternative, even if it is empty. */
10089 ccprev = cc + 1 + LINK_SIZE;
10091 if (opcode != OP_COND && opcode != OP_SCOND)
10093 if (opcode != OP_ONCE)
10095 if (private_data_ptr != 0)
10096 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
10098 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10101 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
10103 compile_matchingpath(common, ccprev, cc, current);
10104 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
10108 /* Instructions after the current alternative is successfully matched. */
10109 /* There is a similar code in compile_bracket_matchingpath. */
10110 if (opcode == OP_ONCE)
10111 match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
10114 if (repeat_type == OP_MINUPTO)
10116 /* We need to preserve the counter. TMP2 will be used below. */
10117 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
10120 if (ket != OP_KET || bra != OP_BRA)
10124 if (common->capture_last_ptr != 0)
10126 if (common->optimized_cbracket[offset >> 1] == 0)
10129 if (opcode != OP_ONCE)
10133 allocate_stack(common, stacksize);
10136 if (repeat_type == OP_MINUPTO)
10138 /* TMP2 was set above. */
10139 OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
10143 if (ket != OP_KET || bra != OP_BRA)
10146 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
10148 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
10153 stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
10155 if (opcode != OP_ONCE)
10156 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
10158 if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
10160 /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
10161 SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
10162 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
10165 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
10167 if (opcode != OP_ONCE)
10170 add_label_addr(common, next_update_addr++);
10173 if (alt_count != 2 * sizeof(sljit_uw))
10176 if (alt_max == 3 && alt_count == sizeof(sljit_uw))
10177 alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
10183 alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
10186 alt_count += sizeof(sljit_uw);
10189 COMPILE_BACKTRACKINGPATH(current->top);
10190 if (current->topbacktracks)
10191 set_jumps(current->topbacktracks, LABEL());
10192 SLJIT_ASSERT(!current->nextbacktracks);
10194 while (*cc == OP_ALT);
10198 SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
10199 assert = CURRENT_AS(bracket_backtrack)->u.assert;
10200 if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
10202 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
10203 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10204 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
10209 /* Free the STR_PTR. */
10210 if (private_data_ptr == 0)
10211 free_stack(common, 1);
10216 /* Using both tmp register is better for instruction scheduling. */
10217 if (common->optimized_cbracket[offset >> 1] != 0)
10219 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10220 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
10221 free_stack(common, 2);
10222 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
10223 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
10227 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10228 free_stack(common, 1);
10229 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
10232 else if (opcode == OP_SBRA || opcode == OP_SCOND)
10234 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
10235 free_stack(common, 1);
10237 else if (opcode == OP_ONCE)
10239 cc = ccbegin + GET(ccbegin, 1);
10240 stacksize = needs_control_head ? 1 : 0;
10242 if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
10244 /* Reset head and drop saved frame. */
10245 stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
10247 else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
10249 /* The STR_PTR must be released. */
10254 free_stack(common, stacksize);
10257 /* Restore previous private_data_ptr */
10258 if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
10259 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw));
10260 else if (ket == OP_KETRMIN)
10262 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
10263 /* See the comment below. */
10264 free_stack(common, 2);
10265 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
10269 if (repeat_type == OP_EXACT)
10271 OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
10272 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
10273 CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
10275 else if (ket == OP_KETRMAX)
10277 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10278 if (bra != OP_BRAZERO)
10279 free_stack(common, 1);
10281 CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
10282 if (bra == OP_BRAZERO)
10284 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
10285 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
10287 free_stack(common, 1);
10290 else if (ket == OP_KETRMIN)
10292 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10294 /* OP_ONCE removes everything in case of a backtrack, so we don't
10295 need to explicitly release the STR_PTR. The extra release would
10296 affect badly the free_stack(2) above. */
10297 if (opcode != OP_ONCE)
10298 free_stack(common, 1);
10299 CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
10300 if (opcode == OP_ONCE)
10301 free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
10302 else if (bra == OP_BRAMINZERO)
10303 free_stack(common, 1);
10305 else if (bra == OP_BRAZERO)
10307 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10308 JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
10313 static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10317 struct sljit_jump *jump;
10319 if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
10321 if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
10323 offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
10324 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10325 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
10326 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
10327 if (common->capture_last_ptr != 0)
10328 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
10329 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
10330 if (common->capture_last_ptr != 0)
10331 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
10333 set_jumps(current->topbacktracks, LABEL());
10334 free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
10338 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
10339 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10341 if (current->topbacktracks)
10343 jump = JUMP(SLJIT_JUMP);
10344 set_jumps(current->topbacktracks, LABEL());
10345 /* Drop the stack frame. */
10346 free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
10349 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
10352 static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10354 assert_backtrack backtrack;
10356 current->top = NULL;
10357 current->topbacktracks = NULL;
10358 current->nextbacktracks = NULL;
10359 if (current->cc[1] > OP_ASSERTBACK_NOT)
10361 /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
10362 compile_bracket_matchingpath(common, current->cc, current);
10363 compile_bracket_backtrackingpath(common, current->top);
10367 memset(&backtrack, 0, sizeof(backtrack));
10368 backtrack.common.cc = current->cc;
10369 backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
10370 /* Manual call of compile_assert_matchingpath. */
10371 compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
10373 SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
10376 static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10379 pcre_uchar opcode = *current->cc;
10380 struct sljit_label *loop;
10381 struct sljit_jump *jump;
10383 if (opcode == OP_THEN || opcode == OP_THEN_ARG)
10385 if (common->then_trap != NULL)
10387 SLJIT_ASSERT(common->control_head_ptr != 0);
10389 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
10390 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
10391 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
10392 jump = JUMP(SLJIT_JUMP);
10395 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
10397 CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
10398 CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
10399 add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
10402 else if (common->positive_assert)
10404 add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
10409 if (common->local_exit)
10411 if (common->quit_label == NULL)
10412 add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
10414 JUMPTO(SLJIT_JUMP, common->quit_label);
10418 if (opcode == OP_SKIP_ARG)
10420 SLJIT_ASSERT(common->control_head_ptr != 0);
10421 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
10422 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
10423 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
10424 sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
10425 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
10427 OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
10428 add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
10432 if (opcode == OP_SKIP)
10433 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10435 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
10436 add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
10439 static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10442 struct sljit_jump *jump;
10445 if (CURRENT_AS(then_trap_backtrack)->then_trap)
10447 common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
10451 size = CURRENT_AS(then_trap_backtrack)->framesize;
10452 size = 3 + (size < 0 ? 0 : size);
10454 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
10455 free_stack(common, size);
10456 jump = JUMP(SLJIT_JUMP);
10458 set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
10459 /* STACK_TOP is set by THEN. */
10460 if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
10461 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10462 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10463 free_stack(common, 3);
10466 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
10469 static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
10472 then_trap_backtrack *save_then_trap = common->then_trap;
10476 if (current->nextbacktracks != NULL)
10477 set_jumps(current->nextbacktracks, LABEL());
10478 switch(*current->cc)
10481 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10482 free_stack(common, 1);
10483 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);
10513 case OP_NOTMINSTAR:
10515 case OP_NOTMINPLUS:
10517 case OP_NOTMINQUERY:
10519 case OP_NOTMINUPTO:
10521 case OP_NOTPOSSTAR:
10522 case OP_NOTPOSPLUS:
10523 case OP_NOTPOSQUERY:
10524 case OP_NOTPOSUPTO:
10526 case OP_NOTMINSTARI:
10528 case OP_NOTMINPLUSI:
10530 case OP_NOTMINQUERYI:
10532 case OP_NOTMINUPTOI:
10534 case OP_NOTPOSSTARI:
10535 case OP_NOTPOSPLUSI:
10536 case OP_NOTPOSQUERYI:
10537 case OP_NOTPOSUPTOI:
10539 case OP_TYPEMINSTAR:
10541 case OP_TYPEMINPLUS:
10543 case OP_TYPEMINQUERY:
10545 case OP_TYPEMINUPTO:
10547 case OP_TYPEPOSSTAR:
10548 case OP_TYPEPOSPLUS:
10549 case OP_TYPEPOSQUERY:
10550 case OP_TYPEPOSUPTO:
10553 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
10556 compile_iterator_backtrackingpath(common, current);
10563 compile_ref_iterator_backtrackingpath(common, current);
10567 compile_recurse_backtrackingpath(common, current);
10571 case OP_ASSERT_NOT:
10572 case OP_ASSERTBACK:
10573 case OP_ASSERTBACK_NOT:
10574 compile_assert_backtrackingpath(common, current);
10585 compile_bracket_backtrackingpath(common, current);
10589 if (current->cc[1] > OP_ASSERTBACK_NOT)
10590 compile_bracket_backtrackingpath(common, current);
10592 compile_assert_backtrackingpath(common, current);
10599 case OP_BRAPOSZERO:
10600 compile_bracketpos_backtrackingpath(common, current);
10603 case OP_BRAMINZERO:
10604 compile_braminzero_backtrackingpath(common, current);
10608 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
10609 if (common->has_skip_arg)
10610 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10611 free_stack(common, common->has_skip_arg ? 5 : 1);
10612 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
10613 if (common->has_skip_arg)
10614 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
10623 compile_control_verb_backtrackingpath(common, current);
10627 if (!common->local_exit)
10628 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
10629 if (common->quit_label == NULL)
10630 add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
10632 JUMPTO(SLJIT_JUMP, common->quit_label);
10638 case OP_ASSERT_ACCEPT:
10639 set_jumps(current->topbacktracks, LABEL());
10643 /* A virtual opcode for then traps. */
10644 compile_then_trap_backtrackingpath(common, current);
10648 SLJIT_ASSERT_STOP();
10651 current = current->prev;
10653 common->then_trap = save_then_trap;
10656 static SLJIT_INLINE void compile_recurse(compiler_common *common)
10659 pcre_uchar *cc = common->start + common->currententry->start;
10660 pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
10661 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
10662 BOOL needs_control_head;
10663 int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
10664 int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
10665 int alternativesize;
10667 backtrack_common altbacktrack;
10668 struct sljit_jump *jump;
10670 /* Recurse captures then. */
10671 common->then_trap = NULL;
10673 SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
10674 needs_frame = framesize >= 0;
10677 alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
10679 SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
10680 common->currententry->entry = LABEL();
10681 set_jumps(common->currententry->calls, common->currententry->entry);
10683 sljit_emit_fast_enter(compiler, TMP2, 0);
10684 count_match(common);
10685 allocate_stack(common, private_data_size + framesize + alternativesize);
10686 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
10687 copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
10688 if (needs_control_head)
10689 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
10690 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
10692 init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
10694 if (alternativesize > 0)
10695 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
10697 memset(&altbacktrack, 0, sizeof(backtrack_common));
10698 common->quit_label = NULL;
10699 common->accept_label = NULL;
10700 common->quit = NULL;
10701 common->accept = NULL;
10702 altbacktrack.cc = ccbegin;
10706 altbacktrack.top = NULL;
10707 altbacktrack.topbacktracks = NULL;
10709 if (altbacktrack.cc != ccbegin)
10710 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
10712 compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
10713 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
10716 add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
10718 compile_backtrackingpath(common, altbacktrack.top);
10719 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
10721 set_jumps(altbacktrack.topbacktracks, LABEL());
10726 altbacktrack.cc = cc + 1 + LINK_SIZE;
10730 /* None of them matched. */
10731 OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
10732 jump = JUMP(SLJIT_JUMP);
10734 if (common->quit != NULL)
10736 set_jumps(common->quit, LABEL());
10737 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
10740 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
10741 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10742 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
10744 OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
10745 common->quit = NULL;
10746 add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
10749 set_jumps(common->accept, LABEL());
10750 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
10753 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
10754 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
10755 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
10757 OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
10760 if (common->quit != NULL)
10761 set_jumps(common->quit, LABEL());
10762 copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
10763 free_stack(common, private_data_size + framesize + alternativesize);
10764 if (needs_control_head)
10766 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
10767 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
10768 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0);
10769 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
10770 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
10774 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
10775 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
10776 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0);
10778 sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
10781 #undef COMPILE_BACKTRACKINGPATH
10785 PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
10787 struct sljit_compiler *compiler;
10788 backtrack_common rootbacktrack;
10789 compiler_common common_data;
10790 compiler_common *common = &common_data;
10791 const sljit_u8 *tables = re->tables;
10792 pcre_study_data *study;
10793 int private_data_size;
10795 executable_functions *functions;
10796 void *executable_func;
10797 sljit_uw executable_size;
10798 sljit_uw total_length;
10799 label_addr_list *label_addr;
10800 struct sljit_label *mainloop_label = NULL;
10801 struct sljit_label *continue_match_label;
10802 struct sljit_label *empty_match_found_label = NULL;
10803 struct sljit_label *empty_match_backtrack_label = NULL;
10804 struct sljit_label *reset_match_label;
10805 struct sljit_label *quit_label;
10806 struct sljit_jump *jump;
10807 struct sljit_jump *minlength_check_failed = NULL;
10808 struct sljit_jump *reqbyte_notfound = NULL;
10809 struct sljit_jump *empty_match = NULL;
10811 SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
10812 study = extra->study_data;
10815 tables = PRIV(default_tables);
10817 memset(&rootbacktrack, 0, sizeof(backtrack_common));
10818 memset(common, 0, sizeof(compiler_common));
10819 rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
10821 common->start = rootbacktrack.cc;
10822 common->read_only_data_head = NULL;
10823 common->fcc = tables + fcc_offset;
10824 common->lcc = (sljit_sw)(tables + lcc_offset);
10825 common->mode = mode;
10826 common->might_be_empty = study->minlength == 0;
10827 common->nltype = NLTYPE_FIXED;
10828 switch(re->options & PCRE_NEWLINE_BITS)
10831 /* Compile-time default */
10834 case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
10835 case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
10836 default: common->newline = NEWLINE; break;
10839 case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
10840 case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
10841 case PCRE_NEWLINE_CR+
10842 PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
10843 case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
10844 case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
10847 common->nlmax = READ_CHAR_MAX;
10849 if ((re->options & PCRE_BSR_ANYCRLF) != 0)
10850 common->bsr_nltype = NLTYPE_ANYCRLF;
10851 else if ((re->options & PCRE_BSR_UNICODE) != 0)
10852 common->bsr_nltype = NLTYPE_ANY;
10856 common->bsr_nltype = NLTYPE_ANYCRLF;
10858 common->bsr_nltype = NLTYPE_ANY;
10861 common->bsr_nlmax = READ_CHAR_MAX;
10862 common->bsr_nlmin = 0;
10863 common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
10864 common->ctypes = (sljit_sw)(tables + ctypes_offset);
10865 common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
10866 common->name_count = re->name_count;
10867 common->name_entry_size = re->name_entry_size;
10868 common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
10870 /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
10871 common->utf = (re->options & PCRE_UTF8) != 0;
10873 common->use_ucp = (re->options & PCRE_UCP) != 0;
10877 if (common->nltype == NLTYPE_ANY)
10878 common->nlmax = 0x2029;
10879 else if (common->nltype == NLTYPE_ANYCRLF)
10880 common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
10883 /* We only care about the first newline character. */
10884 common->nlmax = common->newline & 0xff;
10887 if (common->nltype == NLTYPE_FIXED)
10888 common->nlmin = common->newline & 0xff;
10890 common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
10892 if (common->bsr_nltype == NLTYPE_ANY)
10893 common->bsr_nlmax = 0x2029;
10895 common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
10896 common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
10898 #endif /* SUPPORT_UTF */
10899 ccend = bracketend(common->start);
10901 /* Calculate the local space size on the stack. */
10902 common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
10903 common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, compiler->allocator_data);
10904 if (!common->optimized_cbracket)
10906 #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
10907 memset(common->optimized_cbracket, 0, re->top_bracket + 1);
10909 memset(common->optimized_cbracket, 1, re->top_bracket + 1);
10912 SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
10913 #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
10914 common->capture_last_ptr = common->ovector_start;
10915 common->ovector_start += sizeof(sljit_sw);
10917 if (!check_opcode_types(common, common->start, ccend))
10919 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10923 /* Checking flags and updating ovector_start. */
10924 if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
10926 common->req_char_ptr = common->ovector_start;
10927 common->ovector_start += sizeof(sljit_sw);
10929 if (mode != JIT_COMPILE)
10931 common->start_used_ptr = common->ovector_start;
10932 common->ovector_start += sizeof(sljit_sw);
10933 if (mode == JIT_PARTIAL_SOFT_COMPILE)
10935 common->hit_start = common->ovector_start;
10936 common->ovector_start += 2 * sizeof(sljit_sw);
10939 if ((re->options & PCRE_FIRSTLINE) != 0)
10941 common->match_end_ptr = common->ovector_start;
10942 common->ovector_start += sizeof(sljit_sw);
10944 #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
10945 common->control_head_ptr = 1;
10947 if (common->control_head_ptr != 0)
10949 common->control_head_ptr = common->ovector_start;
10950 common->ovector_start += sizeof(sljit_sw);
10952 if (common->has_set_som)
10954 /* Saving the real start pointer is necessary. */
10955 common->start_ptr = common->ovector_start;
10956 common->ovector_start += sizeof(sljit_sw);
10959 /* Aligning ovector to even number of sljit words. */
10960 if ((common->ovector_start & sizeof(sljit_sw)) != 0)
10961 common->ovector_start += sizeof(sljit_sw);
10963 if (common->start_ptr == 0)
10964 common->start_ptr = OVECTOR(0);
10966 /* Capturing brackets cannot be optimized if callouts are allowed. */
10967 if (common->capture_last_ptr != 0)
10968 memset(common->optimized_cbracket, 0, re->top_bracket + 1);
10970 SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
10971 common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
10973 total_length = ccend - common->start;
10974 common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), compiler->allocator_data);
10975 if (!common->private_data_ptrs)
10977 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10980 memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));
10982 private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
10983 set_private_data_ptrs(common, &private_data_size, ccend);
10984 if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
10986 if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back)
10987 detect_fast_fail(common, common->start, &private_data_size, 4);
10990 SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr);
10992 if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
10994 SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
10995 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10999 if (common->has_then)
11001 common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length);
11002 memset(common->then_offsets, 0, total_length);
11003 set_then_offsets(common, common->start, NULL);
11006 compiler = sljit_create_compiler(NULL);
11009 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
11010 SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
11013 common->compiler = compiler;
11015 /* Main pcre_jit_exec entry. */
11016 sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
11018 /* Register init. */
11019 reset_ovector(common, (re->top_bracket + 1) * 2);
11020 if (common->req_char_ptr != 0)
11021 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);
11023 OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);
11024 OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);
11025 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
11026 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
11027 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
11028 OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
11029 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
11030 OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
11031 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
11032 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
11034 if (common->fast_fail_start_ptr < common->fast_fail_end_ptr)
11035 reset_fast_fail(common);
11037 if (mode == JIT_PARTIAL_SOFT_COMPILE)
11038 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
11039 if (common->mark_ptr != 0)
11040 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
11041 if (common->control_head_ptr != 0)
11042 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
11044 /* Main part of the matching */
11045 if ((re->options & PCRE_ANCHORED) == 0)
11047 mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0);
11048 continue_match_label = LABEL();
11049 /* Forward search if possible. */
11050 if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
11052 if (mode == JIT_COMPILE && fast_forward_first_n_chars(common))
11054 else if ((re->flags & PCRE_FIRSTSET) != 0)
11055 fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0);
11056 else if ((re->flags & PCRE_STARTLINE) != 0)
11057 fast_forward_newline(common);
11058 else if (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
11059 fast_forward_start_bits(common, study->start_bits);
11063 continue_match_label = LABEL();
11065 if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
11067 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
11068 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
11069 minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);
11071 if (common->req_char_ptr != 0)
11072 reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
11074 /* Store the current STR_PTR in OVECTOR(0). */
11075 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
11076 /* Copy the limit of allowed recursions. */
11077 OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);
11078 if (common->capture_last_ptr != 0)
11079 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, -1);
11080 if (common->fast_forward_bc_ptr != NULL)
11081 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0);
11083 if (common->start_ptr != OVECTOR(0))
11084 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);
11086 /* Copy the beginning of the string. */
11087 if (mode == JIT_PARTIAL_SOFT_COMPILE)
11089 jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
11090 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
11091 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
11094 else if (mode == JIT_PARTIAL_HARD_COMPILE)
11095 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
11097 compile_matchingpath(common, common->start, ccend, &rootbacktrack);
11098 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
11100 sljit_free_compiler(compiler);
11101 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
11102 SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
11103 free_read_only_data(common->read_only_data_head, compiler->allocator_data);
11107 if (common->might_be_empty)
11109 empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
11110 empty_match_found_label = LABEL();
11113 common->accept_label = LABEL();
11114 if (common->accept != NULL)
11115 set_jumps(common->accept, common->accept_label);
11117 /* This means we have a match. Update the ovector. */
11118 copy_ovector(common, re->top_bracket + 1);
11119 common->quit_label = common->forced_quit_label = LABEL();
11120 if (common->quit != NULL)
11121 set_jumps(common->quit, common->quit_label);
11122 if (common->forced_quit != NULL)
11123 set_jumps(common->forced_quit, common->forced_quit_label);
11124 if (minlength_check_failed != NULL)
11125 SET_LABEL(minlength_check_failed, common->forced_quit_label);
11126 sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
11128 if (mode != JIT_COMPILE)
11130 common->partialmatchlabel = LABEL();
11131 set_jumps(common->partialmatch, common->partialmatchlabel);
11132 return_with_partial_match(common, common->quit_label);
11135 if (common->might_be_empty)
11136 empty_match_backtrack_label = LABEL();
11137 compile_backtrackingpath(common, rootbacktrack.top);
11138 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
11140 sljit_free_compiler(compiler);
11141 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
11142 SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
11143 free_read_only_data(common->read_only_data_head, compiler->allocator_data);
11147 SLJIT_ASSERT(rootbacktrack.prev == NULL);
11148 reset_match_label = LABEL();
11150 if (mode == JIT_PARTIAL_SOFT_COMPILE)
11152 /* Update hit_start only in the first time. */
11153 jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
11154 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr);
11155 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
11156 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);
11160 /* Check we have remaining characters. */
11161 if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
11163 SLJIT_ASSERT(common->match_end_ptr != 0);
11164 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
11167 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP),
11168 (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr);
11170 if ((re->options & PCRE_ANCHORED) == 0)
11172 if (common->ff_newline_shortcut != NULL)
11174 if ((re->options & PCRE_FIRSTLINE) == 0)
11175 CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
11176 /* There cannot be more newlines here. */
11179 CMPTO(SLJIT_LESS, STR_PTR, 0, ((re->options & PCRE_FIRSTLINE) == 0) ? STR_END : TMP1, 0, mainloop_label);
11182 /* No more remaining characters. */
11183 if (reqbyte_notfound != NULL)
11184 JUMPHERE(reqbyte_notfound);
11186 if (mode == JIT_PARTIAL_SOFT_COMPILE)
11187 CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
11189 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
11190 JUMPTO(SLJIT_JUMP, common->quit_label);
11192 flush_stubs(common);
11194 if (common->might_be_empty)
11196 JUMPHERE(empty_match);
11197 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
11198 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
11199 CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
11200 OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
11201 CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
11202 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
11203 CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
11204 JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
11207 common->fast_forward_bc_ptr = NULL;
11208 common->fast_fail_start_ptr = 0;
11209 common->fast_fail_end_ptr = 0;
11210 common->currententry = common->entries;
11211 common->local_exit = TRUE;
11212 quit_label = common->quit_label;
11213 while (common->currententry != NULL)
11215 /* Might add new entries. */
11216 compile_recurse(common);
11217 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
11219 sljit_free_compiler(compiler);
11220 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
11221 SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
11222 free_read_only_data(common->read_only_data_head, compiler->allocator_data);
11225 flush_stubs(common);
11226 common->currententry = common->currententry->next;
11228 common->local_exit = FALSE;
11229 common->quit_label = quit_label;
11231 /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
11232 /* This is a (really) rare case. */
11233 set_jumps(common->stackalloc, LABEL());
11234 /* RETURN_ADDR is not a saved register. */
11235 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
11236 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
11237 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
11238 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
11239 OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
11240 OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
11242 sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
11243 jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
11244 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
11245 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
11246 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
11247 OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
11248 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
11249 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
11251 /* Allocation failed. */
11253 /* We break the return address cache here, but this is a really rare case. */
11254 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
11255 JUMPTO(SLJIT_JUMP, common->quit_label);
11257 /* Call limit reached. */
11258 set_jumps(common->calllimit, LABEL());
11259 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
11260 JUMPTO(SLJIT_JUMP, common->quit_label);
11262 if (common->revertframes != NULL)
11264 set_jumps(common->revertframes, LABEL());
11265 do_revertframes(common);
11267 if (common->wordboundary != NULL)
11269 set_jumps(common->wordboundary, LABEL());
11270 check_wordboundary(common);
11272 if (common->anynewline != NULL)
11274 set_jumps(common->anynewline, LABEL());
11275 check_anynewline(common);
11277 if (common->hspace != NULL)
11279 set_jumps(common->hspace, LABEL());
11280 check_hspace(common);
11282 if (common->vspace != NULL)
11284 set_jumps(common->vspace, LABEL());
11285 check_vspace(common);
11287 if (common->casefulcmp != NULL)
11289 set_jumps(common->casefulcmp, LABEL());
11290 do_casefulcmp(common);
11292 if (common->caselesscmp != NULL)
11294 set_jumps(common->caselesscmp, LABEL());
11295 do_caselesscmp(common);
11297 if (common->reset_match != NULL)
11299 set_jumps(common->reset_match, LABEL());
11300 do_reset_match(common, (re->top_bracket + 1) * 2);
11301 CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
11302 OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
11303 JUMPTO(SLJIT_JUMP, reset_match_label);
11306 #ifdef COMPILE_PCRE8
11307 if (common->utfreadchar != NULL)
11309 set_jumps(common->utfreadchar, LABEL());
11310 do_utfreadchar(common);
11312 if (common->utfreadchar16 != NULL)
11314 set_jumps(common->utfreadchar16, LABEL());
11315 do_utfreadchar16(common);
11317 if (common->utfreadtype8 != NULL)
11319 set_jumps(common->utfreadtype8, LABEL());
11320 do_utfreadtype8(common);
11322 #endif /* COMPILE_PCRE8 */
11323 #endif /* SUPPORT_UTF */
11325 if (common->getucd != NULL)
11327 set_jumps(common->getucd, LABEL());
11332 SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
11333 SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
11335 executable_func = sljit_generate_code(compiler);
11336 executable_size = sljit_get_generated_code_size(compiler);
11337 label_addr = common->label_addrs;
11338 while (label_addr != NULL)
11340 *label_addr->update_addr = sljit_get_label_addr(label_addr->label);
11341 label_addr = label_addr->next;
11343 sljit_free_compiler(compiler);
11344 if (executable_func == NULL)
11346 free_read_only_data(common->read_only_data_head, compiler->allocator_data);
11350 /* Reuse the function descriptor if possible. */
11351 if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
11352 functions = (executable_functions *)extra->executable_jit;
11355 /* Note: If your memory-checker has flagged the allocation below as a
11356 * memory leak, it is probably because you either forgot to call
11357 * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or
11358 * pcre16_extra) object, or you called said function after having
11359 * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field
11360 * of the object. (The function will only free the JIT data if the
11361 * bit remains set, as the bit indicates that the pointer to the data
11364 functions = SLJIT_MALLOC(sizeof(executable_functions), compiler->allocator_data);
11365 if (functions == NULL)
11367 /* This case is highly unlikely since we just recently
11368 freed a lot of memory. Not impossible though. */
11369 sljit_free_code(executable_func);
11370 free_read_only_data(common->read_only_data_head, compiler->allocator_data);
11373 memset(functions, 0, sizeof(executable_functions));
11374 functions->top_bracket = (re->top_bracket + 1) * 2;
11375 functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0;
11376 extra->executable_jit = functions;
11377 extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
11380 functions->executable_funcs[mode] = executable_func;
11381 functions->read_only_data_heads[mode] = common->read_only_data_head;
11382 functions->executable_sizes[mode] = executable_size;
11385 static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, void *executable_func)
11388 void *executable_func;
11389 jit_function call_executable_func;
11390 } convert_executable_func;
11391 sljit_u8 local_space[MACHINE_STACK_SIZE];
11392 struct sljit_stack local_stack;
11394 local_stack.top = (sljit_sw)&local_space;
11395 local_stack.base = local_stack.top;
11396 local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
11397 local_stack.max_limit = local_stack.limit;
11398 arguments->stack = &local_stack;
11399 convert_executable_func.executable_func = executable_func;
11400 return convert_executable_func.call_executable_func(arguments);
11404 PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,
11405 int length, int start_offset, int options, int *offsets, int offset_count)
11407 executable_functions *functions = (executable_functions *)extra_data->executable_jit;
11409 void *executable_func;
11410 jit_function call_executable_func;
11411 } convert_executable_func;
11412 jit_arguments arguments;
11413 int max_offset_count;
11415 int mode = JIT_COMPILE;
11417 if ((options & PCRE_PARTIAL_HARD) != 0)
11418 mode = JIT_PARTIAL_HARD_COMPILE;
11419 else if ((options & PCRE_PARTIAL_SOFT) != 0)
11420 mode = JIT_PARTIAL_SOFT_COMPILE;
11422 if (functions->executable_funcs[mode] == NULL)
11423 return PCRE_ERROR_JIT_BADOPTION;
11425 /* Sanity checks should be handled by pcre_exec. */
11426 arguments.str = subject + start_offset;
11427 arguments.begin = subject;
11428 arguments.end = subject + length;
11429 arguments.mark_ptr = NULL;
11430 /* JIT decreases this value less frequently than the interpreter. */
11431 arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (sljit_u32)(extra_data->match_limit);
11432 if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
11433 arguments.limit_match = functions->limit_match;
11434 arguments.notbol = (options & PCRE_NOTBOL) != 0;
11435 arguments.noteol = (options & PCRE_NOTEOL) != 0;
11436 arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
11437 arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
11438 arguments.offsets = offsets;
11439 arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
11440 arguments.real_offset_count = offset_count;
11442 /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
11443 the output vector for storing captured strings, with the remainder used as
11444 workspace. We don't need the workspace here. For compatibility, we limit the
11445 number of captured strings in the same way as pcre_exec(), so that the user
11446 gets the same result with and without JIT. */
11448 if (offset_count != 2)
11449 offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
11450 max_offset_count = functions->top_bracket;
11451 if (offset_count > max_offset_count)
11452 offset_count = max_offset_count;
11453 arguments.offset_count = offset_count;
11455 if (functions->callback)
11456 arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
11458 arguments.stack = (struct sljit_stack *)functions->userdata;
11460 if (arguments.stack == NULL)
11461 retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
11464 convert_executable_func.executable_func = functions->executable_funcs[mode];
11465 retval = convert_executable_func.call_executable_func(&arguments);
11468 if (retval * 2 > offset_count)
11470 if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
11471 *(extra_data->mark) = arguments.mark_ptr;
11476 #if defined COMPILE_PCRE8
11477 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
11478 pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,
11479 PCRE_SPTR subject, int length, int start_offset, int options,
11480 int *offsets, int offset_count, pcre_jit_stack *stack)
11481 #elif defined COMPILE_PCRE16
11482 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
11483 pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
11484 PCRE_SPTR16 subject, int length, int start_offset, int options,
11485 int *offsets, int offset_count, pcre16_jit_stack *stack)
11486 #elif defined COMPILE_PCRE32
11487 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
11488 pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
11489 PCRE_SPTR32 subject, int length, int start_offset, int options,
11490 int *offsets, int offset_count, pcre32_jit_stack *stack)
11493 pcre_uchar *subject_ptr = (pcre_uchar *)subject;
11494 executable_functions *functions = (executable_functions *)extra_data->executable_jit;
11496 void *executable_func;
11497 jit_function call_executable_func;
11498 } convert_executable_func;
11499 jit_arguments arguments;
11500 int max_offset_count;
11502 int mode = JIT_COMPILE;
11504 SLJIT_UNUSED_ARG(argument_re);
11506 /* Plausibility checks */
11507 if ((options & ~PUBLIC_JIT_EXEC_OPTIONS) != 0) return PCRE_ERROR_JIT_BADOPTION;
11509 if ((options & PCRE_PARTIAL_HARD) != 0)
11510 mode = JIT_PARTIAL_HARD_COMPILE;
11511 else if ((options & PCRE_PARTIAL_SOFT) != 0)
11512 mode = JIT_PARTIAL_SOFT_COMPILE;
11514 if (functions->executable_funcs[mode] == NULL)
11515 return PCRE_ERROR_JIT_BADOPTION;
11517 /* Sanity checks should be handled by pcre_exec. */
11518 arguments.stack = (struct sljit_stack *)stack;
11519 arguments.str = subject_ptr + start_offset;
11520 arguments.begin = subject_ptr;
11521 arguments.end = subject_ptr + length;
11522 arguments.mark_ptr = NULL;
11523 /* JIT decreases this value less frequently than the interpreter. */
11524 arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (sljit_u32)(extra_data->match_limit);
11525 if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
11526 arguments.limit_match = functions->limit_match;
11527 arguments.notbol = (options & PCRE_NOTBOL) != 0;
11528 arguments.noteol = (options & PCRE_NOTEOL) != 0;
11529 arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
11530 arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
11531 arguments.offsets = offsets;
11532 arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
11533 arguments.real_offset_count = offset_count;
11535 /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
11536 the output vector for storing captured strings, with the remainder used as
11537 workspace. We don't need the workspace here. For compatibility, we limit the
11538 number of captured strings in the same way as pcre_exec(), so that the user
11539 gets the same result with and without JIT. */
11541 if (offset_count != 2)
11542 offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
11543 max_offset_count = functions->top_bracket;
11544 if (offset_count > max_offset_count)
11545 offset_count = max_offset_count;
11546 arguments.offset_count = offset_count;
11548 convert_executable_func.executable_func = functions->executable_funcs[mode];
11549 retval = convert_executable_func.call_executable_func(&arguments);
11551 if (retval * 2 > offset_count)
11553 if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
11554 *(extra_data->mark) = arguments.mark_ptr;
11560 PRIV(jit_free)(void *executable_funcs)
11563 executable_functions *functions = (executable_functions *)executable_funcs;
11564 for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
11566 if (functions->executable_funcs[i] != NULL)
11567 sljit_free_code(functions->executable_funcs[i]);
11568 free_read_only_data(functions->read_only_data_heads[i], NULL);
11570 SLJIT_FREE(functions, compiler->allocator_data);
11574 PRIV(jit_get_size)(void *executable_funcs)
11578 sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
11579 for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
11580 size += executable_sizes[i];
11585 PRIV(jit_get_target)(void)
11587 return sljit_get_platform_name();
11590 #if defined COMPILE_PCRE8
11591 PCRE_EXP_DECL pcre_jit_stack *
11592 pcre_jit_stack_alloc(int startsize, int maxsize)
11593 #elif defined COMPILE_PCRE16
11594 PCRE_EXP_DECL pcre16_jit_stack *
11595 pcre16_jit_stack_alloc(int startsize, int maxsize)
11596 #elif defined COMPILE_PCRE32
11597 PCRE_EXP_DECL pcre32_jit_stack *
11598 pcre32_jit_stack_alloc(int startsize, int maxsize)
11601 if (startsize < 1 || maxsize < 1)
11603 if (startsize > maxsize)
11604 startsize = maxsize;
11605 startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
11606 maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
11607 return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize, NULL);
11610 #if defined COMPILE_PCRE8
11612 pcre_jit_stack_free(pcre_jit_stack *stack)
11613 #elif defined COMPILE_PCRE16
11615 pcre16_jit_stack_free(pcre16_jit_stack *stack)
11616 #elif defined COMPILE_PCRE32
11618 pcre32_jit_stack_free(pcre32_jit_stack *stack)
11621 sljit_free_stack((struct sljit_stack *)stack, NULL);
11624 #if defined COMPILE_PCRE8
11626 pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
11627 #elif defined COMPILE_PCRE16
11629 pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
11630 #elif defined COMPILE_PCRE32
11632 pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
11635 executable_functions *functions;
11636 if (extra != NULL &&
11637 (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
11638 extra->executable_jit != NULL)
11640 functions = (executable_functions *)extra->executable_jit;
11641 functions->callback = callback;
11642 functions->userdata = userdata;
11646 #if defined COMPILE_PCRE8
11648 pcre_jit_free_unused_memory(void)
11649 #elif defined COMPILE_PCRE16
11651 pcre16_jit_free_unused_memory(void)
11652 #elif defined COMPILE_PCRE32
11654 pcre32_jit_free_unused_memory(void)
11657 sljit_free_unused_memory_exec();
11660 #else /* SUPPORT_JIT */
11662 /* These are dummy functions to avoid linking errors when JIT support is not
11665 #if defined COMPILE_PCRE8
11666 PCRE_EXP_DECL pcre_jit_stack *
11667 pcre_jit_stack_alloc(int startsize, int maxsize)
11668 #elif defined COMPILE_PCRE16
11669 PCRE_EXP_DECL pcre16_jit_stack *
11670 pcre16_jit_stack_alloc(int startsize, int maxsize)
11671 #elif defined COMPILE_PCRE32
11672 PCRE_EXP_DECL pcre32_jit_stack *
11673 pcre32_jit_stack_alloc(int startsize, int maxsize)
11681 #if defined COMPILE_PCRE8
11683 pcre_jit_stack_free(pcre_jit_stack *stack)
11684 #elif defined COMPILE_PCRE16
11686 pcre16_jit_stack_free(pcre16_jit_stack *stack)
11687 #elif defined COMPILE_PCRE32
11689 pcre32_jit_stack_free(pcre32_jit_stack *stack)
11695 #if defined COMPILE_PCRE8
11697 pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
11698 #elif defined COMPILE_PCRE16
11700 pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
11701 #elif defined COMPILE_PCRE32
11703 pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
11711 #if defined COMPILE_PCRE8
11713 pcre_jit_free_unused_memory(void)
11714 #elif defined COMPILE_PCRE16
11716 pcre16_jit_free_unused_memory(void)
11717 #elif defined COMPILE_PCRE32
11719 pcre32_jit_free_unused_memory(void)
11726 /* End of pcre_jit_compile.c */