46#if defined(__has_feature)
47#if __has_feature(memory_sanitizer)
48#include <sanitizer/msan_interface.h>
60#define SLJIT_CONFIG_AUTO 1
61#define SLJIT_CONFIG_STATIC 1
62#define SLJIT_VERBOSE 0
70#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)
71#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)
73static void * pcre2_jit_malloc(
size_t size,
void *allocator_data)
79static void pcre2_jit_free(
void *
ptr,
void *allocator_data)
87#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
88#error Unsupported architecture
102#define MACHINE_STACK_SIZE 32768
106#define STACK_GROWTH_RATE 8192
109#if defined SLJIT_DEBUG && SLJIT_DEBUG
110#define DESTROY_REGISTERS 1
183typedef struct jit_arguments {
185 struct sljit_stack *stack;
201#define JIT_NUMBER_OF_COMPILE_MODES 3
203typedef struct executable_functions {
204 void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
205 void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
206 sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
209} executable_functions;
211typedef struct jump_list {
212 struct sljit_jump *jump;
213 struct jump_list *
next;
216typedef struct stub_list {
217 struct sljit_jump *
start;
218 struct sljit_label *quit;
219 struct stub_list *
next;
232enum early_fail_types {
244typedef struct backtrack_common {
247 struct backtrack_common *
prev;
251 jump_list *simple_backtracks;
255 struct backtrack_common *
top;
259 jump_list *own_backtracks;
264typedef struct assert_backtrack {
265 backtrack_common common;
266 jump_list *condfailed;
270 int private_data_ptr;
272 struct sljit_label *matchingpath;
275typedef struct bracket_backtrack {
276 backtrack_common common;
278 struct sljit_label *alternative_matchingpath;
280 struct sljit_label *recursive_matchingpath;
282 struct sljit_label *zero_matchingpath;
286 jump_list *condfailed;
291 struct sljit_jump *matching_mov_addr;
294 int private_data_ptr;
297typedef struct bracketpos_backtrack {
298 backtrack_common common;
300 int private_data_ptr;
305} bracketpos_backtrack;
307typedef struct braminzero_backtrack {
308 backtrack_common common;
309 struct sljit_label *matchingpath;
310} braminzero_backtrack;
312typedef struct char_iterator_backtrack {
313 backtrack_common common;
315 struct sljit_label *matchingpath;
317 jump_list *backtracks;
319 unsigned int othercasebit;
324} char_iterator_backtrack;
326typedef struct ref_iterator_backtrack {
327 backtrack_common common;
329 struct sljit_label *matchingpath;
330} ref_iterator_backtrack;
332typedef struct recurse_entry {
333 struct recurse_entry *
next;
335 struct sljit_label *entry_label;
337 struct sljit_label *backtrack_label;
339 jump_list *entry_calls;
341 jump_list *backtrack_calls;
346typedef struct recurse_backtrack {
347 backtrack_common common;
349 struct sljit_label *matchingpath;
351 recurse_entry *entry;
353 BOOL inlined_pattern;
356typedef struct vreverse_backtrack {
357 backtrack_common common;
359 struct sljit_label *matchingpath;
362#define OP_THEN_TRAP OP_TABLE_LENGTH
364typedef struct then_trap_backtrack {
365 backtrack_common common;
368 struct then_trap_backtrack *then_trap;
375} then_trap_backtrack;
377#define MAX_N_CHARS 12
378#define MAX_DIFF_CHARS 5
380typedef struct fast_forward_char_data {
387} fast_forward_char_data;
389#define MAX_CLASS_RANGE_SIZE 4
390#define MAX_CLASS_CHARS_SIZE 3
392typedef struct compiler_common {
394 struct sljit_compiler *compiler;
402 void *read_only_data_head;
408 then_trap_backtrack *then_trap;
441 uint8_t *recurse_bitset;
449 BOOL allow_empty_partial;
459 BOOL has_skip_in_assert_back;
461 BOOL local_quit_available;
463 BOOL in_positive_assertion;
482 struct sljit_label *partialmatchlabel;
483 struct sljit_label *quit_label;
484 struct sljit_label *abort_label;
485 struct sljit_label *accept_label;
486 struct sljit_label *ff_newline_shortcut;
488 recurse_entry *entries;
489 recurse_entry *currententry;
490 jump_list *partialmatch;
492 jump_list *positive_assertion_quit;
494 jump_list *failed_match;
496 jump_list *calllimit;
497 jump_list *stackalloc;
498 jump_list *revertframes;
499 jump_list *wordboundary;
500 jump_list *ucp_wordboundary;
501 jump_list *anynewline;
504 jump_list *casefulcmp;
505 jump_list *caselesscmp;
506 jump_list *reset_match;
508 jump_list *restart_match;
511#ifdef SUPPORT_UNICODE
518 jump_list *getucdtype;
519#if PCRE2_CODE_UNIT_WIDTH == 8
520 jump_list *utfreadchar;
521 jump_list *utfreadtype8;
522 jump_list *utfpeakcharback;
524#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
525 jump_list *utfreadchar_invalid;
526 jump_list *utfreadnewline_invalid;
527 jump_list *utfmoveback_invalid;
528 jump_list *utfpeakcharback_invalid;
535typedef struct compare_context {
538#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
543#if PCRE2_CODE_UNIT_WIDTH == 8
546#elif PCRE2_CODE_UNIT_WIDTH == 16
548#elif PCRE2_CODE_UNIT_WIDTH == 32
555#if PCRE2_CODE_UNIT_WIDTH == 8
558#elif PCRE2_CODE_UNIT_WIDTH == 16
560#elif PCRE2_CODE_UNIT_WIDTH == 32
571#define STACK(i) ((i) * SSIZE_OF(sw))
573#ifdef SLJIT_PREF_SHIFT_REG
574#if SLJIT_PREF_SHIFT_REG == SLJIT_R2
576#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
577#define SHIFT_REG_IS_R3
579#error "Unsupported shift register"
584#ifdef SHIFT_REG_IS_R3
591#define STR_PTR SLJIT_R1
592#define STR_END SLJIT_S0
593#define STACK_TOP SLJIT_S1
594#define STACK_LIMIT SLJIT_S2
595#define COUNT_MATCH SLJIT_S3
596#define ARGUMENTS SLJIT_S4
597#define RETURN_ADDR SLJIT_R4
599#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
600#define HAS_VIRTUAL_REGISTERS 1
602#define HAS_VIRTUAL_REGISTERS 0
607#define LOCALS0 (0 * sizeof(sljit_sw))
608#define LOCALS1 (1 * sizeof(sljit_sw))
610#define POSSESSIVE0 (2 * sizeof(sljit_sw))
611#define POSSESSIVE1 (3 * sizeof(sljit_sw))
613#define LIMIT_MATCH (4 * sizeof(sljit_sw))
618#define OVECTOR_START (common->ovector_start)
619#define OVECTOR(i) (OVECTOR_START + (i) * SSIZE_OF(sw))
620#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * SSIZE_OF(sw))
621#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
623#if PCRE2_CODE_UNIT_WIDTH == 8
624#define MOV_UCHAR SLJIT_MOV_U8
625#define IN_UCHARS(x) (x)
626#elif PCRE2_CODE_UNIT_WIDTH == 16
627#define MOV_UCHAR SLJIT_MOV_U16
628#define UCHAR_SHIFT (1)
629#define IN_UCHARS(x) ((x) * 2)
630#elif PCRE2_CODE_UNIT_WIDTH == 32
631#define MOV_UCHAR SLJIT_MOV_U32
632#define UCHAR_SHIFT (2)
633#define IN_UCHARS(x) ((x) * 4)
635#error Unsupported compiling mode
639#define DEFINE_COMPILER \
640 struct sljit_compiler *compiler = common->compiler
641#define OP1(op, dst, dstw, src, srcw) \
642 sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
643#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
644 sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
645#define OP2U(op, src1, src1w, src2, src2w) \
646 sljit_emit_op2u(compiler, (op), (src1), (src1w), (src2), (src2w))
647#define OP_SRC(op, src, srcw) \
648 sljit_emit_op_src(compiler, (op), (src), (srcw))
650 sljit_emit_label(compiler)
652 sljit_emit_jump(compiler, (type))
653#define JUMPTO(type, label) \
654 sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
655#define JUMPHERE(jump) \
656 sljit_set_label((jump), sljit_emit_label(compiler))
657#define SET_LABEL(jump, label) \
658 sljit_set_label((jump), (label))
659#define CMP(type, src1, src1w, src2, src2w) \
660 sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
661#define CMPTO(type, src1, src1w, src2, src2w, label) \
662 sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
663#define OP_FLAGS(op, dst, dstw, type) \
664 sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type))
665#define SELECT(type, dst_reg, src1, src1w, src2_reg) \
666 sljit_emit_select(compiler, (type), (dst_reg), (src1), (src1w), (src2_reg))
667#define GET_LOCAL_BASE(dst, dstw, offset) \
668 sljit_get_local_base(compiler, (dst), (dstw), (offset))
670#define READ_CHAR_MAX 0x7fffffff
672#define INVALID_UTF_CHAR -1
673#define UNASSIGNED_UTF_CHAR 888
675#if defined SUPPORT_UNICODE
676#if PCRE2_CODE_UNIT_WIDTH == 8
678#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
680 if (ptr[0] <= 0x7f) \
682 else if (ptr + 1 < end && ptr[1] >= 0x80 && ptr[1] < 0xc0) \
686 if (ptr[0] >= 0xc2 && ptr[0] <= 0xdf) \
688 c |= (ptr[0] - 0xc0) << 6; \
691 else if (ptr + 2 < end && ptr[2] >= 0x80 && ptr[2] < 0xc0) \
693 c = c << 6 | (ptr[2] - 0x80); \
695 if (ptr[0] >= 0xe0 && ptr[0] <= 0xef) \
697 c |= (ptr[0] - 0xe0) << 12; \
700 if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \
705 else if (ptr + 3 < end && ptr[3] >= 0x80 && ptr[3] < 0xc0) \
707 c = c << 6 | (ptr[3] - 0x80); \
709 if (ptr[0] >= 0xf0 && ptr[0] <= 0xf4) \
711 c |= (ptr[0] - 0xf0) << 18; \
714 if (c >= 0x110000 || c < 0x10000) \
740#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
745 else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \
749 if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \
751 c |= (ptr[-2] - 0xc0) << 6; \
754 else if (ptr - 2 > start && ptr[-2] >= 0x80 && ptr[-2] < 0xc0) \
756 c = c << 6 | (ptr[-2] - 0x80); \
758 if (ptr[-3] >= 0xe0 && ptr[-3] <= 0xef) \
760 c |= (ptr[-3] - 0xe0) << 12; \
763 if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \
768 else if (ptr - 3 > start && ptr[-3] >= 0x80 && ptr[-3] < 0xc0) \
770 c = c << 6 | (ptr[-3] - 0x80); \
772 if (ptr[-4] >= 0xf0 && ptr[-4] <= 0xf4) \
774 c |= (ptr[-4] - 0xf0) << 18; \
777 if (c >= 0x110000 || c < 0x10000) \
803#elif PCRE2_CODE_UNIT_WIDTH == 16
805#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
807 if (ptr[0] < 0xd800 || ptr[0] >= 0xe000) \
809 else if (ptr[0] < 0xdc00 && ptr + 1 < end && ptr[1] >= 0xdc00 && ptr[1] < 0xe000) \
811 c = (((ptr[0] - 0xd800) << 10) | (ptr[1] - 0xdc00)) + 0x10000; \
820#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
823 if (c < 0xd800 || c >= 0xe000) \
825 else if (c >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \
827 c = (((ptr[-2] - 0xd800) << 10) | (c - 0xdc00)) + 0x10000; \
837#elif PCRE2_CODE_UNIT_WIDTH == 32
839#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
841 if (ptr[0] < 0xd800 || (ptr[0] >= 0xe000 && ptr[0] < 0x110000)) \
849#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
852 if (ptr[-1] < 0xd800 || (ptr[-1] >= 0xe000 && ptr[-1] < 0x110000)) \
866do cc +=
GET(cc, 1);
while (*cc ==
OP_ALT);
1069#ifdef SUPPORT_UNICODE
1070 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1091#ifdef SUPPORT_UNICODE
1092 if (common->utf)
return NULL;
1099#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
1101 return cc +
GET(cc, 1);
1109 return cc + 1 + 2 + cc[1];
1130 common->has_set_som =
TRUE;
1131 common->might_be_empty =
TRUE;
1136#ifdef SUPPORT_UNICODE
1137 if (common->iref_ptr == 0)
1139 common->iref_ptr = common->ovector_start;
1140 common->ovector_start += 3 *
sizeof(
sljit_sw);
1145 common->optimized_cbracket[
GET2(cc, 1)] = 0;
1151 slot = bracketend(cc);
1152 if (slot > assert_na_end)
1153 assert_na_end = slot;
1173 common->optimized_cbracket[
GET2(cc, 1)] = 0;
1181 slot = common->name_table +
GET2(cc, 1) * common->name_entry_size;
1184 common->optimized_cbracket[
GET2(slot, 0)] = 0;
1185 slot += common->name_entry_size;
1192 if (common->recursive_head_ptr == 0)
1194 common->recursive_head_ptr = common->ovector_start;
1195 common->ovector_start +=
sizeof(
sljit_sw);
1202 if (common->capture_last_ptr == 0)
1204 common->capture_last_ptr = common->ovector_start;
1205 common->ovector_start +=
sizeof(
sljit_sw);
1211 slot = bracketend(cc);
1212 if (slot > assert_back_end)
1213 assert_back_end = slot;
1218 common->has_then =
TRUE;
1219 common->control_head_ptr = 1;
1224 if (cc < assert_na_end)
1228 if (common->mark_ptr == 0)
1230 common->mark_ptr = common->ovector_start;
1231 common->ovector_start +=
sizeof(
sljit_sw);
1233 cc += 1 + 2 + cc[1];
1237 common->has_then =
TRUE;
1238 common->control_head_ptr = 1;
1243 if (cc < assert_back_end)
1244 common->has_skip_in_assert_back =
TRUE;
1245 if (cc < assert_na_end)
1251 common->control_head_ptr = 1;
1252 common->has_skip_arg =
TRUE;
1253 if (cc < assert_back_end)
1254 common->has_skip_in_assert_back =
TRUE;
1255 if (cc < assert_na_end)
1257 cc += 1 + 2 + cc[1];
1263 if (cc < assert_na_end)
1269 cc = next_opcode(common, cc);
1278#define EARLY_FAIL_ENHANCE_MAX (3 + 3)
1292static int detect_early_fail(compiler_common *common,
PCRE2_SPTR cc,
1300int count, prev_count;
1306next_alt = cc +
GET(cc, 1);
1317 accelerated_start =
NULL;
1377#ifdef SUPPORT_UNICODE
1378 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1397 accelerated_start = cc - 1;
1457 accelerated_start = cc;
1459#ifdef SUPPORT_UNICODE
1460 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1468#ifdef SUPPORT_UNICODE
1469 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1506#ifdef SUPPORT_UNICODE
1507 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1513#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
1515 accelerated_start = cc;
1518 accelerated_start = cc;
1579 end = bracketend(cc);
1583 prev_count = detect_early_fail(common, cc, private_data_start, depth + 1, prev_count);
1585 if (prev_count >
count)
1588 if (PRIVATE_DATA(cc) != 0)
1589 common->private_data_ptrs[
begin - common->start] = 1;
1591 if (
count < EARLY_FAIL_ENHANCE_MAX)
1606 if (accelerated_start ==
NULL)
1611 common->fast_forward_bc_ptr = accelerated_start;
1612 common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip;
1613 *private_data_start +=
sizeof(
sljit_sw);
1618 common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail;
1620 if (common->early_fail_start_ptr == 0)
1621 common->early_fail_start_ptr = *private_data_start;
1623 *private_data_start +=
sizeof(
sljit_sw);
1624 common->early_fail_end_ptr = *private_data_start;
1627 return EARLY_FAIL_ENHANCE_MAX;
1633 common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range;
1635 if (common->early_fail_start_ptr == 0)
1636 common->early_fail_start_ptr = *private_data_start;
1638 *private_data_start += 2 *
sizeof(
sljit_sw);
1639 common->early_fail_end_ptr = *private_data_start;
1642 return EARLY_FAIL_ENHANCE_MAX;
1648 common->private_data_ptrs[
begin - common->start] = 1;
1650 if (
count >= EARLY_FAIL_ENHANCE_MAX)
1655 result = EARLY_FAIL_ENHANCE_MAX;
1660 next_alt = cc +
GET(cc, 1);
1667static int get_class_iterator_size(
PCRE2_SPTR cc)
1724 next_end = bracketend(
next);
1725 if (next_end -
next != length || memcmp(
begin,
next, IN_UCHARS(length)) != 0)
1752 next_end = bracketend(
next + 1);
1753 if (next_end -
next == (length + 1) && memcmp(
begin,
next + 1, IN_UCHARS(length)) == 0)
1761 common->private_data_ptrs[max_end - common->start -
LINK_SIZE] = next_end - max_end;
1764 common->private_data_ptrs[max_end - common->start -
LINK_SIZE + 2] =
max + 2;
1776 common->private_data_ptrs[
end - common->start -
LINK_SIZE] = max_end -
end;
1785#define CASE_ITERATOR_PRIVATE_DATA_1 \
1793 case OP_MINQUERYI: \
1794 case OP_NOTMINSTAR: \
1795 case OP_NOTMINPLUS: \
1797 case OP_NOTMINQUERY: \
1798 case OP_NOTMINSTARI: \
1799 case OP_NOTMINPLUSI: \
1800 case OP_NOTQUERYI: \
1801 case OP_NOTMINQUERYI:
1803#define CASE_ITERATOR_PRIVATE_DATA_2A \
1813#define CASE_ITERATOR_PRIVATE_DATA_2B \
1819 case OP_NOTMINUPTO: \
1821 case OP_NOTMINUPTOI:
1823#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1824 case OP_TYPEMINSTAR: \
1825 case OP_TYPEMINPLUS: \
1826 case OP_TYPEQUERY: \
1827 case OP_TYPEMINQUERY:
1829#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1833#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1835 case OP_TYPEMINUPTO:
1837static void set_private_data_ptrs(compiler_common *common,
int *private_data_start,
PCRE2_SPTR ccend)
1842int private_data_ptr = *private_data_start;
1843int space,
size, bracketlen;
1857 if (detect_repeat(common, cc))
1862 end = bracketend(cc);
1865 repeat_check =
TRUE;
1870 if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1872 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1873 private_data_ptr +=
sizeof(
sljit_sw);
1874 cc += common->private_data_ptrs[cc + 1 - common->start];
1890 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1891 private_data_ptr +=
sizeof(
sljit_sw);
1896 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1897 private_data_ptr +=
sizeof(
sljit_sw);
1899 if (find_vreverse(cc))
1901 common->private_data_ptrs[cc + 1 - common->start] = 1;
1902 private_data_ptr +=
sizeof(
sljit_sw);
1910 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1911 private_data_ptr +=
sizeof(
sljit_sw);
1917 common->private_data_ptrs[cc - common->start] = 0;
1918 alternative = cc +
GET(cc, 1);
1921 common->private_data_ptrs[cc - common->start] = private_data_ptr;
1922 private_data_ptr +=
sizeof(
sljit_sw);
1940 repeat_check =
FALSE;
1943 CASE_ITERATOR_PRIVATE_DATA_1
1948 CASE_ITERATOR_PRIVATE_DATA_2A
1953 CASE_ITERATOR_PRIVATE_DATA_2B
1958 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1963 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1983 space = get_class_iterator_size(cc +
size);
1986#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
1989 space = get_class_iterator_size(cc +
size);
1994 cc = next_opcode(common, cc);
2001 if (space > 0 && cc >=
end)
2003 common->private_data_ptrs[cc - common->start] = private_data_ptr;
2004 private_data_ptr +=
sizeof(
sljit_sw) * space;
2012#ifdef SUPPORT_UNICODE
2013 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2024 end = bracketend(cc);
2031*private_data_start = private_data_ptr;
2040BOOL setsom_found = recursive;
2041BOOL setmark_found = recursive;
2045#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
2047*needs_control_head =
TRUE;
2049*needs_control_head =
FALSE;
2054 ccend = bracketend(cc) - (1 +
LINK_SIZE);
2057 possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
2059 capture_last_found =
TRUE;
2061 cc = next_opcode(common, cc);
2070 stack_restore =
TRUE;
2074 setsom_found =
TRUE;
2084 stack_restore =
TRUE;
2088 setmark_found =
TRUE;
2090 if (common->control_head_ptr != 0)
2091 *needs_control_head =
TRUE;
2092 cc += 1 + 2 + cc[1];
2096 stack_restore =
TRUE;
2097 if (common->has_set_som && !setsom_found)
2100 setsom_found =
TRUE;
2102 if (common->mark_ptr != 0 && !setmark_found)
2105 setmark_found =
TRUE;
2107 if (common->capture_last_ptr != 0 && !capture_last_found)
2110 capture_last_found =
TRUE;
2119 stack_restore =
TRUE;
2120 if (common->capture_last_ptr != 0 && !capture_last_found)
2123 capture_last_found =
TRUE;
2130 stack_restore =
TRUE;
2131 if (common->control_head_ptr != 0)
2132 *needs_control_head =
TRUE;
2137 stack_restore =
TRUE;
2210 cc = next_opcode(common, cc);
2217 return stack_restore ? no_frame : no_stack;
2221return stack_restore ? no_frame : no_stack;
2224static void init_frame(compiler_common *common,
PCRE2_SPTR cc,
PCRE2_SPTR ccend,
int stackpos,
int stacktop)
2237stackpos = STACK(stackpos);
2240 ccend = bracketend(cc) - (1 +
LINK_SIZE);
2242 cc = next_opcode(common, cc);
2255 stackpos -= SSIZE_OF(sw);
2257 stackpos -= SSIZE_OF(sw);
2258 setsom_found =
TRUE;
2272 stackpos -= SSIZE_OF(sw);
2274 stackpos -= SSIZE_OF(sw);
2275 setmark_found =
TRUE;
2277 cc += 1 + 2 + cc[1];
2281 if (common->has_set_som && !setsom_found)
2285 stackpos -= SSIZE_OF(sw);
2287 stackpos -= SSIZE_OF(sw);
2288 setsom_found =
TRUE;
2290 if (common->mark_ptr != 0 && !setmark_found)
2294 stackpos -= SSIZE_OF(sw);
2296 stackpos -= SSIZE_OF(sw);
2297 setmark_found =
TRUE;
2299 if (common->capture_last_ptr != 0 && !capture_last_found)
2303 stackpos -= SSIZE_OF(sw);
2305 stackpos -= SSIZE_OF(sw);
2306 capture_last_found =
TRUE;
2315 if (common->capture_last_ptr != 0 && !capture_last_found)
2319 stackpos -= SSIZE_OF(sw);
2321 stackpos -= SSIZE_OF(sw);
2322 capture_last_found =
TRUE;
2326 stackpos -= SSIZE_OF(sw);
2330 stackpos -= SSIZE_OF(sw);
2332 stackpos -= SSIZE_OF(sw);
2338 cc = next_opcode(common, cc);
2347#define RECURSE_TMP_REG_COUNT 3
2349typedef struct delayed_mem_copy_status {
2350 struct sljit_compiler *compiler;
2351 int store_bases[RECURSE_TMP_REG_COUNT];
2352 int store_offsets[RECURSE_TMP_REG_COUNT];
2353 int tmp_regs[RECURSE_TMP_REG_COUNT];
2354 int saved_tmp_regs[RECURSE_TMP_REG_COUNT];
2356} delayed_mem_copy_status;
2358static void delayed_mem_copy_init(delayed_mem_copy_status *
status, compiler_common *common)
2362for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
2367 status->store_bases[i] = -1;
2370status->compiler = common->compiler;
2373static void delayed_mem_copy_move(delayed_mem_copy_status *
status,
int load_base,
sljit_sw load_offset,
2374 int store_base,
sljit_sw store_offset)
2377int next_tmp_reg =
status->next_tmp_reg;
2378int tmp_reg =
status->tmp_regs[next_tmp_reg];
2382if (
status->store_bases[next_tmp_reg] == -1)
2392status->store_bases[next_tmp_reg] = store_base;
2393status->store_offsets[next_tmp_reg] = store_offset;
2395status->next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
2398static void delayed_mem_copy_finish(delayed_mem_copy_status *
status)
2401int next_tmp_reg =
status->next_tmp_reg;
2402int tmp_reg, saved_tmp_reg, i;
2404for (i = 0; i < RECURSE_TMP_REG_COUNT; i++)
2406 if (
status->store_bases[next_tmp_reg] != -1)
2408 tmp_reg =
status->tmp_regs[next_tmp_reg];
2409 saved_tmp_reg =
status->saved_tmp_regs[next_tmp_reg];
2415 OP1(
SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0);
2418 next_tmp_reg = (next_tmp_reg + 1) % RECURSE_TMP_REG_COUNT;
2422#undef RECURSE_TMP_REG_COUNT
2424static BOOL recurse_check_bit(compiler_common *common,
sljit_sw bit_index)
2433SLJIT_ASSERT((bit_index >> 3) < common->recurse_bitset_size);
2435mask = 1 << (bit_index & 0x7);
2436byte = common->recurse_bitset + (bit_index >> 3);
2445enum get_recurse_flags {
2446 recurse_flag_quit_found = (1 << 0),
2447 recurse_flag_accept_found = (1 << 1),
2448 recurse_flag_setsom_found = (1 << 2),
2449 recurse_flag_setmark_found = (1 << 3),
2450 recurse_flag_control_head_found = (1 << 4),
2453static int get_recurse_data_length(compiler_common *common,
PCRE2_SPTR cc,
PCRE2_SPTR ccend, uint32_t *result_flags)
2458uint32_t recurse_flags = 0;
2460memset(common->recurse_bitset, 0, common->recurse_bitset_size);
2462#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
2464recurse_flags |= recurse_flag_control_head_found;
2475 recurse_flags |= recurse_flag_setsom_found;
2480 if (common->has_set_som)
2481 recurse_flags |= recurse_flag_setsom_found;
2482 if (common->mark_ptr != 0)
2483 recurse_flags |= recurse_flag_setmark_found;
2484 if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
2490 offset = PRIVATE_DATA(cc);
2493 if (recurse_check_bit(common,
offset))
2496 cc += PRIVATE_DATA(cc + 1);
2514 if (recurse_check_bit(common, PRIVATE_DATA(cc)))
2522 if (recurse_check_bit(common, OVECTOR(
offset << 1)))
2527 if (common->optimized_cbracket[
offset] == 0 && recurse_check_bit(common, OVECTOR_PRIV(
offset)))
2529 if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
2537 if (recurse_check_bit(common, OVECTOR(
offset << 1)))
2542 if (recurse_check_bit(common, OVECTOR_PRIV(
offset)))
2544 if (recurse_check_bit(common, PRIVATE_DATA(cc)))
2546 if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
2553 alternative = cc +
GET(cc, 1);
2554 if ((*alternative ==
OP_KETRMAX || *alternative ==
OP_KETRMIN) && recurse_check_bit(common, PRIVATE_DATA(cc)))
2559 CASE_ITERATOR_PRIVATE_DATA_1
2560 offset = PRIVATE_DATA(cc);
2564#ifdef SUPPORT_UNICODE
2565 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2569 CASE_ITERATOR_PRIVATE_DATA_2A
2570 offset = PRIVATE_DATA(cc);
2577#ifdef SUPPORT_UNICODE
2578 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2582 CASE_ITERATOR_PRIVATE_DATA_2B
2583 offset = PRIVATE_DATA(cc);
2590#ifdef SUPPORT_UNICODE
2591 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2595 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2596 offset = PRIVATE_DATA(cc);
2602 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2603 offset = PRIVATE_DATA(cc);
2612 CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2613 offset = PRIVATE_DATA(cc);
2624#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
2631 offset = PRIVATE_DATA(cc);
2633 length += get_class_iterator_size(cc +
size);
2642 recurse_flags |= recurse_flag_setmark_found;
2643 if (common->control_head_ptr != 0)
2644 recurse_flags |= recurse_flag_control_head_found;
2646 recurse_flags |= recurse_flag_quit_found;
2648 cc += 1 + 2 + cc[1];
2654 recurse_flags |= recurse_flag_quit_found;
2659 recurse_flags |= recurse_flag_quit_found;
2660 cc += 1 + 2 + cc[1];
2665 recurse_flags |= recurse_flag_quit_found | recurse_flag_control_head_found;
2671 recurse_flags |= recurse_flag_accept_found;
2676 cc = next_opcode(common, cc);
2683if (recurse_flags & recurse_flag_control_head_found)
2685if (recurse_flags & recurse_flag_quit_found)
2687 if (recurse_flags & recurse_flag_setsom_found)
2689 if (recurse_flags & recurse_flag_setmark_found)
2693*result_flags = recurse_flags;
2697enum copy_recurse_data_types {
2698 recurse_copy_from_global,
2699 recurse_copy_private_to_global,
2700 recurse_copy_shared_to_global,
2701 recurse_copy_kept_shared_to_global,
2706 int type,
int stackptr,
int stacktop, uint32_t recurse_flags)
2708delayed_mem_copy_status
status;
2713int private_count, shared_count, kept_shared_count;
2714int from_sp, base_reg,
offset, i;
2716memset(common->recurse_bitset, 0, common->recurse_bitset_size);
2718#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
2720recurse_check_bit(common, common->control_head_ptr);
2725 case recurse_copy_from_global:
2727 base_reg = STACK_TOP;
2730 case recurse_copy_private_to_global:
2731 case recurse_copy_shared_to_global:
2732 case recurse_copy_kept_shared_to_global:
2734 base_reg = STACK_TOP;
2744stackptr = STACK(stackptr);
2745stacktop = STACK(stacktop);
2747status.tmp_regs[0] = TMP1;
2748status.saved_tmp_regs[0] = TMP1;
2750if (base_reg != TMP2)
2752 status.tmp_regs[1] = TMP2;
2753 status.saved_tmp_regs[1] = TMP2;
2757 status.saved_tmp_regs[1] = RETURN_ADDR;
2758 if (HAS_VIRTUAL_REGISTERS)
2759 status.tmp_regs[1] = STR_PTR;
2761 status.tmp_regs[1] = RETURN_ADDR;
2764status.saved_tmp_regs[2] = TMP3;
2765if (HAS_VIRTUAL_REGISTERS)
2766 status.tmp_regs[2] = STR_END;
2768 status.tmp_regs[2] = TMP3;
2770delayed_mem_copy_init(&
status, common);
2772if (
type != recurse_copy_shared_to_global &&
type != recurse_copy_kept_shared_to_global)
2774 SLJIT_ASSERT(
type == recurse_copy_from_global ||
type == recurse_copy_private_to_global ||
type == recurse_swap_global);
2777 delayed_mem_copy_move(&
status, base_reg, stackptr,
SLJIT_SP, common->recursive_head_ptr);
2779 if (from_sp ||
type == recurse_swap_global)
2780 delayed_mem_copy_move(&
status,
SLJIT_SP, common->recursive_head_ptr, base_reg, stackptr);
2785#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
2786if (
type != recurse_copy_shared_to_global)
2789 delayed_mem_copy_move(&
status, base_reg, stackptr,
SLJIT_SP, common->control_head_ptr);
2791 if (from_sp ||
type == recurse_swap_global)
2792 delayed_mem_copy_move(&
status,
SLJIT_SP, common->control_head_ptr, base_reg, stackptr);
2802 kept_shared_count = 0;
2808 if ((recurse_flags & recurse_flag_quit_found) && recurse_check_bit(common, OVECTOR(0)))
2810 kept_shared_srcw[0] = OVECTOR(0);
2811 kept_shared_count = 1;
2817 if (recurse_flags & recurse_flag_quit_found)
2819 if (common->has_set_som && recurse_check_bit(common, OVECTOR(0)))
2821 kept_shared_srcw[0] = OVECTOR(0);
2822 kept_shared_count = 1;
2824 if (common->mark_ptr != 0 && recurse_check_bit(common, common->mark_ptr))
2826 kept_shared_srcw[kept_shared_count] = common->mark_ptr;
2827 kept_shared_count++;
2830 if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
2832 shared_srcw[0] = common->capture_last_ptr;
2839 private_srcw[0] = PRIVATE_DATA(cc);
2840 if (private_srcw[0] != 0)
2842 if (recurse_check_bit(common, private_srcw[0]))
2845 cc += PRIVATE_DATA(cc + 1);
2862 private_srcw[0] = PRIVATE_DATA(cc);
2863 if (recurse_check_bit(common, private_srcw[0]))
2871 shared_srcw[0] = OVECTOR(
offset << 1);
2872 if (recurse_check_bit(common, shared_srcw[0]))
2874 shared_srcw[1] = shared_srcw[0] +
sizeof(
sljit_sw);
2875 SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
2879 if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
2881 shared_srcw[shared_count] = common->capture_last_ptr;
2885 if (common->optimized_cbracket[
offset] == 0)
2887 private_srcw[0] = OVECTOR_PRIV(
offset);
2888 if (recurse_check_bit(common, private_srcw[0]))
2898 shared_srcw[0] = OVECTOR(
offset << 1);
2899 if (recurse_check_bit(common, shared_srcw[0]))
2901 shared_srcw[1] = shared_srcw[0] +
sizeof(
sljit_sw);
2902 SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
2906 if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
2908 shared_srcw[shared_count] = common->capture_last_ptr;
2912 private_srcw[0] = PRIVATE_DATA(cc);
2913 if (recurse_check_bit(common, private_srcw[0]))
2917 if (recurse_check_bit(common,
offset))
2919 private_srcw[private_count] =
offset;
2927 alternative = cc +
GET(cc, 1);
2930 private_srcw[0] = PRIVATE_DATA(cc);
2931 if (recurse_check_bit(common, private_srcw[0]))
2937 CASE_ITERATOR_PRIVATE_DATA_1
2938 private_srcw[0] = PRIVATE_DATA(cc);
2939 if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
2942#ifdef SUPPORT_UNICODE
2943 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2947 CASE_ITERATOR_PRIVATE_DATA_2A
2948 private_srcw[0] = PRIVATE_DATA(cc);
2949 if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
2952 private_srcw[1] = private_srcw[0] +
sizeof(
sljit_sw);
2953 SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
2956#ifdef SUPPORT_UNICODE
2957 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2961 CASE_ITERATOR_PRIVATE_DATA_2B
2962 private_srcw[0] = PRIVATE_DATA(cc);
2963 if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
2966 private_srcw[1] = private_srcw[0] +
sizeof(
sljit_sw);
2967 SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
2970#ifdef SUPPORT_UNICODE
2971 if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2975 CASE_ITERATOR_TYPE_PRIVATE_DATA_1
2976 private_srcw[0] = PRIVATE_DATA(cc);
2977 if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
2982 CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
2983 private_srcw[0] = PRIVATE_DATA(cc);
2984 if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
2987 private_srcw[1] = private_srcw[0] +
sizeof(
sljit_sw);
2988 SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
2993 CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
2994 private_srcw[0] = PRIVATE_DATA(cc);
2995 if (private_srcw[0] != 0 && recurse_check_bit(common, private_srcw[0]))
2998 private_srcw[1] = private_srcw[0] +
sizeof(
sljit_sw);
2999 SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
3006#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
3012 if (PRIVATE_DATA(cc) != 0)
3015 private_srcw[0] = PRIVATE_DATA(cc);
3016 switch(get_class_iterator_size(cc + i))
3022 if (recurse_check_bit(common, private_srcw[0]))
3025 private_srcw[1] = private_srcw[0] +
sizeof(
sljit_sw);
3026 SLJIT_ASSERT(recurse_check_bit(common, private_srcw[1]));
3043 if ((recurse_flags & recurse_flag_quit_found) && recurse_check_bit(common, common->mark_ptr))
3045 kept_shared_srcw[0] = common->mark_ptr;
3046 kept_shared_count = 1;
3048 if (common->control_head_ptr != 0 && recurse_check_bit(common, common->control_head_ptr))
3050 private_srcw[0] = common->control_head_ptr;
3053 cc += 1 + 2 + cc[1];
3058 if (recurse_check_bit(common, common->control_head_ptr))
3060 private_srcw[0] = common->control_head_ptr;
3067 cc = next_opcode(common, cc);
3072 if (
type != recurse_copy_shared_to_global &&
type != recurse_copy_kept_shared_to_global)
3074 SLJIT_ASSERT(
type == recurse_copy_from_global ||
type == recurse_copy_private_to_global ||
type == recurse_swap_global);
3076 for (i = 0; i < private_count; i++)
3081 delayed_mem_copy_move(&
status, base_reg, stackptr,
SLJIT_SP, private_srcw[i]);
3083 if (from_sp ||
type == recurse_swap_global)
3084 delayed_mem_copy_move(&
status,
SLJIT_SP, private_srcw[i], base_reg, stackptr);
3090 stackptr +=
sizeof(
sljit_sw) * private_count;
3092 if (
type != recurse_copy_private_to_global &&
type != recurse_copy_kept_shared_to_global)
3094 SLJIT_ASSERT(
type == recurse_copy_from_global ||
type == recurse_copy_shared_to_global ||
type == recurse_swap_global);
3096 for (i = 0; i < shared_count; i++)
3101 delayed_mem_copy_move(&
status, base_reg, stackptr,
SLJIT_SP, shared_srcw[i]);
3103 if (from_sp ||
type == recurse_swap_global)
3104 delayed_mem_copy_move(&
status,
SLJIT_SP, shared_srcw[i], base_reg, stackptr);
3110 stackptr +=
sizeof(
sljit_sw) * shared_count;
3112 if (
type != recurse_copy_private_to_global &&
type != recurse_swap_global)
3114 SLJIT_ASSERT(
type == recurse_copy_from_global ||
type == recurse_copy_shared_to_global ||
type == recurse_copy_kept_shared_to_global);
3116 for (i = 0; i < kept_shared_count; i++)
3121 delayed_mem_copy_move(&
status, base_reg, stackptr,
SLJIT_SP, kept_shared_srcw[i]);
3123 if (from_sp ||
type == recurse_swap_global)
3124 delayed_mem_copy_move(&
status,
SLJIT_SP, kept_shared_srcw[i], base_reg, stackptr);
3130 stackptr +=
sizeof(
sljit_sw) * kept_shared_count;
3135delayed_mem_copy_finish(&
status);
3145 current_offset =
NULL;
3148 has_alternatives =
FALSE;
3150cc = next_opcode(common, cc);
3152if (has_alternatives)
3159 current_offset = common->then_offsets + (cc - common->start);
3165 cc = set_then_offsets(common, cc, current_offset);
3168 if (*cc ==
OP_ALT && has_alternatives)
3177 current_offset = common->then_offsets + (cc - common->start);
3182 *current_offset = 1;
3183 cc = next_opcode(common, cc);
3190#undef CASE_ITERATOR_PRIVATE_DATA_1
3191#undef CASE_ITERATOR_PRIVATE_DATA_2A
3192#undef CASE_ITERATOR_PRIVATE_DATA_2B
3193#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
3194#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
3195#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
3208 SET_LABEL(list->jump, label);
3218 list_item->next = *list;
3219 list_item->jump = jump;
3224static void add_stub(compiler_common *common,
struct sljit_jump *
start)
3231 list_item->start =
start;
3232 list_item->quit = LABEL();
3233 list_item->next = common->stubs;
3234 common->stubs = list_item;
3238static void flush_stubs(compiler_common *common)
3241stub_list *list_item = common->stubs;
3245 JUMPHERE(list_item->start);
3248 list_item = list_item->next;
3250common->stubs =
NULL;
3253static SLJIT_INLINE void count_match(compiler_common *common)
3258add_jump(compiler, &common->calllimit, JUMP(
SLJIT_ZERO));
3268#ifdef DESTROY_REGISTERS
3275add_stub(common,
CMP(
SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));
3301*(
void**)
result = common->read_only_data_head;
3302common->read_only_data_head = (
void *)
result;
3306static SLJIT_INLINE void reset_ovector(compiler_common *common,
int length)
3318 for (i = 1; i < length; i++)
3325 GET_LOCAL_BASE(
SLJIT_R1, 0, OVECTOR_START);
3345static SLJIT_INLINE void reset_early_fail(compiler_common *common)
3354SLJIT_ASSERT(common->early_fail_start_ptr < common->early_fail_end_ptr);
3370 for (i = common->early_fail_start_ptr; i < common->early_fail_end_ptr; i +=
sizeof(
sljit_sw))
3375GET_LOCAL_BASE(TMP1, 0, common->early_fail_start_ptr);
3388if (uncleared_size >=
sizeof(
sljit_sw))
3391if (uncleared_size >= 2 *
sizeof(
sljit_sw))
3395static SLJIT_INLINE void do_reset_match(compiler_common *common,
int length)
3407 for (i = 2; i < length; i++)
3414 GET_LOCAL_BASE(TMP2, 0, OVECTOR_START +
sizeof(
sljit_sw));
3423 GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 *
sizeof(
sljit_sw));
3433if (!HAS_VIRTUAL_REGISTERS)
3436 OP1(
SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
3438if (common->mark_ptr != 0)
3440if (common->control_head_ptr != 0)
3442if (HAS_VIRTUAL_REGISTERS)
3455 case type_then_trap:
3473static SLJIT_INLINE void copy_ovector(compiler_common *common,
int topbracket)
3483if (HAS_VIRTUAL_REGISTERS)
3487 if (common->mark_ptr != 0)
3491 if (common->mark_ptr != 0)
3500 if (common->mark_ptr != 0)
3504 if (common->mark_ptr != 0)
3511GET_LOCAL_BASE(
SLJIT_S0, 0, OVECTOR_START - (has_pre ?
sizeof(
sljit_sw) : 0));
3527#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
3542 GET_LOCAL_BASE(
SLJIT_R0, 0, OVECTOR_START + topbracket * 2 *
sizeof(
sljit_sw));
3554 GET_LOCAL_BASE(
SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 *
sizeof(
sljit_sw));
3577SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
3580if (arguments_reg != ARGUMENTS)
3581 OP1(
SLJIT_MOV, arguments_reg, 0, ARGUMENTS, 0);
3594#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
3600#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
3608static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
3637#ifdef SUPPORT_UNICODE
3638if (common->utf || common->ucp)
3650 return common->fcc[c] != c;
3658static SLJIT_INLINE unsigned int char_othercase(compiler_common *common,
unsigned int c)
3661#ifdef SUPPORT_UNICODE
3662if ((common->utf || common->ucp) && c > 127)
3668static unsigned int char_get_othercase_bit(compiler_common *common,
PCRE2_SPTR cc)
3671unsigned int c, oc, bit;
3672#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
3676#ifdef SUPPORT_UNICODE
3677if (common->utf || common->ucp)
3687 oc = common->fcc[c];
3705if (c <= 127 && bit == 0x20)
3706 return (0 << 8) | 0x20;
3709if (!is_powerof2(bit))
3712#if PCRE2_CODE_UNIT_WIDTH == 8
3714#ifdef SUPPORT_UNICODE
3715if (common->utf && c > 127)
3717 n = GET_EXTRALEN(*cc);
3718 while ((bit & 0x3f) == 0)
3723 return (
n << 8) | bit;
3726return (0 << 8) | bit;
3728#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
3730#ifdef SUPPORT_UNICODE
3731if (common->utf && c > 65535)
3733 if (bit >= (1u << 10))
3736 return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
3739return (bit < 256) ? ((0
u << 8) | bit) : ((1u << 8) | (bit >> 8));
3744static void check_partial(compiler_common *common,
BOOL force)
3755if (!force && !common->allow_empty_partial)
3764 if (common->partialmatchlabel !=
NULL)
3765 JUMPTO(
SLJIT_JUMP, common->partialmatchlabel);
3767 add_jump(compiler, &common->partialmatch, JUMP(
SLJIT_JUMP));
3774static void check_str_end(compiler_common *common, jump_list **end_reached)
3791 add_jump(compiler, end_reached, JUMP(
SLJIT_JUMP));
3796 if (common->partialmatchlabel !=
NULL)
3797 JUMPTO(
SLJIT_JUMP, common->partialmatchlabel);
3799 add_jump(compiler, &common->partialmatch, JUMP(
SLJIT_JUMP));
3804static void detect_partial_match(compiler_common *common, jump_list **backtracks)
3817if (!common->allow_empty_partial)
3825 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
3829 if (common->partialmatchlabel !=
NULL)
3830 JUMPTO(
SLJIT_JUMP, common->partialmatchlabel);
3832 add_jump(compiler, &common->partialmatch, JUMP(
SLJIT_JUMP));
3837static void process_partial_match(compiler_common *common)
3851 if (common->partialmatchlabel !=
NULL)
3858static void detect_partial_match_to(compiler_common *common,
struct sljit_label *
label)
3863process_partial_match(common);
3871#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3880OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3882#ifdef SUPPORT_UNICODE
3883#if PCRE2_CODE_UNIT_WIDTH == 8
3886 if (
max < 128)
return;
3891 add_jump(compiler, common->invalid_utf ? &common->utfreadchar_invalid : &common->utfreadchar, JUMP(
SLJIT_FAST_CALL));
3893 if (backtracks && common->invalid_utf)
3897#elif PCRE2_CODE_UNIT_WIDTH == 16
3900 if (
max < 0xd800)
return;
3904 if (common->invalid_utf)
3909 add_jump(compiler, &common->utfreadchar_invalid, JUMP(
SLJIT_FAST_CALL));
3911 if (backtracks && common->invalid_utf)
3918 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3921 OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
3926#elif PCRE2_CODE_UNIT_WIDTH == 32
3927if (common->invalid_utf)
3929 if (
max < 0xd800)
return;
3931 if (backtracks !=
NULL)
3950static void peek_char_back(compiler_common *common,
sljit_u32 max, jump_list **backtracks)
3956#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
3963OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3965#ifdef SUPPORT_UNICODE
3966#if PCRE2_CODE_UNIT_WIDTH == 8
3969 if (
max < 128)
return;
3972 if (common->invalid_utf)
3974 add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(
SLJIT_FAST_CALL));
3975 if (backtracks !=
NULL)
3982#elif PCRE2_CODE_UNIT_WIDTH == 16
3985 if (
max < 0xd800)
return;
3987 if (common->invalid_utf)
3990 add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(
SLJIT_FAST_CALL));
3991 if (backtracks !=
NULL)
3999 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4003 OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
4007#elif PCRE2_CODE_UNIT_WIDTH == 32
4008if (common->invalid_utf)
4018#define READ_CHAR_UPDATE_STR_PTR 0x1
4019#define READ_CHAR_UTF8_NEWLINE 0x2
4020#define READ_CHAR_NEWLINE (READ_CHAR_UPDATE_STR_PTR | READ_CHAR_UTF8_NEWLINE)
4021#define READ_CHAR_VALID_UTF 0x4
4030#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4033#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4043OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4046#ifdef SUPPORT_UNICODE
4047#if PCRE2_CODE_UNIT_WIDTH == 8
4050 if (
max < 128 && !(
options & READ_CHAR_UPDATE_STR_PTR))
return;
4052 if (common->invalid_utf && !(
options & READ_CHAR_VALID_UTF))
4056 if (
options & READ_CHAR_UTF8_NEWLINE)
4057 add_jump(compiler, &common->utfreadnewline_invalid, JUMP(
SLJIT_FAST_CALL));
4059 add_jump(compiler, &common->utfreadchar_invalid, JUMP(
SLJIT_FAST_CALL));
4061 if (backtracks !=
NULL)
4071 if (
options & READ_CHAR_UPDATE_STR_PTR)
4073 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4077 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4078 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4081 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4082 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
4083 if (!(
options & READ_CHAR_UPDATE_STR_PTR))
4087 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4089 if (
options & READ_CHAR_UPDATE_STR_PTR)
4090 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
4092 else if (
min >= 0x800 &&
max <= 0xffff)
4095 if (
options & READ_CHAR_UPDATE_STR_PTR)
4097 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4101 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4102 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4103 if (!(
options & READ_CHAR_UPDATE_STR_PTR))
4107 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4109 if (
options & READ_CHAR_UPDATE_STR_PTR)
4110 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
4112 else if (
max >= 0x800)
4119 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4123 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4124 if (!(
options & READ_CHAR_UPDATE_STR_PTR))
4131 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4132 if (
options & READ_CHAR_UPDATE_STR_PTR)
4133 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
4137#elif PCRE2_CODE_UNIT_WIDTH == 16
4140 if (
max < 0xd800 && !(
options & READ_CHAR_UPDATE_STR_PTR))
return;
4142 if (common->invalid_utf && !(
options & READ_CHAR_VALID_UTF))
4147 if (
options & READ_CHAR_UTF8_NEWLINE)
4148 add_jump(compiler, &common->utfreadnewline_invalid, JUMP(
SLJIT_FAST_CALL));
4150 add_jump(compiler, &common->utfreadchar_invalid, JUMP(
SLJIT_FAST_CALL));
4152 if (backtracks !=
NULL)
4163 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4167 OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
4177 if (
options & READ_CHAR_UPDATE_STR_PTR)
4180 if (
options & READ_CHAR_UPDATE_STR_PTR)
4181 SELECT(
SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR);
4188 if (
options & READ_CHAR_UPDATE_STR_PTR)
4195#elif PCRE2_CODE_UNIT_WIDTH == 32
4196if (common->invalid_utf)
4198 if (backtracks !=
NULL)
4217static void skip_valid_char(compiler_common *common)
4220#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
4224#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
4227 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
4229#if PCRE2_CODE_UNIT_WIDTH == 8
4232 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4233#elif PCRE2_CODE_UNIT_WIDTH == 16
4239 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4248#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4260 if (*bitset++ !=
value)
4263while (bitset <
end);
4267static void read_char7_type(compiler_common *common, jump_list **backtracks,
BOOL negated)
4277OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), 0);
4287 if (common->invalid_utf)
4290 add_jump(compiler, &common->utfreadchar_invalid, JUMP(
SLJIT_FAST_CALL));
4297 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4305static void read_char8_type(compiler_common *common, jump_list **backtracks,
BOOL negated)
4309#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
4312#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4319OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), 0);
4322#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
4331 if (common->invalid_utf)
4334 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4337 if (common->invalid_utf)
4341 OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
4343 if (common->invalid_utf)
4351 else if (common->invalid_utf)
4353 add_jump(compiler, &common->utfreadchar_invalid, JUMP(
SLJIT_FAST_CALL));
4370#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32
4371if (common->invalid_utf && negated)
4375#if PCRE2_CODE_UNIT_WIDTH != 8
4381#if PCRE2_CODE_UNIT_WIDTH != 8
4385#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
4386if (common->utf && negated)
4389 if (!common->invalid_utf)
4397 SELECT(
SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR);
4413 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4424static void move_back(compiler_common *common, jump_list **backtracks,
BOOL must_be_valid)
4431#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
4435#ifdef SUPPORT_UNICODE
4436#if PCRE2_CODE_UNIT_WIDTH == 8
4441 if (!must_be_valid && common->invalid_utf)
4443 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
4446 add_jump(compiler, &common->utfmoveback_invalid, JUMP(
SLJIT_FAST_CALL));
4447 if (backtracks !=
NULL)
4454 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
4460#elif PCRE2_CODE_UNIT_WIDTH == 16
4463 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
4466 if (!must_be_valid && common->invalid_utf)
4470 add_jump(compiler, &common->utfmoveback_invalid, JUMP(
SLJIT_FAST_CALL));
4471 if (backtracks !=
NULL)
4482 OP2(
SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4485#elif PCRE2_CODE_UNIT_WIDTH == 32
4486if (common->invalid_utf && !must_be_valid)
4488 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
4489 if (backtracks !=
NULL)
4499 OP2(
SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4511static void check_newlinechar(compiler_common *common,
int nltype, jump_list **backtracks,
BOOL jumpifmatch)
4544#ifdef SUPPORT_UNICODE
4546#if PCRE2_CODE_UNIT_WIDTH == 8
4547static void do_utfreadchar(compiler_common *common)
4555OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4558OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4569OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4572OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4583OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
4588OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4592static void do_utfreadtype8(compiler_common *common)
4605OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4612OP2(
SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
4624OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4628static void do_utfreadchar_invalid(compiler_common *common)
4654OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
4657OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
4670OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4673OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4678 exit_invalid[2] =
NULL;
4686three_byte_entry = LABEL();
4693 exit_invalid[3] =
NULL;
4704 exit_invalid[4] =
NULL;
4713OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4716OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4721 exit_invalid[5] =
NULL;
4731 exit_invalid[6] =
NULL;
4739JUMPHERE(buffer_end_close);
4744OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4747OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
4760OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4763OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4768 exit_invalid[10] =
NULL;
4779exit_invalid_label = LABEL();
4780for (i = 0; i < 11; i++)
4787static void do_utfreadnewline_invalid(compiler_common *common)
4811 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4827OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4833skip_start = LABEL();
4840OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4848three_byte_exit = LABEL();
4867OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4874OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4878static void do_utfmoveback_invalid(compiler_common *common)
4897OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
4910OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4924OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4928exit_ok_label = LABEL();
4933JUMPHERE(buffer_start_close);
4938OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4948OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4955exit_invalid_label = LABEL();
4962JUMPHERE(exit_invalid[4]);
4966exit_invalid_label = LABEL();
4967for (i = 0; i < 4; i++)
4974static void do_utfpeakcharback(compiler_common *common)
4982OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4986OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
4990OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));
4994OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
4997OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5000OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
5003OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
5006OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
5011static void do_utfpeakcharback_invalid(compiler_common *common)
5030OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5034two_byte_entry = LABEL();
5037OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5045OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
5048OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
5052three_byte_entry = LABEL();
5054OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
5061 exit_invalid[2] =
NULL;
5071 exit_invalid[3] =
NULL;
5082OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
5085OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-4));
5090OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5096 exit_invalid[5] =
NULL;
5109OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5117OP2(
SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
5120OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-3));
5131OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5135exit_invalid_label = LABEL();
5136for (i = 0; i < 8; i++)
5145#if PCRE2_CODE_UNIT_WIDTH == 16
5147static void do_utfreadchar_invalid(compiler_common *common)
5161OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5169OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5172JUMPHERE(exit_invalid[0]);
5173JUMPHERE(exit_invalid[1]);
5174JUMPHERE(exit_invalid[2]);
5179static void do_utfreadnewline_invalid(compiler_common *common)
5193OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5201OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
5205JUMPHERE(exit_invalid[0]);
5206JUMPHERE(exit_invalid[1]);
5211static void do_utfmoveback_invalid(compiler_common *common)
5222OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
5230JUMPHERE(exit_invalid[0]);
5231JUMPHERE(exit_invalid[1]);
5232JUMPHERE(exit_invalid[2]);
5239static void do_utfpeakcharback_invalid(compiler_common *common)
5253OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5258OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5263JUMPHERE(exit_invalid[0]);
5264JUMPHERE(exit_invalid[1]);
5265JUMPHERE(exit_invalid[2]);
5274#define UCD_BLOCK_MASK 127
5275#define UCD_BLOCK_SHIFT 7
5277static void do_getucd(compiler_common *common)
5282#if PCRE2_CODE_UNIT_WIDTH == 32
5286#if defined SLJIT_DEBUG && SLJIT_DEBUG
5297#if PCRE2_CODE_UNIT_WIDTH == 32
5311OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5317static void do_getucdtype(compiler_common *common)
5322#if PCRE2_CODE_UNIT_WIDTH == 32
5326#if defined SLJIT_DEBUG && SLJIT_DEBUG
5337#if PCRE2_CODE_UNIT_WIDTH == 32
5351OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5358OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
5374#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5378jump_list *newline =
NULL;
5379sljit_u32 overall_options = common->re->overall_options;
5386 newlinecheck =
TRUE;
5396 if (common->nltype ==
NLTYPE_FIXED && common->newline > 255)
5401 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
5402 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5414 read_char(common, common->nlmin, common->nlmax,
NULL, READ_CHAR_NEWLINE);
5415 check_newlinechar(common, common->nltype, &newline,
TRUE);
5416 CMPTO(
SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
5419 set_jumps(newline, LABEL());
5429 if (HAS_VIRTUAL_REGISTERS)
5439 if (HAS_VIRTUAL_REGISTERS)
5444#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
5447 if (HAS_VIRTUAL_REGISTERS)
5450 OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
5455 add_jump(compiler, &common->abort,
CMP(
SLJIT_LESS, TMP2, 0, STR_PTR, 0));
5464 newlinelabel = LABEL();
5467 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
5470#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
5473 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5480#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5481if (common->utf && !common->invalid_utf) readuchar =
TRUE;
5483if (newlinecheck) readuchar =
TRUE;
5486 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
5492#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5493#if PCRE2_CODE_UNIT_WIDTH == 8
5494if (common->invalid_utf)
5499 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
5506else if (common->utf)
5510 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5513#elif PCRE2_CODE_UNIT_WIDTH == 16
5514if (common->invalid_utf)
5519 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
5526else if (common->utf)
5534 SELECT(
SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR);
5541 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5568 chars->chars[0] =
chr;
5571 chars->last_count = 1;
5575for (i = 0; i <
count; i++)
5576 if (chars->chars[i] ==
chr)
5579if (
count >= MAX_DIFF_CHARS)
5586chars->count =
count + 1;
5589 chars->last_count++;
5592static int scan_prefix(compiler_common *common,
PCRE2_SPTR cc, fast_forward_char_data *chars,
int max_chars,
sljit_u32 *rec_count)
5596int len, repeat, len_save, consumed = 0;
5600#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
5602#elif defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16
5611 if (*rec_count == 0)
5653 cc = bracketend(cc);
5671 repeat =
GET2(cc, 1);
5686#ifdef SUPPORT_UNICODE
5687 if (common->utf && HAS_EXTRALEN(*cc))
len += GET_EXTRALEN(*cc);
5689 max_chars = scan_prefix(common, cc +
len, chars, max_chars, rec_count);
5708 alternative = cc +
GET(cc, 1);
5709 while (*alternative ==
OP_ALT)
5711 max_chars = scan_prefix(common, alternative + 1 +
LINK_SIZE, chars, max_chars, rec_count);
5714 alternative +=
GET(alternative, 1);
5723#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
5724 if (common->utf && !is_char7_bitset((
const sljit_u8 *)(cc + 1),
FALSE))
5731#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5732 if (common->utf)
return consumed;
5737#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
5739#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5740 if (common->utf)
return consumed;
5748#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
5757#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
5766#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
5783#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5784 if (common->utf)
return consumed;
5790#ifdef SUPPORT_UNICODE
5793#if PCRE2_CODE_UNIT_WIDTH != 32
5794 if (common->utf)
return consumed;
5802 repeat =
GET2(cc, 1);
5808#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
5809 if (common->utf)
return consumed;
5812 repeat =
GET2(cc, 1);
5827 if (--max_chars == 0)
5831 while (--repeat > 0);
5850 max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count);
5864 repeat =
GET2(cc, 1);
5872 if (bytes[31] & 0x80)
5874 else if (chars->count != 255)
5876 bytes_end = bytes + 32;
5888 if ((
byte & 0x1) != 0)
5889 add_prefix_char(
chr, chars,
TRUE);
5897 while (chars->count != 255 && bytes < bytes_end);
5898 bytes = bytes_end - 32;
5902 if (--max_chars == 0)
5906 while (--repeat > 0);
5935#ifdef SUPPORT_UNICODE
5936 if (common->utf && HAS_EXTRALEN(*cc))
len += GET_EXTRALEN(*cc);
5939 if (caseless && char_has_othercase(common, cc))
5941#ifdef SUPPORT_UNICODE
5952#ifdef SUPPORT_UNICODE
5953 if (common->ucp &&
chr > 127)
5980 add_prefix_char(*cc, chars,
len == 0);
5983 add_prefix_char(*oc, chars,
len == 0);
5985 if (--max_chars == 0)
6006#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
6009#if PCRE2_CODE_UNIT_WIDTH == 8
6012#elif PCRE2_CODE_UNIT_WIDTH == 16
6016#error "Unknown code width"
6023#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
6025static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forward_char_data *chars,
int max)
6029 sljit_s32 max_offset = max_fast_forward_char_pair_offset();
6032 for (i =
max - 1; i >= 1; i--)
6034 if (chars[i].last_count > 2)
6036 a1 = chars[i].chars[0];
6037 a2 = chars[i].chars[1];
6038 a_pri = chars[i].last_count;
6046 b_pri = chars[
j].last_count;
6049 b1 = chars[
j].chars[0];
6050 b2 = chars[
j].chars[1];
6052 if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)
6054 max_pri = a_pri + b_pri;
6067fast_forward_char_pair_simd(common, max_i, chars[max_i].chars[0], chars[max_i].chars[1], max_j, chars[max_j].chars[0], chars[max_j].chars[1]);
6080BOOL has_match_end = (common->match_end_ptr != 0);
6099#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
6101if (JIT_HAS_FAST_FORWARD_CHAR_SIMD)
6103 fast_forward_char_simd(common, char1, char2,
offset);
6119 add_jump(compiler, &common->failed_match, partial_quit);
6121OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
6128 mask = char1 ^ char2;
6129 if (is_powerof2(mask))
6142#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
6143if (common->utf &&
offset > 0)
6146 jumpto_if_not_utf_char_start(compiler, TMP1,
start);
6153 JUMPHERE(partial_quit);
6159static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common)
6164fast_forward_char_data chars[MAX_N_CHARS];
6169int range_right = -1, range_len;
6174for (i = 0; i < MAX_N_CHARS; i++)
6177 chars[i].last_count = 0;
6181max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count);
6187for (i = 0; i <
max; i++)
6191 switch (chars[i].
count)
6194 chars[i].count = 255;
6195 chars[i].last_count = 0;
6199 chars[i].last_count = (chars[i].last_count == 1) ? 7 : 5;
6201 chars[i].chars[1] = chars[i].chars[0];
6207 if (is_powerof2(chars[i].chars[0] ^ chars[i].chars[1]))
6208 chars[i].last_count = (chars[i].last_count == 2) ? 6 : 4;
6210 chars[i].last_count = (chars[i].last_count == 2) ? 3 : 2;
6214 chars[i].last_count = (chars[i].count == 255) ? 0 : 1;
6219#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
6220if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && check_fast_forward_char_pair_simd(common, chars,
max))
6228for (i = 0; i <=
max; i++)
6230 if (in_range && (i - from) > range_len && (chars[i - 1].
count < 255))
6232 range_len = i - from;
6233 range_right = i - 1;
6236 if (i <
max && chars[i].
count < 255)
6249if (range_right >= 0)
6251 update_table = (
sljit_u8 *)allocate_read_only_data(common, 256);
6252 if (update_table ==
NULL)
6254 memset(update_table, IN_UCHARS(range_len), 256);
6256 for (i = 0; i < range_len; i++)
6260 char_set = chars[range_right - i].chars;
6261 char_set_end = char_set + chars[range_right - i].count;
6264 if (update_table[(*char_set) & 0xff] > IN_UCHARS(i))
6265 update_table[(*char_set) & 0xff] = IN_UCHARS(i);
6268 while (char_set < char_set_end);
6274for (i = 0; i <
max; i++)
6276 if (range_right == i)
6281 if (chars[i].last_count >= 2)
6284 else if (chars[
offset].last_count < chars[i].last_count)
6295 fast_forward_first_char2(common, chars[
offset].chars[0], chars[
offset].chars[1],
offset);
6301if (common->match_end_ptr != 0)
6306 add_jump(compiler, &common->failed_match, JUMP(
SLJIT_LESS));
6313 add_jump(compiler, &common->failed_match, JUMP(
SLJIT_LESS));
6318if (!HAS_VIRTUAL_REGISTERS)
6322add_jump(compiler, &common->failed_match,
CMP(
SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
6324#if PCRE2_CODE_UNIT_WIDTH == 8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
6330if (!HAS_VIRTUAL_REGISTERS)
6335OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
6347 mask = chars[
offset].chars[0] ^ chars[
offset].chars[1];
6348 if (is_powerof2(mask))
6362#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
6363if (common->utf &&
offset != 0)
6367 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
6371 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
6373 jumpto_if_not_utf_char_start(compiler, TMP1,
start);
6383if (common->match_end_ptr != 0)
6390static SLJIT_INLINE void fast_forward_first_char(compiler_common *common)
6398 oc =
TABLE_GET(first_char, common->fcc, first_char);
6399#if defined SUPPORT_UNICODE
6400 if (first_char > 127 && (common->utf || common->ucp))
6405fast_forward_first_char2(common, first_char, oc, 0);
6408static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
6417jump_list *newline =
NULL;
6419if (common->match_end_ptr != 0)
6425if (common->nltype ==
NLTYPE_FIXED && common->newline > 255)
6427#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
6430 if (HAS_VIRTUAL_REGISTERS)
6446#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
6449 OP2(
SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
6451 fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff);
6458 if (HAS_VIRTUAL_REGISTERS)
6474#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
6477 OP2(
SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
6482 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
6483 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
6491 JUMPHERE(firstchar);
6493 if (common->match_end_ptr != 0)
6498if (HAS_VIRTUAL_REGISTERS)
6515common->ff_newline_shortcut = loop;
6517#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
6526 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
6532 fast_forward_char_simd(common, common->newline, common->newline, 0);
6545 read_char(common, common->nlmin, common->nlmax,
NULL, READ_CHAR_NEWLINE);
6549 check_newlinechar(common, common->nltype, &newline,
FALSE);
6550 set_jumps(newline, loop);
6562 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
6565#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
6568 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
6569 JUMPHERE(notfoundnl);
6577if (common->match_end_ptr != 0)
6581static BOOL optimize_class(compiler_common *common,
const sljit_u8 *bits,
BOOL nclass,
BOOL invert, jump_list **backtracks);
6583static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common)
6586const sljit_u8 *start_bits = common->re->start_bitmap;
6589#if PCRE2_CODE_UNIT_WIDTH != 8
6592jump_list *matches =
NULL;
6594if (common->match_end_ptr != 0)
6597 OP1(
SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
6607 add_jump(compiler, &common->failed_match, partial_quit);
6609OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
6612if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0,
FALSE, &matches))
6614#if PCRE2_CODE_UNIT_WIDTH != 8
6615 if ((start_bits[31] & 0x80) != 0)
6619#elif defined SUPPORT_UNICODE
6620 if (common->utf && is_char7_bitset(start_bits,
FALSE))
6626 if (!HAS_VIRTUAL_REGISTERS)
6639 set_jumps(matches,
start);
6641#if PCRE2_CODE_UNIT_WIDTH != 8
6649 JUMPHERE(partial_quit);
6651if (common->match_end_ptr != 0)
6652 OP1(
SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
6663jump_list *not_found =
NULL;
6680 oc =
TABLE_GET(req_char, common->fcc, req_char);
6681#if defined SUPPORT_UNICODE
6682 if (req_char > 127 && (common->utf || common->ucp))
6687#ifdef JIT_HAS_FAST_REQUESTED_CHAR_SIMD
6688if (JIT_HAS_FAST_REQUESTED_CHAR_SIMD)
6690 not_found = fast_requested_char_simd(common, req_char, oc);
6698 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(TMP1), 0);
6704 bit = req_char ^ oc;
6705 if (is_powerof2(bit))
6726JUMPHERE(already_found);
6731static void do_revertframes(compiler_common *common)
6738GET_LOCAL_BASE(TMP1, 0, 0);
6746OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
6747if (HAS_VIRTUAL_REGISTERS)
6759 GET_LOCAL_BASE(TMP1, 0, 0);
6772OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
6773if (HAS_VIRTUAL_REGISTERS)
6787#ifdef SUPPORT_UNICODE
6788#define UCPCAT(bit) (1 << (bit))
6789#define UCPCAT2(bit1, bit2) (UCPCAT(bit1) | UCPCAT(bit2))
6790#define UCPCAT3(bit1, bit2, bit3) (UCPCAT(bit1) | UCPCAT(bit2) | UCPCAT(bit3))
6791#define UCPCAT_RANGE(start, end) (((1 << ((end) + 1)) - 1) - ((1 << (start)) - 1))
6792#define UCPCAT_L UCPCAT_RANGE(ucp_Ll, ucp_Lu)
6793#define UCPCAT_N UCPCAT_RANGE(ucp_Nd, ucp_No)
6794#define UCPCAT_ALL ((1 << (ucp_Zs + 1)) - 1)
6797static void check_wordboundary(compiler_common *common,
BOOL ucp)
6801jump_list *skipread_list =
NULL;
6802#ifdef SUPPORT_UNICODE
6804jump_list *invalid_utf1 =
NULL;
6806jump_list *invalid_utf2 =
NULL;
6807#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE
6821#ifdef SUPPORT_UNICODE
6822if (common->invalid_utf)
6824 peek_char_back(common, READ_CHAR_MAX, &invalid_utf1);
6828 OP1(
SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
6831 check_start_used_ptr(common);
6832 OP1(
SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
6840 peek_char_back(common, READ_CHAR_MAX,
NULL);
6844 check_start_used_ptr(common);
6845 read_char(common, 0, READ_CHAR_MAX,
NULL, READ_CHAR_UPDATE_STR_PTR);
6850#ifdef SUPPORT_UNICODE
6861#if PCRE2_CODE_UNIT_WIDTH != 8
6863#elif defined SUPPORT_UNICODE
6872#if PCRE2_CODE_UNIT_WIDTH != 8
6874#elif defined SUPPORT_UNICODE
6882check_str_end(common, &skipread_list);
6886#ifdef SUPPORT_UNICODE
6900#if PCRE2_CODE_UNIT_WIDTH != 8
6904#elif defined SUPPORT_UNICODE
6913#if PCRE2_CODE_UNIT_WIDTH != 8
6915#elif defined SUPPORT_UNICODE
6920set_jumps(skipread_list, LABEL());
6926#ifdef SUPPORT_UNICODE
6927if (common->invalid_utf)
6929 set_jumps(invalid_utf1, LABEL());
6938 set_jumps(invalid_utf2, LABEL());
6946static BOOL optimize_class_ranges(compiler_common *common,
const sljit_u8 *bits,
BOOL nclass,
BOOL invert, jump_list **backtracks)
6950int ranges[MAX_CLASS_RANGE_SIZE];
6952int i, byte, length = 0;
6958for (i = 0; i < 256; )
6961 if ((i & 0x7) == 0 && bits[
byte] == all)
6965 cbit = (bits[byte] >> (i & 0x7)) & 0x1;
6968 if (length >= MAX_CLASS_RANGE_SIZE)
6979if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
6981 if (length >= MAX_CLASS_RANGE_SIZE)
6983 ranges[length] = 256;
6987if (length < 0 || length > 4)
6991if (invert) bit ^= 0x1;
6994if (length == 0 && bit == 0)
6995 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
7008 if (ranges[0] + 1 != ranges[1])
7021 if (ranges[0] + 1 != ranges[1])
7032 if (ranges[1] + 1 != ranges[2])
7042 if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
7043 && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
7044 && (ranges[1] & (ranges[2] - ranges[0])) == 0
7045 && is_powerof2(ranges[2] - ranges[0]))
7047 SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
7049 if (ranges[2] + 1 != ranges[3])
7062 if (ranges[0] + 1 != ranges[1])
7071 if (ranges[2] + 1 != ranges[3])
7083 if (ranges[1] + 1 != ranges[2])
7098static BOOL optimize_class_chars(compiler_common *common,
const sljit_u8 *bits,
BOOL nclass,
BOOL invert, jump_list **backtracks)
7102uint16_t char_list[MAX_CLASS_CHARS_SIZE];
7112for (i = 0; i < 32; i++)
7128 if ((c & 0x20) != 0)
7130 for (k = 0; k <
len; k++)
7131 if (char_list[k] == c - 0x20)
7133 char_list[k] |= 0x120;
7140 if (
len >= MAX_CLASS_CHARS_SIZE)
7143 char_list[
len++] = (uint16_t) c;
7157if (char_list[0] == 0)
7168 if ((char_list[i] & 0x100) != 0)
7182 for (i = 0; i <
len; i++)
7183 if ((char_list[i] & 0x100) != 0)
7199static BOOL optimize_class(compiler_common *common,
const sljit_u8 *bits,
BOOL nclass,
BOOL invert, jump_list **backtracks)
7202if (optimize_class_ranges(common, bits, nclass, invert, backtracks))
7204return optimize_class_chars(common, bits, nclass, invert, backtracks);
7207static void check_anynewline(compiler_common *common)
7218#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
7219#if PCRE2_CODE_UNIT_WIDTH == 8
7226#if PCRE2_CODE_UNIT_WIDTH == 8
7234static void check_hspace(compiler_common *common)
7246#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
7247#if PCRE2_CODE_UNIT_WIDTH == 8
7264#if PCRE2_CODE_UNIT_WIDTH == 8
7273static void check_vspace(compiler_common *common)
7284#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
7285#if PCRE2_CODE_UNIT_WIDTH == 8
7292#if PCRE2_CODE_UNIT_WIDTH == 8
7301static void do_casefulcmp(compiler_common *common)
7309if (HAS_VIRTUAL_REGISTERS)
7311 char1_reg = STR_END;
7312 char2_reg = STACK_TOP;
7317 char2_reg = RETURN_ADDR;
7321OP2(
SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
7323if (char1_reg == STR_END)
7326 OP1(
SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
7360 OP1(MOV_UCHAR, char1_reg, 0,
SLJIT_MEM1(TMP1), 0);
7361 OP1(MOV_UCHAR, char2_reg, 0,
SLJIT_MEM1(STR_PTR), 0);
7372if (char1_reg == STR_END)
7375 OP1(
SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
7381static void do_caselesscmp(compiler_common *common)
7386int char1_reg = STR_END;
7391if (HAS_VIRTUAL_REGISTERS)
7393 char2_reg = STACK_TOP;
7394 lcc_table = STACK_LIMIT;
7398 char2_reg = RETURN_ADDR;
7408OP2(
SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
7412if (char2_reg == STACK_TOP)
7415 OP1(
SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
7426else if (opt_type == 2)
7438 OP1(MOV_UCHAR, char1_reg, 0,
SLJIT_MEM1(TMP1), 0);
7439 OP1(MOV_UCHAR, char2_reg, 0,
SLJIT_MEM1(STR_PTR), 0);
7443#if PCRE2_CODE_UNIT_WIDTH != 8
7447#if PCRE2_CODE_UNIT_WIDTH != 8
7452#if PCRE2_CODE_UNIT_WIDTH != 8
7469if (char2_reg == STACK_TOP)
7472 OP1(
SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
7480 compare_context *
context, jump_list **backtracks)
7483unsigned int othercasebit = 0;
7485#ifdef SUPPORT_UNICODE
7489if (caseless && char_has_othercase(common, cc))
7491 othercasebit = char_get_othercase_bit(common, cc);
7494#if PCRE2_CODE_UNIT_WIDTH == 8
7495 othercasechar = cc + (othercasebit >> 8);
7496 othercasebit &= 0xff;
7497#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
7502 othercasechar = cc + (othercasebit >> 9);
7503 if ((othercasebit & 0x100) != 0)
7504 othercasebit = (othercasebit & 0xff) << 8;
7506 othercasebit &= 0xff;
7512#if PCRE2_CODE_UNIT_WIDTH == 8
7513#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
7516 else if (
context->length >= 2)
7521#elif PCRE2_CODE_UNIT_WIDTH == 16
7522#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
7528#elif PCRE2_CODE_UNIT_WIDTH == 32
7534#ifdef SUPPORT_UNICODE
7536if (common->utf && HAS_EXTRALEN(*cc))
7537 utflength += GET_EXTRALEN(*cc);
7543 context->length -= IN_UCHARS(1);
7544#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
7547 if (othercasebit != 0 && othercasechar == cc)
7559#if PCRE2_CODE_UNIT_WIDTH == 8
7567 else if (
context->length >= 2)
7569#if PCRE2_CODE_UNIT_WIDTH == 8
7570 else if (
context->length >= 1)
7589#if PCRE2_CODE_UNIT_WIDTH == 8
7612 if (othercasebit != 0 && othercasechar == cc)
7623#ifdef SUPPORT_UNICODE
7626while (utflength > 0);
7632#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
7634#define SET_CHAR_OFFSET(value) \
7635 if ((value) != charoffset) \
7637 if ((value) < charoffset) \
7638 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
7640 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
7642 charoffset = (value);
7646#ifdef SUPPORT_UNICODE
7647#define XCLASS_SAVE_CHAR 0x001
7648#define XCLASS_CHAR_SAVED 0x002
7649#define XCLASS_HAS_TYPE 0x004
7650#define XCLASS_HAS_SCRIPT 0x008
7651#define XCLASS_HAS_SCRIPT_EXTENSION 0x010
7652#define XCLASS_HAS_BOOL 0x020
7653#define XCLASS_HAS_BIDICL 0x040
7654#define XCLASS_NEEDS_UCD (XCLASS_HAS_TYPE | XCLASS_HAS_SCRIPT | XCLASS_HAS_SCRIPT_EXTENSION | XCLASS_HAS_BOOL | XCLASS_HAS_BIDICL)
7655#define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080
7656#define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100
7657#define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0 0x200
7660static void compile_xclass_matchingpath(compiler_common *common,
PCRE2_SPTR cc, jump_list **backtracks)
7663jump_list *found =
NULL;
7664jump_list **list = (cc[0] &
XCL_NOT) == 0 ? &found : backtracks;
7668int compares, invertcmp, numberofcmps;
7669#if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16)
7670BOOL utf = common->utf;
7673#ifdef SUPPORT_UNICODE
7702#ifdef SUPPORT_UNICODE
7703 unicode_status |= XCLASS_SAVE_CHAR;
7713#ifdef SUPPORT_UNICODE
7714 unicode_status |= XCLASS_SAVE_CHAR;
7717#ifdef SUPPORT_UNICODE
7725 other_cases =
PRIV(ucd_caseless_sets) + cc[1];
7728 if (*other_cases >
max)
max = *other_cases;
7729 if (*other_cases <
min)
min = *other_cases;
7735 max = READ_CHAR_MAX;
7756 items = UCPCAT_RANGE(
PRIV(ucp_typerange)[(
int)cc[1] * 2],
PRIV(ucp_typerange)[(
int)cc[1] * 2 + 1]);
7760 items = UCPCAT(cc[1]);
7768 items = UCPCAT_L | UCPCAT_N;
7772 unicode_status |= XCLASS_HAS_SCRIPT_EXTENSION;
7775 unicode_status |= XCLASS_SCRIPT_EXTENSION_NOTPROP;
7782 unicode_status |= XCLASS_HAS_SCRIPT;
7790 unicode_status |= XCLASS_SAVE_CHAR | XCLASS_HAS_TYPE;
7796 unicode_status |= XCLASS_SAVE_CHAR;
7800 unicode_status |= XCLASS_HAS_BOOL;
7804 unicode_status |= XCLASS_HAS_BIDICL;
7815 items ^= UCPCAT_ALL;
7816 category_list |= items;
7817 unicode_status |= XCLASS_HAS_TYPE;
7826#ifdef SUPPORT_UNICODE
7827if (category_list == UCPCAT_ALL)
7830 compile_char1_matchingpath(common,
OP_ALLANY, cc, backtracks,
FALSE);
7831 if (list == backtracks)
7832 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
7836if (compares == 0 && category_list == 0)
7839 compile_char1_matchingpath(common,
OP_ALLANY, cc, backtracks,
FALSE);
7840 if (list != backtracks)
7841 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
7851 read_char(common,
min,
max, backtracks, READ_CHAR_UPDATE_STR_PTR);
7854#ifdef SUPPORT_UNICODE
7855 read_char(common,
min,
max, (unicode_status & XCLASS_NEEDS_UCD) ? backtracks :
NULL, 0);
7866 if (!optimize_class(common, (
const sljit_u8 *)cc, (((
const sljit_u8 *)cc)[31] & 0x80) != 0,
TRUE, &found))
7876 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
7887else if ((cc[-1] &
XCL_MAP) != 0)
7889 OP1(
SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
7890#ifdef SUPPORT_UNICODE
7891 unicode_status |= XCLASS_CHAR_SAVED;
7895#if PCRE2_CODE_UNIT_WIDTH == 8
7908#if PCRE2_CODE_UNIT_WIDTH == 8
7914 OP1(
SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
7918#ifdef SUPPORT_UNICODE
7919if (unicode_status & XCLASS_NEEDS_UCD)
7921 if ((unicode_status & (XCLASS_SAVE_CHAR | XCLASS_CHAR_SAVED)) == XCLASS_SAVE_CHAR)
7922 OP1(
SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
7924#if PCRE2_CODE_UNIT_WIDTH == 32
7938 OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
7943 OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
7947 if (category_list != 0)
7950 if (unicode_status & XCLASS_HAS_BIDICL)
7975 invertcmp = (compares == 0 && list != backtracks);
7979 add_jump(compiler, compares > 0 ? list : backtracks, jump);
7988 if (unicode_status & XCLASS_HAS_BOOL)
8014 invertcmp = (compares == 0 && list != backtracks);
8019 add_jump(compiler, compares > 0 ? list : backtracks, JUMP(
SLJIT_NOT_ZERO ^ invertcmp));
8028 if (unicode_status & XCLASS_HAS_SCRIPT)
8058 invertcmp = (compares == 0 && list != backtracks);
8062 add_jump(compiler, compares > 0 ? list : backtracks,
CMP(
SLJIT_EQUAL ^ invertcmp, TMP1, 0,
SLJIT_IMM, (
int)cc[1]));
8071 if (unicode_status & XCLASS_HAS_SCRIPT_EXTENSION)
8077 if (unicode_status & XCLASS_SCRIPT_EXTENSION_NOTPROP)
8079 if (unicode_status & XCLASS_HAS_TYPE)
8081 if (unicode_status & XCLASS_SAVE_CHAR)
8084 unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0;
8088 OP1(
SLJIT_MOV, RETURN_ADDR, 0, TMP2, 0);
8089 unicode_status |= XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR;
8115 invertcmp = (compares == 0 && list != backtracks);
8123 add_jump(compiler, backtracks, jump);
8130 add_jump(compiler, compares > 0 ? list : backtracks, JUMP(
SLJIT_NOT_ZERO ^ invertcmp));
8139 if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0)
8141 else if (unicode_status & XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR)
8142 OP1(
SLJIT_MOV, TMP2, 0, RETURN_ADDR, 0);
8146 if (unicode_status & XCLASS_SAVE_CHAR)
8147 OP1(
SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
8149 if (unicode_status & XCLASS_HAS_TYPE)
8151 if (unicode_status & XCLASS_SAVE_CHAR)
8152 typereg = RETURN_ADDR;
8157 if (category_list > 0)
8160 invertcmp = (compares == 0 && list != backtracks);
8162 add_jump(compiler, compares > 0 ? list : backtracks, JUMP(
SLJIT_NOT_ZERO ^ invertcmp));
8175 invertcmp = (compares == 0 && list != backtracks);
8189 else if (numberofcmps > 0)
8215 else if (numberofcmps > 0)
8228#ifdef SUPPORT_UNICODE
8269 other_cases =
PRIV(ucd_caseless_sets) + cc[1];
8274 SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
8277 if (is_powerof2(other_cases[1] ^ other_cases[0]))
8279 if (charoffset == 0)
8290 else if (is_powerof2(other_cases[2] ^ other_cases[1]))
8292 if (charoffset == 0)
8329 SET_CHAR_OFFSET(0xa0);
8347 SET_CHAR_OFFSET(0x2066);
8373 SET_CHAR_OFFSET(0x2066);
8410 SET_CHAR_OFFSET(0xff10);
8416 SET_CHAR_OFFSET(0xff21);
8420 SET_CHAR_OFFSET(0xff41);
8424 SET_CHAR_OFFSET(0xff10);
8440 add_jump(compiler, compares > 0 ? list : backtracks, jump);
8445 set_jumps(found, LABEL());
8448#undef SET_TYPE_OFFSET
8449#undef SET_CHAR_OFFSET
8461 if (HAS_VIRTUAL_REGISTERS)
8472 if (HAS_VIRTUAL_REGISTERS)
8487#ifdef SUPPORT_UNICODE
8488 if (common->invalid_utf)
8501 if (common->nltype ==
NLTYPE_FIXED && common->newline > 255)
8504 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
8515 check_partial(common,
TRUE);
8516 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
8519 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
8526 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
8532 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
8539 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
8541 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
8547 add_jump(compiler, backtracks,
CMP(
SLJIT_LESS, TMP2, 0, STR_END, 0));
8553 read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);
8557 add_jump(compiler, backtracks, JUMP(
SLJIT_ZERO));
8565 check_partial(common,
TRUE);
8569 add_jump(compiler, backtracks,
CMP(
SLJIT_LESS, STR_PTR, 0, STR_END, 0));
8571 check_partial(common,
TRUE);
8575 if (HAS_VIRTUAL_REGISTERS)
8584 if (!common->endonly)
8585 compile_simple_assertion_matchingpath(common,
OP_EODN, cc, backtracks);
8588 add_jump(compiler, backtracks,
CMP(
SLJIT_LESS, STR_PTR, 0, STR_END, 0));
8589 check_partial(common,
FALSE);
8595 if (HAS_VIRTUAL_REGISTERS)
8603 check_partial(common,
FALSE);
8607 if (common->nltype ==
NLTYPE_FIXED && common->newline > 255)
8610 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
8618 check_partial(common,
TRUE);
8619 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
8623 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
8629 peek_char(common, common->nlmax, TMP3, 0,
NULL);
8630 check_newlinechar(common, common->nltype, backtracks,
FALSE);
8636 if (HAS_VIRTUAL_REGISTERS)
8655 if (HAS_VIRTUAL_REGISTERS)
8672 if (!common->alt_circumflex)
8675 if (common->nltype ==
NLTYPE_FIXED && common->newline > 255)
8678 add_jump(compiler, backtracks,
CMP(
SLJIT_LESS, TMP1, 0, TMP2, 0));
8679 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
8680 OP1(MOV_UCHAR, TMP2, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
8686 peek_char_back(common, common->nlmax, backtracks);
8687 check_newlinechar(common, common->nltype, backtracks,
FALSE);
8696#ifdef SUPPORT_UNICODE
8698#if PCRE2_CODE_UNIT_WIDTH != 32
8708int lgb, rgb, ricount;
8729 if ((
PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
8747 while (bptr > start_subject)
8759 if ((ricount & 1) != 0)
break;
8776while (cc < end_subject);
8791int lgb, rgb, ricount;
8801 GETCHARINC_INVALID(c, cc, end_subject,
break);
8812 if ((
PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
8830 while (bptr > start_subject)
8832 GETCHARBACK_INVALID(c, bptr, start_subject,
break);
8840 if ((ricount & 1) != 0)
8858while (cc < end_subject);
8871int lgb, rgb, ricount;
8880#if PCRE2_CODE_UNIT_WIDTH == 32
8886while (cc < end_subject)
8889#if PCRE2_CODE_UNIT_WIDTH == 32
8895 if ((
PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
8913 while (bptr > start_subject)
8917#if PCRE2_CODE_UNIT_WIDTH == 32
8927 if ((ricount & 1) != 0)
8954unsigned int c, oc, bit;
8958#ifdef SUPPORT_UNICODE
8968 detect_partial_match(common, backtracks);
8969#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
8983 detect_partial_match(common, backtracks);
8984#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
8997 detect_partial_match(common, backtracks);
8998#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
9010 detect_partial_match(common, backtracks);
9011 read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR);
9012 if (common->nltype ==
NLTYPE_FIXED && common->newline > 255)
9019 check_str_end(common, &end_list);
9021 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
9023 set_jumps(end_list, LABEL());
9027 check_newlinechar(common, common->nltype, backtracks,
TRUE);
9032 detect_partial_match(common, backtracks);
9033#ifdef SUPPORT_UNICODE
9034 if (common->utf && common->invalid_utf)
9036 read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR);
9041 skip_valid_char(common);
9046 detect_partial_match(common, backtracks);
9050#ifdef SUPPORT_UNICODE
9055 propdata[2] = cc[0];
9056 propdata[3] = cc[1];
9059 detect_partial_match(common, backtracks);
9060 compile_xclass_matchingpath(common, propdata, backtracks);
9066 detect_partial_match(common, backtracks);
9067 read_char(common, common->bsr_nlmin, common->bsr_nlmax,
NULL, 0);
9074 check_str_end(common, &end_list);
9075 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), 0);
9080 check_newlinechar(common, common->bsr_nltype, backtracks,
FALSE);
9081 set_jumps(end_list, LABEL());
9089 detect_partial_match(common, backtracks);
9092 read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR);
9094 read_char(common, 0x9, 0x3000,
NULL, 0);
9104 detect_partial_match(common, backtracks);
9107 read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR);
9109 read_char(common, 0xa, 0x2029,
NULL, 0);
9116#ifdef SUPPORT_UNICODE
9119 detect_partial_match(common, backtracks);
9124#if PCRE2_CODE_UNIT_WIDTH != 32
9127 if (common->invalid_utf)
9132 if (common->invalid_utf)
9142 check_partial(common,
TRUE);
9151#ifdef SUPPORT_UNICODE
9152 if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
9156 detect_partial_match(common, backtracks);
9158 if (
type ==
OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
9162 add_jump(compiler, backtracks,
CMP(
SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
9164 context.length = IN_UCHARS(length);
9166#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
9172#ifdef SUPPORT_UNICODE
9186 oc = char_othercase(common, c);
9187 read_char(common, c < oc ? c : oc, c > oc ? c : oc,
NULL, 0);
9208 detect_partial_match(common, backtracks);
9211#ifdef SUPPORT_UNICODE
9214#if PCRE2_CODE_UNIT_WIDTH == 8
9216 if (c < 128 && !common->invalid_utf)
9219 if (
type ==
OP_NOT || !char_has_othercase(common, cc))
9231 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
9245 if (
type ==
OP_NOT || !char_has_othercase(common, cc))
9247 read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR);
9252 oc = char_othercase(common, c);
9253 read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR);
9255 if (is_powerof2(bit))
9271 detect_partial_match(common, backtracks);
9273#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
9276 read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR);
9278 read_char(common, 0, bit,
NULL, 0);
9281 read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR);
9283 read_char(common, 0, 255,
NULL, 0);
9289#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
9296 add_jump(compiler, backtracks, jump[0]);
9300#elif PCRE2_CODE_UNIT_WIDTH != 8
9304 add_jump(compiler, backtracks, jump[0]);
9314 add_jump(compiler, backtracks, JUMP(
SLJIT_ZERO));
9316#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
9317 if (jump[0] !=
NULL)
9322#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
9325 detect_partial_match(common, backtracks);
9326 compile_xclass_matchingpath(common, cc +
LINK_SIZE, backtracks);
9327 return cc +
GET(cc, 0) - 1;
9352#ifdef SUPPORT_UNICODE
9353 if (common->utf && HAS_EXTRALEN(cc[1]))
9354 size += GET_EXTRALEN(cc[1]);
9360#ifdef SUPPORT_UNICODE
9363 if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
9365 else if (HAS_EXTRALEN(cc[1]))
9366 size += GET_EXTRALEN(cc[1]);
9370 if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
9386 add_jump(compiler, backtracks,
CMP(
SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
9389#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
9392 do cc = byte_sequence_compare(common, *cc ==
OP_CHARI, cc + 1, &
context, backtracks);
while (
context.length > 0);
9397return compile_char1_matchingpath(common, *cc, cc + 1, backtracks,
TRUE);
9401static void compile_matchingpath(compiler_common *,
PCRE2_SPTR,
PCRE2_SPTR, backtrack_common *);
9402static void compile_backtrackingpath(compiler_common *,
struct backtrack_common *);
9404#define PUSH_BACKTRACK(size, ccstart, error) \
9407 backtrack = sljit_alloc_memory(compiler, (size)); \
9408 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
9410 memset(backtrack, 0, size); \
9411 backtrack->prev = parent->top; \
9412 backtrack->cc = (ccstart); \
9413 parent->top = backtrack; \
9417#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
9420 backtrack = sljit_alloc_memory(compiler, (size)); \
9421 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
9423 memset(backtrack, 0, size); \
9424 backtrack->prev = parent->top; \
9425 backtrack->cc = (ccstart); \
9426 parent->top = backtrack; \
9430#define BACKTRACK_AS(type) ((type *)backtrack)
9432static void compile_dnref_search(compiler_common *common,
PCRE2_SPTR cc, jump_list **backtracks)
9437PCRE2_SPTR slot = common->name_table +
GET2(cc, 1) * common->name_entry_size;
9439jump_list *found =
NULL;
9449 GET_LOCAL_BASE(TMP2, 0, OVECTOR(
offset));
9451 slot += common->name_entry_size;
9455GET_LOCAL_BASE(TMP2, 0, OVECTOR(
offset));
9456if (backtracks !=
NULL && !common->unset_backref)
9459set_jumps(found, LABEL());
9462static void compile_ref_matchingpath(compiler_common *common,
PCRE2_SPTR cc, jump_list **backtracks,
BOOL withchecks,
BOOL emptyfail)
9470#if defined SUPPORT_UNICODE
9473jump_list *no_match =
NULL;
9474int source_reg = COUNT_MATCH;
9475int source_end_reg = ARGUMENTS;
9476int char1_reg = STACK_LIMIT;
9484 if (withchecks && !common->unset_backref)
9490#if defined SUPPORT_UNICODE
9491if (common->utf && *cc ==
OP_REFI)
9500 if (withchecks && emptyfail)
9501 add_jump(compiler, backtracks,
CMP(
SLJIT_EQUAL, TMP1, 0, TMP2, 0));
9508 OP1(
SLJIT_MOV, source_end_reg, 0, TMP2, 0);
9516 OP1(
SLJIT_MOV, STR_PTR, 0, source_reg, 0);
9518 read_char(common, 0, READ_CHAR_MAX,
NULL, READ_CHAR_UPDATE_STR_PTR | READ_CHAR_VALID_UTF);
9520 OP1(
SLJIT_MOV, source_reg, 0, STR_PTR, 0);
9525 read_char(common, 0, READ_CHAR_MAX, &no_match, READ_CHAR_UPDATE_STR_PTR);
9535 OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
9541 OP2(
SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);
9548 caseless_loop = LABEL();
9555 set_jumps(no_match, LABEL());
9562 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
9571 check_partial(common,
FALSE);
9572 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
9592 OP2(
SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
9595 add_jump(compiler, backtracks, partial);
9597 add_jump(compiler, *cc ==
OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(
SLJIT_FAST_CALL));
9605 OP2(
SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
9606 OP2(
SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
9609 add_jump(compiler, *cc ==
OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(
SLJIT_FAST_CALL));
9612 check_partial(common,
FALSE);
9613 add_jump(compiler, backtracks, JUMP(
SLJIT_JUMP));
9614 JUMPHERE(nopartial);
9621 add_jump(compiler, backtracks, jump);
9631backtrack_common *backtrack;
9641PUSH_BACKTRACK(
sizeof(ref_iterator_backtrack), cc,
NULL);
9650minimize = (
type & 0x1) != 0;
9686 allocate_stack(common, 2);
9699 compile_dnref_search(common, ccbegin,
NULL);
9709 allocate_stack(common, 1);
9716 if (!common->unset_backref)
9722 compile_dnref_search(common, ccbegin, &backtrack->own_backtracks);
9735 compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks,
FALSE,
FALSE);
9747 allocate_stack(common, 1);
9757 allocate_stack(common, 1);
9762 JUMPHERE(zerolength);
9763 BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
9765 count_match(common);
9769allocate_stack(common, ref ? 2 : 3);
9784 compile_dnref_search(common, ccbegin,
NULL);
9797 if (!common->unset_backref)
9803 compile_dnref_search(common, ccbegin, &backtrack->own_backtracks);
9810BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL();
9816compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks,
TRUE,
TRUE);
9831JUMPHERE(zerolength);
9840backtrack_common *backtrack;
9841recurse_entry *entry = common->entries;
9845BOOL needs_control_head;
9847PUSH_BACKTRACK(
sizeof(recurse_backtrack), cc,
NULL);
9850if (get_framesize(common, common->start +
start,
NULL,
TRUE, &needs_control_head) == no_stack)
9852 start_cc = common->start +
start;
9853 compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 +
LINK_SIZE), backtrack);
9854 BACKTRACK_AS(recurse_backtrack)->inlined_pattern =
TRUE;
9858while (entry !=
NULL)
9860 if (entry->start ==
start)
9863 entry = entry->next;
9872 entry->entry_label =
NULL;
9873 entry->backtrack_label =
NULL;
9874 entry->entry_calls =
NULL;
9875 entry->backtrack_calls =
NULL;
9876 entry->start =
start;
9881 common->entries = entry;
9884BACKTRACK_AS(recurse_backtrack)->entry = entry;
9886if (entry->entry_label ==
NULL)
9892BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();
9902if (arguments->callout ==
NULL)
9907begin = arguments->begin;
9909oveccount = callout_block->capture_top;
9913callout_block->version = 2;
9914callout_block->callout_flags = 0;
9917callout_block->subject_length = arguments->end - arguments->begin;
9918callout_block->start_match = jit_ovector[0] -
begin;
9919callout_block->current_position = (
PCRE2_SPTR)callout_block->offset_vector -
begin;
9920callout_block->subject =
begin;
9923callout_block->capture_top = 1;
9924callout_block->offset_vector = ovector;
9933while (--oveccount != 0)
9941 callout_block->capture_top = capture_top;
9947return (arguments->callout)(callout_block, arguments->callout_data);
9950#define CALLOUT_ARG_OFFSET(arg) \
9951 SLJIT_OFFSETOF(pcre2_callout_block, arg)
9956backtrack_common *backtrack;
9958unsigned int callout_length = (*cc ==
OP_CALLOUT)
9963sljit_uw callout_arg_size = (common->re->top_bracket + 1) * 2 * SSIZE_OF(sw);
9965PUSH_BACKTRACK(
sizeof(backtrack_common), cc,
NULL);
9969allocate_stack(common, callout_arg_size);
9982if (common->mark_ptr != 0)
9997 value2 = (callout_length - (1 + 4*
LINK_SIZE + 2));
10002OP1(mov_opcode,
SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length),
SLJIT_IMM, value2);
10003OP1(mov_opcode,
SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset),
SLJIT_IMM, value3);
10012GET_LOCAL_BASE(
SLJIT_R2, 0, OVECTOR_START);
10015free_stack(common, callout_arg_size);
10020if (common->abort_label ==
NULL)
10024return cc + callout_length;
10027#undef CALLOUT_ARG_SIZE
10028#undef CALLOUT_ARG_OFFSET
10030static PCRE2_SPTR compile_reverse_matchingpath(compiler_common *common,
PCRE2_SPTR cc, backtrack_common *parent)
10033backtrack_common *backtrack =
NULL;
10034jump_list **reverse_failed;
10035unsigned int lmin, lmax;
10036#ifdef SUPPORT_UNICODE
10045 reverse_failed = &parent->own_backtracks;
10046 lmin =
GET2(cc, 1);
10055 PUSH_BACKTRACK(
sizeof(vreverse_backtrack), cc,
NULL);
10057 reverse_failed = &backtrack->own_backtracks;
10058 lmin =
GET2(cc, 1);
10065if (HAS_VIRTUAL_REGISTERS)
10073#ifdef SUPPORT_UNICODE
10081 move_back(common, reverse_failed,
FALSE);
10093 move_back(common, reverse_failed,
FALSE);
10107 add_jump(compiler, reverse_failed,
CMP(
SLJIT_LESS, STR_PTR, 0, TMP2, 0));
10116 SELECT(
SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR);
10122check_start_used_ptr(common);
10125 BACKTRACK_AS(vreverse_backtrack)->matchingpath = LABEL();
10162static PCRE2_SPTR compile_assert_matchingpath(compiler_common *common,
PCRE2_SPTR cc, assert_backtrack *backtrack,
BOOL conditional)
10168BOOL needs_control_head;
10169BOOL end_block_size = 0;
10171int private_data_ptr;
10172backtrack_common altbacktrack;
10176jump_list *tmp =
NULL;
10177jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.own_backtracks;
10180BOOL save_local_quit_available = common->local_quit_available;
10181BOOL save_in_positive_assertion = common->in_positive_assertion;
10182then_trap_backtrack *save_then_trap = common->then_trap;
10183struct sljit_label *save_quit_label = common->quit_label;
10184struct sljit_label *save_accept_label = common->accept_label;
10185jump_list *save_quit = common->quit;
10186jump_list *save_positive_assertion_quit = common->positive_assertion_quit;
10187jump_list *save_accept = common->accept;
10192common->then_trap =
NULL;
10201private_data_ptr = PRIVATE_DATA(cc);
10203framesize = get_framesize(common, cc,
NULL,
FALSE, &needs_control_head);
10204backtrack->framesize = framesize;
10205backtrack->private_data_ptr = private_data_ptr;
10216 free_stack(common, 1);
10221 end_block_size = 3;
10226 if (bra ==
OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 +
LINK_SIZE))
10229 extrasize += end_block_size;
10231 if (needs_control_head)
10234 if (framesize == no_frame)
10238 allocate_stack(common, extrasize);
10240 if (needs_control_head)
10246 if (needs_control_head)
10255 extrasize = (needs_control_head ? 3 : 2) + end_block_size;
10258 allocate_stack(common, framesize + extrasize);
10262 if (needs_control_head)
10266 if (needs_control_head)
10275 init_frame(common, ccbegin,
NULL, framesize + extrasize - 1, extrasize);
10278if (end_block_size > 0)
10281 OP1(
SLJIT_MOV, STR_END, 0, STR_PTR, 0);
10284memset(&altbacktrack, 0,
sizeof(backtrack_common));
10288 local_quit_available =
TRUE;
10289 common->local_quit_available =
TRUE;
10290 common->quit_label =
NULL;
10291 common->quit =
NULL;
10295common->positive_assertion_quit =
NULL;
10299 common->accept_label =
NULL;
10300 common->accept =
NULL;
10301 altbacktrack.top =
NULL;
10302 altbacktrack.own_backtracks =
NULL;
10304 if (*ccbegin ==
OP_ALT && extrasize > 0)
10307 altbacktrack.cc = ccbegin;
10312 ccbegin = compile_reverse_matchingpath(common, ccbegin, &altbacktrack);
10314 compile_matchingpath(common, ccbegin, cc, &altbacktrack);
10317 if (local_quit_available)
10319 common->local_quit_available = save_local_quit_available;
10320 common->quit_label = save_quit_label;
10321 common->quit = save_quit;
10323 common->in_positive_assertion = save_in_positive_assertion;
10324 common->then_trap = save_then_trap;
10325 common->accept_label = save_accept_label;
10326 common->positive_assertion_quit = save_positive_assertion_quit;
10327 common->accept = save_accept;
10334 add_jump(compiler, &altbacktrack.top->simple_backtracks,
CMP(
SLJIT_LESS, STR_PTR, 0, STR_END, 0));
10337 common->accept_label = LABEL();
10338 if (common->accept !=
NULL)
10339 set_jumps(common->accept, common->accept_label);
10344 if (framesize == no_frame)
10346 else if (extrasize > 0)
10347 free_stack(common, extrasize);
10349 if (end_block_size > 0)
10352 if (needs_control_head)
10362 if (end_block_size > 0)
10365 if (needs_control_head)
10372 if (end_block_size > 0)
10375 if (needs_control_head)
10388 OP1(
SLJIT_MOV, STR_PTR, 0,
SLJIT_MEM1(STACK_TOP), STACK(-end_block_size - (needs_control_head ? 2 : 1)));
10403 else if (framesize >= 0)
10409 add_jump(compiler, found, JUMP(
SLJIT_JUMP));
10411 compile_backtrackingpath(common, altbacktrack.top);
10414 if (local_quit_available)
10416 common->local_quit_available = save_local_quit_available;
10417 common->quit_label = save_quit_label;
10418 common->quit = save_quit;
10420 common->in_positive_assertion = save_in_positive_assertion;
10421 common->then_trap = save_then_trap;
10422 common->accept_label = save_accept_label;
10423 common->positive_assertion_quit = save_positive_assertion_quit;
10424 common->accept = save_accept;
10427 set_jumps(altbacktrack.own_backtracks, LABEL());
10436if (local_quit_available)
10440 common->positive_assertion_quit = common->quit;
10444if (common->positive_assertion_quit !=
NULL)
10447 set_jumps(common->positive_assertion_quit, LABEL());
10460if (end_block_size > 0)
10463if (needs_control_head)
10469 if ((conditional && extrasize > 0) || bra ==
OP_BRAZERO)
10477 if (extrasize >= 2)
10478 free_stack(common, extrasize - 1);
10481 else if (extrasize > 0)
10482 free_stack(common, extrasize);
10490 free_stack(common, framesize + extrasize - 1);
10494 free_stack(common, framesize + extrasize);
10499 add_jump(compiler, target, jump);
10502 set_jumps(tmp, LABEL());
10514 if (extrasize >= 2)
10536 if (extrasize == 2 + end_block_size)
10553 backtrack->matchingpath = LABEL();
10554 SET_LABEL(jump, backtrack->matchingpath);
10558 JUMPTO(
SLJIT_JUMP, backtrack->matchingpath);
10560 if (framesize >= 0)
10568 set_jumps(backtrack->common.own_backtracks, LABEL());
10581 if (extrasize >= 2)
10582 free_stack(common, extrasize - 1);
10585 else if (extrasize > 0)
10586 free_stack(common, extrasize);
10595 free_stack(common, framesize + extrasize - 1);
10599 free_stack(common, framesize + extrasize);
10604 backtrack->matchingpath = LABEL();
10607 JUMPTO(
SLJIT_JUMP, backtrack->matchingpath);
10613 SLJIT_ASSERT(found == &backtrack->common.own_backtracks);
10614 set_jumps(backtrack->common.own_backtracks, LABEL());
10615 backtrack->common.own_backtracks =
NULL;
10619if (local_quit_available)
10621 common->local_quit_available = save_local_quit_available;
10622 common->quit_label = save_quit_label;
10623 common->quit = save_quit;
10625common->in_positive_assertion = save_in_positive_assertion;
10626common->then_trap = save_then_trap;
10627common->accept_label = save_accept_label;
10628common->positive_assertion_quit = save_positive_assertion_quit;
10629common->accept = save_accept;
10633static SLJIT_INLINE void match_once_common(compiler_common *common,
PCRE2_UCHAR ket,
int framesize,
int private_data_ptr,
BOOL has_alternatives,
BOOL needs_control_head)
10640 if (framesize == no_frame)
10644 stacksize = needs_control_head ? 1 : 0;
10645 if (ket !=
OP_KET || has_alternatives)
10649 free_stack(common, stacksize);
10652 if (needs_control_head)
10666 stacksize = (ket !=
OP_KET || has_alternatives) ? 2 : 1;
10668 if (needs_control_head)
10677if (needs_control_head)
10681static SLJIT_INLINE int match_capture_common(compiler_common *common,
int stacksize,
int offset,
int private_data_ptr)
10685if (common->capture_last_ptr != 0)
10692if (common->optimized_cbracket[
offset >> 1] == 0)
10713#ifdef SUPPORT_UNICODE
10724static void match_script_run_common(compiler_common *common,
int private_data_ptr, backtrack_common *parent)
10731#ifdef SUPPORT_UNICODE
10795static PCRE2_SPTR compile_bracket_matchingpath(compiler_common *common,
PCRE2_SPTR cc, backtrack_common *parent)
10798backtrack_common *backtrack;
10800int private_data_ptr = 0;
10803int repeat_ptr = 0, repeat_length = 0;
10804int repeat_type = 0, repeat_count = 0;
10810assert_backtrack *
assert;
10811BOOL has_alternatives;
10819PUSH_BACKTRACK(
sizeof(bracket_backtrack), cc,
NULL);
10830matchingpath = bracketend(cc) - 1 -
LINK_SIZE;
10831ket = *matchingpath;
10832if (ket ==
OP_KET && PRIVATE_DATA(matchingpath) != 0)
10834 repeat_ptr = PRIVATE_DATA(matchingpath);
10835 repeat_length = PRIVATE_DATA(matchingpath + 1);
10836 repeat_type = PRIVATE_DATA(matchingpath + 2);
10837 repeat_count = PRIVATE_DATA(matchingpath + 3);
10838 SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
10850has_alternatives = *cc ==
OP_ALT;
10854 compile_time_checks_must_be_grouped_together);
10865 if (common->optimized_cbracket[
offset] == 0)
10867 private_data_ptr = OVECTOR_PRIV(
offset);
10873 private_data_ptr = OVECTOR(
offset);
10875 BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
10881 private_data_ptr = PRIVATE_DATA(ccbegin);
10883 BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
10885 BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin,
NULL,
FALSE, &needs_control_head);
10896 allocate_stack(common, stacksize);
10914 free_stack(common, 1);
10925 if (opcode !=
OP_ONCE || BACKTRACK_AS(bracket_backtrack)->
u.framesize < 0)
10946if (repeat_type != 0)
10950 rmax_label = LABEL();
10954 BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
10958 rmax_label = LABEL();
10959 if (has_alternatives && opcode >=
OP_BRA && opcode <
OP_SBRA && repeat_type == 0)
10960 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
10967 if (needs_control_head)
10973 if (BACKTRACK_AS(bracket_backtrack)->
u.framesize < 0)
10979 if (!needs_control_head)
10984 if (BACKTRACK_AS(bracket_backtrack)->
u.framesize == no_frame)
10991 allocate_stack(common, stacksize);
10994 if (needs_control_head)
11002 if (needs_control_head)
11005 if (BACKTRACK_AS(bracket_backtrack)->
u.framesize == no_frame)
11009 else if (ket ==
OP_KETRMAX || has_alternatives)
11014 if (ket !=
OP_KET || has_alternatives)
11017 stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
11018 allocate_stack(common, stacksize);
11020 if (needs_control_head)
11026 stacksize = needs_control_head ? 1 : 0;
11027 if (ket !=
OP_KET || has_alternatives)
11039 init_frame(common, ccbegin,
NULL, BACKTRACK_AS(bracket_backtrack)->
u.framesize + stacksize, stacksize + 1);
11045 if (common->optimized_cbracket[
offset >> 1] != 0)
11048 allocate_stack(common, 2);
11058 allocate_stack(common, 1);
11066 allocate_stack(common, 4);
11072 OP1(
SLJIT_MOV, STR_END, 0, STR_PTR, 0);
11075 if (*matchingpath ==
OP_REVERSE || has_vreverse)
11076 matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack);
11082 allocate_stack(common, 1);
11087 matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack);
11089else if (has_alternatives)
11092 allocate_stack(common, 1);
11099 if (*matchingpath ==
OP_CREF)
11102 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->
u.condfailed),
11111 slot = common->name_table +
GET2(matchingpath, 1) * common->name_entry_size;
11115 slot += common->name_entry_size;
11121 slot += common->name_entry_size;
11124 add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->
u.condfailed), JUMP(
SLJIT_ZERO));
11130 BACKTRACK_AS(bracket_backtrack)->u.condfailed =
NULL;
11133 if (*matchingpath ==
OP_TRUE)
11140 else if (*matchingpath ==
OP_RREF)
11142 stacksize =
GET2(matchingpath, 1);
11143 if (common->currententry ==
NULL)
11147 else if (common->currententry->start == 0)
11148 stacksize = stacksize == 0;
11150 stacksize = stacksize == (int)
GET2(common->start, common->currententry->start + 1 +
LINK_SIZE);
11152 if (stacksize != 0)
11157 if (common->currententry ==
NULL || common->currententry->start == 0)
11162 slot = common->name_table +
GET2(matchingpath, 1) * common->name_entry_size;
11163 i = (int)
GET2(common->start, common->currententry->start + 1 +
LINK_SIZE);
11164 while (stacksize > 0)
11166 if ((
int)
GET2(slot, 0) == i)
11168 slot += common->name_entry_size;
11173 if (stacksize != 0)
11178 if (stacksize == 0)
11197 assert->common.cc = matchingpath;
11198 BACKTRACK_AS(bracket_backtrack)->u.assert =
assert;
11199 matchingpath = compile_assert_matchingpath(common, matchingpath,
assert,
TRUE);
11203compile_matchingpath(common, matchingpath, cc, backtrack);
11213 add_jump(compiler, &backtrack->top->simple_backtracks,
CMP(
SLJIT_LESS, STR_PTR, 0, STR_END, 0));
11216 if (PRIVATE_DATA(ccbegin + 1))
11223 match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->
u.framesize, private_data_ptr, has_alternatives, needs_control_head);
11226 match_script_run_common(common, private_data_ptr, backtrack);
11241 if (common->capture_last_ptr != 0)
11243 if (common->optimized_cbracket[
offset >> 1] == 0)
11246if (has_alternatives && opcode !=
OP_ONCE)
11250 allocate_stack(common, stacksize);
11270 stacksize = match_capture_common(common, stacksize,
offset, private_data_ptr);
11280if (has_alternatives)
11290 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
11294if (
offset != 0 && common->optimized_cbracket[
offset >> 1] != 0)
11302 if (repeat_type != 0)
11304 if (has_alternatives)
11305 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
11310 free_stack(common, 1);
11312 else if (opcode < OP_BRA || opcode >=
OP_SBRA)
11314 if (has_alternatives)
11315 BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
11324 free_stack(common, 1);
11332 BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
11337 count_match(common);
11341else if (repeat_type ==
OP_UPTO)
11345 allocate_stack(common, 1);
11350 BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
11355 JUMPTO(
SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
11356 if (braminzero !=
NULL)
11358 JUMPHERE(braminzero);
11362 if (opcode ==
OP_ONCE && BACKTRACK_AS(bracket_backtrack)->
u.framesize >= 0)
11369 free_stack(common, 1);
11375 count_match(common);
11382 int framesize = BACKTRACK_AS(bracket_backtrack)->u.framesize;
11384 SLJIT_ASSERT(SHRT_MIN <= framesize && framesize < SHRT_MAX/2);
11388 data = (int)((
short)((
unsigned short)framesize << 1) | (needs_control_head ? 1 : 0));
11389 BACKTRACK_AS(bracket_backtrack)->u.framesize =
data;
11391return cc + repeat_length;
11394static PCRE2_SPTR compile_bracketpos_matchingpath(compiler_common *common,
PCRE2_SPTR cc, backtrack_common *parent)
11397backtrack_common *backtrack;
11399int private_data_ptr;
11400int cbraprivptr = 0;
11401BOOL needs_control_head;
11409struct jump_list *emptymatch =
NULL;
11411PUSH_BACKTRACK(
sizeof(bracketpos_backtrack), cc,
NULL);
11419private_data_ptr = PRIVATE_DATA(cc);
11421BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
11435 cbraprivptr = OVECTOR_PRIV(
offset);
11445framesize = get_framesize(common, cc,
NULL,
FALSE, &needs_control_head);
11446BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
11452 if (common->capture_last_ptr != 0)
11458 if (needs_control_head)
11463 BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
11464 allocate_stack(common, stacksize);
11465 if (framesize == no_frame)
11475 if (common->capture_last_ptr != 0)
11478 if (needs_control_head)
11480 if (common->capture_last_ptr != 0)
11488 if (needs_control_head)
11494 if (needs_control_head)
11498 if (needs_control_head)
11506 stacksize = framesize + 1;
11509 if (needs_control_head)
11513 BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
11515 allocate_stack(common, stacksize);
11517 if (needs_control_head)
11527 if (needs_control_head)
11538 init_frame(common, cc,
NULL, stacksize - 1, stacksize - framesize);
11539 stack -= 1 + (
offset == 0);
11548 backtrack->top =
NULL;
11549 backtrack->own_backtracks =
NULL;
11552 compile_matchingpath(common, ccbegin, cc, backtrack);
11558 if (framesize == no_frame)
11566 if (common->capture_last_ptr != 0)
11578 if (needs_control_head)
11582 add_jump(compiler, &emptymatch,
CMP(
SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
11595 if (common->capture_last_ptr != 0)
11609 if (needs_control_head)
11613 add_jump(compiler, &emptymatch,
CMP(
SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
11625 flush_stubs(common);
11627 compile_backtrackingpath(common, backtrack->top);
11630 set_jumps(backtrack->own_backtracks, LABEL());
11662backtrack->own_backtracks =
NULL;
11672set_jumps(emptymatch, LABEL());
11673count_match(common);
11719 *opcode = cc[class_len - 1];
11724 *
end = cc + class_len;
11735 *
end = cc + class_len;
11747 *exact =
GET2(cc, class_len);
11761 else if (*
max == 1)
11784 *exact =
GET2(cc, 0);
11810 *
end = next_opcode(common, cc);
11816#ifdef SUPPORT_UNICODE
11817if (common->utf && HAS_EXTRALEN(*cc)) *
end += GET_EXTRALEN(*cc);
11822static PCRE2_SPTR compile_iterator_matchingpath(compiler_common *common,
PCRE2_SPTR cc, backtrack_common *parent)
11825backtrack_common *backtrack;
11829sljit_s32 early_fail_ptr = PRIVATE_DATA(cc + 1);
11831BOOL charpos_enabled;
11833unsigned int charpos_othercasebit;
11835jump_list *no_match =
NULL;
11836jump_list *no_char1_match =
NULL;
11839int private_data_ptr = PRIVATE_DATA(cc);
11841int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
11842int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw);
11843int tmp_base, tmp_offset;
11844#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
11848PUSH_BACKTRACK(
sizeof(char_iterator_backtrack), cc,
NULL);
11850early_fail_type = (early_fail_ptr & 0x7);
11851early_fail_ptr >>= 3;
11854if (common->early_fail_start_ptr == 0 && common->fast_forward_bc_ptr ==
NULL)
11856 early_fail_ptr = 0;
11857 early_fail_type = type_skip;
11861 || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr));
11863if (early_fail_type == type_fail)
11866cc = get_iterator_parameters(common, cc, &opcode, &
type, &
max, &exact, &
end);
11876 tmp_offset = POSSESSIVE0;
11891 add_jump(compiler, &backtrack->own_backtracks,
CMP(
SLJIT_GREATER, TMP1, 0, STR_END, 0));
11894 compile_char1_matchingpath(common,
type, cc, &backtrack->own_backtracks,
FALSE);
11902 compile_char1_matchingpath(common,
type, cc, &backtrack->own_backtracks,
TRUE);
11907else if (exact == 1)
11908 compile_char1_matchingpath(common,
type, cc, &backtrack->own_backtracks,
TRUE);
11910if (early_fail_type == type_fail_range)
11915 OP2(
SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0);
11916 OP2(
SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0);
11934 allocate_stack(common, 2);
11942 compile_char1_matchingpath(common,
type, cc, &BACKTRACK_AS(char_iterator_backtrack)->
u.backtracks,
TRUE);
11952 allocate_stack(common, 1);
11957 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
11960#ifdef SUPPORT_UNICODE
11968 if (private_data_ptr == 0)
11969 allocate_stack(common, 2);
11971 OP1(
SLJIT_MOV, base, offset0, STR_END, 0);
11972 OP1(
SLJIT_MOV, base, offset1, STR_PTR, 0);
11974 OP1(
SLJIT_MOV, STR_PTR, 0, STR_END, 0);
11975 process_partial_match(common);
11977 if (early_fail_ptr != 0)
11979 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
11982#ifdef SUPPORT_UNICODE
11983 else if (!common->utf)
11988 if (private_data_ptr == 0)
11989 allocate_stack(common, 2);
11991 OP1(
SLJIT_MOV, base, offset1, STR_PTR, 0);
12002 process_partial_match(common);
12006 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12008 if (early_fail_ptr != 0)
12010 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
12015 charpos_enabled =
FALSE;
12017 charpos_othercasebit = 0;
12021#ifdef SUPPORT_UNICODE
12022 charpos_enabled = !common->utf || !HAS_EXTRALEN(
end[1]);
12024 charpos_enabled =
TRUE;
12026 if (charpos_enabled && *
end ==
OP_CHARI && char_has_othercase(common,
end + 1))
12028 charpos_othercasebit = char_get_othercase_bit(common,
end + 1);
12029 if (charpos_othercasebit == 0)
12030 charpos_enabled =
FALSE;
12033 if (charpos_enabled)
12035 charpos_char =
end[1];
12038#if PCRE2_CODE_UNIT_WIDTH == 8
12040#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
12042 if ((charpos_othercasebit & 0x100) != 0)
12043 charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
12045 if (charpos_othercasebit != 0)
12046 charpos_char |= charpos_othercasebit;
12048 BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled =
TRUE;
12049 BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
12050 BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
12054 if (charpos_enabled)
12065 add_jump(compiler, &backtrack->own_backtracks, JUMP(
SLJIT_ZERO));
12067 compile_char1_matchingpath(common,
type, cc, &backtrack->own_backtracks,
FALSE);
12068 if (early_fail_ptr != 0)
12072 detect_partial_match(common, &backtrack->own_backtracks);
12073 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
12074 if (charpos_othercasebit != 0)
12078 if (private_data_ptr == 0)
12079 allocate_stack(common, 2);
12080 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12081 OP1(
SLJIT_MOV, base, offset1, STR_PTR, 0);
12086 add_jump(compiler, &no_match, JUMP(
SLJIT_ZERO));
12091 compile_char1_matchingpath(common,
type, cc, &no_match,
FALSE);
12092 if (early_fail_ptr != 0)
12094 detect_partial_match(common, &no_match);
12095 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
12096 if (charpos_othercasebit != 0)
12102 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12108 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12114 set_jumps(no_match, LABEL());
12116 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12120 if (private_data_ptr == 0)
12121 allocate_stack(common, 2);
12123 OP1(
SLJIT_MOV, base, offset1, STR_PTR, 0);
12124#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
12125 use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode ==
OP_STAR);
12129 OP1(
SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);
12134 detect_partial_match(common, &no_match);
12136 compile_char1_matchingpath(common,
type, cc, &no_char1_match,
FALSE);
12137#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
12139 OP1(
SLJIT_MOV, use_tmp ? TMP3 : base, use_tmp ? 0 : offset0, STR_PTR, 0);
12145 add_jump(compiler, &no_match, JUMP(
SLJIT_ZERO));
12148 detect_partial_match_to(common, label);
12151 set_jumps(no_char1_match, LABEL());
12152#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
12155 set_jumps(no_match, LABEL());
12159 OP1(
SLJIT_MOV, base, offset0, TMP3, 0);
12162 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12168 set_jumps(no_match, LABEL());
12169 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12172 if (early_fail_ptr != 0)
12176 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
12180 if (private_data_ptr == 0)
12181 allocate_stack(common, 1);
12182 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12183 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
12184 if (early_fail_ptr != 0)
12190 if (private_data_ptr == 0)
12191 allocate_stack(common, 2);
12192 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12194 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
12200 if (private_data_ptr == 0)
12201 allocate_stack(common, 1);
12202 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12204 compile_char1_matchingpath(common,
type, cc, &BACKTRACK_AS(char_iterator_backtrack)->
u.backtracks,
TRUE);
12205 BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
12212#if defined SUPPORT_UNICODE
12218 OP1(
SLJIT_MOV, STR_PTR, 0, STR_END, 0);
12219 process_partial_match(common);
12220 if (early_fail_ptr != 0)
12225#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
12228 OP1(
SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
12229 detect_partial_match(common, &no_match);
12231 compile_char1_matchingpath(common,
type, cc, &no_match,
FALSE);
12232 OP1(
SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
12233 detect_partial_match_to(common, label);
12235 set_jumps(no_match, LABEL());
12236 OP1(
SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
12237 if (early_fail_ptr != 0)
12239 if (!HAS_VIRTUAL_REGISTERS && tmp_base == TMP3)
12248 detect_partial_match(common, &no_match);
12250 compile_char1_matchingpath(common,
type, cc, &no_char1_match,
FALSE);
12251 detect_partial_match_to(common, label);
12254 set_jumps(no_char1_match, LABEL());
12256 set_jumps(no_match, LABEL());
12257 if (early_fail_ptr != 0)
12263#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
12269 detect_partial_match(common, &no_match);
12271 compile_char1_matchingpath(common,
type, cc, &no_match,
FALSE);
12274 add_jump(compiler, &no_match, JUMP(
SLJIT_ZERO));
12275 detect_partial_match_to(common, label);
12277 set_jumps(no_match, LABEL());
12295 process_partial_match(common);
12303 detect_partial_match(common, &no_match);
12305 compile_char1_matchingpath(common,
type, cc, &no_char1_match,
FALSE);
12307 add_jump(compiler, &no_match, JUMP(
SLJIT_ZERO));
12308 detect_partial_match_to(common, label);
12311 set_jumps(no_char1_match, LABEL());
12313 set_jumps(no_match, LABEL());
12318 OP1(
SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
12319 compile_char1_matchingpath(common,
type, cc, &no_match,
TRUE);
12320 OP1(
SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
12321 set_jumps(no_match, LABEL());
12322 OP1(
SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
12330count_match(common);
12337backtrack_common *backtrack;
12339PUSH_BACKTRACK(
sizeof(backtrack_common), cc,
NULL);
12343 add_jump(compiler, &backtrack->own_backtracks, JUMP(
SLJIT_JUMP));
12348 add_jump(compiler, &common->restart_match,
CMP(
SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
12353 if (common->accept_label ==
NULL)
12354 add_jump(compiler, &common->accept, JUMP(
SLJIT_JUMP));
12360if (common->accept_label ==
NULL)
12365if (HAS_VIRTUAL_REGISTERS)
12374add_jump(compiler, &backtrack->own_backtracks, JUMP(
SLJIT_NOT_ZERO));
12376if (common->accept_label ==
NULL)
12377 add_jump(compiler, &common->accept, JUMP(
SLJIT_ZERO));
12382if (common->accept_label ==
NULL)
12386add_jump(compiler, &backtrack->own_backtracks, JUMP(
SLJIT_JUMP));
12394BOOL optimized_cbracket = common->optimized_cbracket[
offset] != 0;
12397if (common->currententry !=
NULL)
12400if (!optimized_cbracket)
12404if (!optimized_cbracket)
12412backtrack_common *backtrack;
12418 ccend += 2 + cc[1];
12420PUSH_BACKTRACK(
sizeof(backtrack_common), cc,
NULL);
12424 allocate_stack(common, 1);
12431 if (HAS_VIRTUAL_REGISTERS)
12441static PCRE2_UCHAR then_trap_opcode[1] = { OP_THEN_TRAP };
12446backtrack_common *backtrack;
12447BOOL needs_control_head;
12450PUSH_BACKTRACK_NOVALUE(
sizeof(then_trap_backtrack), cc);
12451common->then_trap = BACKTRACK_AS(then_trap_backtrack);
12452BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
12453BACKTRACK_AS(then_trap_backtrack)->start = (
sljit_sw)(cc - common->start);
12454BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend,
FALSE, &needs_control_head);
12456size = BACKTRACK_AS(then_trap_backtrack)->framesize;
12460allocate_stack(common,
size);
12469size = BACKTRACK_AS(then_trap_backtrack)->framesize;
12471 init_frame(common, cc, ccend,
size - 1, 0);
12474static void compile_matchingpath(compiler_common *common,
PCRE2_SPTR cc,
PCRE2_SPTR ccend, backtrack_common *parent)
12477backtrack_common *backtrack;
12479then_trap_backtrack *save_then_trap =
NULL;
12483if (common->has_then && common->then_offsets[cc - common->start] != 0)
12486 has_then_trap =
TRUE;
12487 save_then_trap = common->then_trap;
12489 compile_then_trap_matchingpath(common, cc, ccend, parent);
12508 cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);
12530 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks,
TRUE);
12534 PUSH_BACKTRACK_NOVALUE(
sizeof(backtrack_common), cc);
12536 allocate_stack(common, 1);
12545 cc = compile_charn_matchingpath(common, cc, ccend, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);
12547 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks,
TRUE);
12615 cc = compile_iterator_matchingpath(common, cc, parent);
12621 cc = compile_iterator_matchingpath(common, cc, parent);
12623 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks,
TRUE);
12626#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
12629 cc = compile_iterator_matchingpath(common, cc, parent);
12631 cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks,
TRUE);
12638 cc = compile_ref_iterator_matchingpath(common, cc, parent);
12641 compile_ref_matchingpath(common, cc, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks,
TRUE,
FALSE);
12649 cc = compile_ref_iterator_matchingpath(common, cc, parent);
12652 compile_dnref_search(common, cc, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks);
12653 compile_ref_matchingpath(common, cc, parent->top !=
NULL ? &parent->top->simple_backtracks : &parent->own_backtracks,
TRUE,
FALSE);
12659 cc = compile_recurse_matchingpath(common, cc, parent);
12664 cc = compile_callout_matchingpath(common, cc, parent);
12671 PUSH_BACKTRACK_NOVALUE(
sizeof(assert_backtrack), cc);
12672 cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack),
FALSE);
12676 PUSH_BACKTRACK_NOVALUE(
sizeof(braminzero_backtrack), cc);
12677 cc = bracketend(cc + 1);
12680 allocate_stack(common, 1);
12685 allocate_stack(common, 2);
12689 BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
12690 count_match(common);
12703 cc = compile_bracket_matchingpath(common, cc, parent);
12708 cc = compile_bracket_matchingpath(common, cc, parent);
12711 PUSH_BACKTRACK_NOVALUE(
sizeof(assert_backtrack), cc);
12712 cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack),
FALSE);
12721 cc = compile_bracketpos_matchingpath(common, cc, parent);
12725 PUSH_BACKTRACK_NOVALUE(
sizeof(backtrack_common), cc);
12728 allocate_stack(common, common->has_skip_arg ? 5 : 1);
12729 if (HAS_VIRTUAL_REGISTERS)
12735 if (common->has_skip_arg)
12744 cc += 1 + 2 + cc[1];
12755 cc = compile_control_verb_matchingpath(common, cc, parent);
12761 cc = compile_fail_accept_matchingpath(common, cc, parent);
12765 cc = compile_close_matchingpath(common, cc);
12769 cc = bracketend(cc + 1);
12783 PUSH_BACKTRACK_NOVALUE(
sizeof(then_trap_backtrack), cc);
12784 BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
12785 BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
12786 common->then_trap = save_then_trap;
12791#undef PUSH_BACKTRACK
12792#undef PUSH_BACKTRACK_NOVALUE
12795#define COMPILE_BACKTRACKINGPATH(current) \
12798 compile_backtrackingpath(common, (current)); \
12799 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
12804#define CURRENT_AS(type) ((type *)current)
12806static void compile_iterator_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
12815jump_list *jumplist =
NULL;
12817int private_data_ptr = PRIVATE_DATA(cc);
12819int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
12820int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + SSIZE_OF(sw);
12822cc = get_iterator_parameters(common, cc, &opcode, &
type, &
max, &exact, &
end);
12831 set_jumps(CURRENT_AS(char_iterator_backtrack)->
u.backtracks, LABEL());
12833 free_stack(common, 1);
12838 if (CURRENT_AS(char_iterator_backtrack)->
u.charpos.enabled)
12840 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12841 OP1(
SLJIT_MOV, TMP2, 0, base, offset1);
12846 OP1(MOV_UCHAR, TMP1, 0,
SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
12847 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12848 if (CURRENT_AS(char_iterator_backtrack)->
u.charpos.othercasebit != 0)
12849 OP2(
SLJIT_OR, TMP1, 0, TMP1, 0,
SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->
u.charpos.othercasebit);
12850 CMPTO(
SLJIT_EQUAL, TMP1, 0,
SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->
u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath);
12856 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12859 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12860 JUMPTO(
SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
12863 if (private_data_ptr == 0)
12864 free_stack(common, 2);
12869 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12870 compile_char1_matchingpath(common,
type, cc, &jumplist,
TRUE);
12871 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12872 JUMPTO(
SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
12873 set_jumps(jumplist, LABEL());
12874 if (private_data_ptr == 0)
12875 free_stack(common, 1);
12879 OP1(
SLJIT_MOV, TMP1, 0, base, offset1);
12880 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12882 add_jump(compiler, &jumplist, JUMP(
SLJIT_ZERO));
12884 OP1(
SLJIT_MOV, base, offset1, TMP1, 0);
12885 compile_char1_matchingpath(common,
type, cc, &jumplist,
TRUE);
12886 OP1(
SLJIT_MOV, base, offset0, STR_PTR, 0);
12887 JUMPTO(
SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
12889 set_jumps(jumplist, LABEL());
12890 if (private_data_ptr == 0)
12891 free_stack(common, 2);
12895 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12899 set_jumps(CURRENT_AS(char_iterator_backtrack)->
u.backtracks, LABEL());
12900 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12902 JUMPTO(
SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
12904 if (private_data_ptr == 0)
12905 free_stack(common, 1);
12909 OP1(
SLJIT_MOV, STR_PTR, 0, base, offset0);
12912 compile_char1_matchingpath(common,
type, cc, &jumplist,
TRUE);
12913 JUMPTO(
SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath);
12914 set_jumps(jumplist, LABEL());
12916 if (private_data_ptr == 0)
12917 free_stack(common, 1);
12931set_jumps(
current->own_backtracks, LABEL());
12934static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
12943if ((
type & 0x1) == 0)
12946 set_jumps(
current->own_backtracks, LABEL());
12948 free_stack(common, 1);
12955set_jumps(
current->own_backtracks, LABEL());
12956free_stack(common, ref ? 2 : 3);
12959static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
12962recurse_entry *entry;
12964if (!CURRENT_AS(recurse_backtrack)->inlined_pattern)
12966 entry = CURRENT_AS(recurse_backtrack)->entry;
12967 if (entry->backtrack_label ==
NULL)
12974 compile_backtrackingpath(common,
current->top);
12976set_jumps(
current->own_backtracks, LABEL());
12979static void compile_assert_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
12999if (CURRENT_AS(assert_backtrack)->framesize < 0)
13001 set_jumps(
current->own_backtracks, LABEL());
13007 free_stack(common, 1);
13018 free_stack(common, 1);
13021 free_stack(common, 1);
13033 set_jumps(
current->own_backtracks, LABEL());
13036 set_jumps(
current->own_backtracks, LABEL());
13043 JUMPTO(
SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
13048static void compile_bracket_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13051int opcode, stacksize, alt_count, alt_max;
13053int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
13054int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
13060assert_backtrack *
assert;
13061BOOL has_alternatives;
13079ccbegin = bracketend(cc) - 1 -
LINK_SIZE;
13081if (ket ==
OP_KET && PRIVATE_DATA(ccbegin) != 0)
13083 repeat_ptr = PRIVATE_DATA(ccbegin);
13084 repeat_type = PRIVATE_DATA(ccbegin + 2);
13085 repeat_count = PRIVATE_DATA(ccbegin + 3);
13094has_alternatives = *cc ==
OP_ALT;
13102alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
13107 needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
13108 CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
13111if (ket !=
OP_KET && repeat_type != 0)
13115 free_stack(common, 1);
13127 free_stack(common, 1);
13136 if (repeat_type != 0)
13142 free_stack(common, 1);
13147 if (opcode !=
OP_ONCE || CURRENT_AS(bracket_backtrack)->
u.framesize < 0)
13152 CMPTO(
SLJIT_NOT_EQUAL, STR_PTR, 0,
SLJIT_MEM1(TMP1), STACK(-CURRENT_AS(bracket_backtrack)->
u.framesize - 2), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
13156 free_stack(common, 1);
13159 JUMPTO(
SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
13161 rmin_label = LABEL();
13162 if (repeat_type != 0)
13168 free_stack(common, 1);
13174 exact_label = LABEL();
13179 if (common->capture_last_ptr != 0)
13186 free_stack(common, 3);
13190 else if (common->optimized_cbracket[
offset >> 1] == 0)
13194 free_stack(common, 2);
13202 if (CURRENT_AS(bracket_backtrack)->
u.framesize >= 0)
13212 if (has_alternatives)
13216 free_stack(common, 1);
13222else if (has_alternatives)
13225 free_stack(common, 1);
13231 SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->
u.matching_mov_addr);
13232 sljit_set_label(CURRENT_AS(bracket_backtrack)->
u.matching_mov_addr, LABEL());
13239COMPILE_BACKTRACKINGPATH(
current->top);
13241 set_jumps(
current->own_backtracks, LABEL());
13249 assert = CURRENT_AS(bracket_backtrack)->u.assert;
13259 set_jumps(CURRENT_AS(bracket_backtrack)->
u.assert->condfailed, LABEL());
13261 else if (CURRENT_AS(bracket_backtrack)->
u.condfailed !=
NULL)
13265 set_jumps(CURRENT_AS(bracket_backtrack)->
u.condfailed, LABEL());
13271if (has_alternatives)
13285 has_vreverse =
FALSE;
13293 ccprev = compile_reverse_matchingpath(common, ccprev,
current);
13299 if (private_data_ptr != 0)
13308 compile_matchingpath(common, ccprev, cc,
current);
13318 add_jump(compiler, &
current->top->simple_backtracks,
CMP(
SLJIT_LESS, STR_PTR, 0, STR_END, 0));
13321 if (PRIVATE_DATA(ccbegin + 1))
13328 match_script_run_common(common, private_data_ptr,
current);
13336 match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->
u.framesize, private_data_ptr, has_alternatives, needs_control_head);
13349 if (common->capture_last_ptr != 0)
13351 if (common->optimized_cbracket[
offset >> 1] == 0)
13358 allocate_stack(common, stacksize);
13378 stacksize = match_capture_common(common, stacksize,
offset, private_data_ptr);
13395 JUMPTO(
SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
13401 JUMPHERE(next_alt);
13403 if (alt_count < alt_max)
13416 COMPILE_BACKTRACKINGPATH(
current->top);
13418 set_jumps(
current->own_backtracks, LABEL());
13426 assert = CURRENT_AS(bracket_backtrack)->u.assert;
13439 if (private_data_ptr == 0)
13440 free_stack(common, 1);
13446 if (common->optimized_cbracket[
offset >> 1] != 0)
13450 free_stack(common, 2);
13457 free_stack(common, 1);
13468 free_stack(common, 4);
13473 free_stack(common, 1);
13477 cc = ccbegin +
GET(ccbegin, 1);
13478 stacksize = needs_control_head ? 1 : 0;
13480 if (CURRENT_AS(bracket_backtrack)->
u.framesize >= 0)
13483 stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket !=
OP_KET || *cc ==
OP_ALT) ? 2 : 1);
13492 free_stack(common, stacksize);
13496 if (CURRENT_AS(bracket_backtrack)->
u.framesize >= 0)
13502 free_stack(common, 2);
13517 free_stack(common, 1);
13523 JUMPTO(
SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
13525 free_stack(common, 1);
13536 free_stack(common, 1);
13541 free_stack(common, 1);
13546 JUMPTO(
SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
13551static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13559if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
13572 if (common->capture_last_ptr != 0)
13575 if (common->capture_last_ptr != 0)
13578 set_jumps(
current->own_backtracks, LABEL());
13579 free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
13590 set_jumps(
current->own_backtracks, LABEL());
13592 free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
13598static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13600assert_backtrack backtrack;
13609 compile_bracket_backtrackingpath(common,
current->top);
13613 memset(&backtrack, 0,
sizeof(backtrack));
13614 backtrack.common.cc =
current->cc;
13615 backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
13617 compile_assert_matchingpath(common,
current->cc, &backtrack,
FALSE);
13622static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13631 if (common->then_trap !=
NULL)
13645 add_jump(compiler, &common->then_trap->quit, JUMP(
SLJIT_JUMP));
13648 else if (!common->local_quit_available && common->in_positive_assertion)
13650 add_jump(compiler, &common->positive_assertion_quit, JUMP(
SLJIT_JUMP));
13655if (common->local_quit_available)
13658 if (common->quit_label ==
NULL)
13659 add_jump(compiler, &common->quit, JUMP(
SLJIT_JUMP));
13681add_jump(compiler, &common->reset_match, JUMP(
SLJIT_JUMP));
13684static SLJIT_INLINE void compile_vreverse_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13692skip_valid_char(common);
13694JUMPTO(
SLJIT_JUMP, CURRENT_AS(vreverse_backtrack)->matchingpath);
13698set_jumps(
current->own_backtracks, label);
13701static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13707if (CURRENT_AS(then_trap_backtrack)->then_trap)
13709 common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
13713size = CURRENT_AS(then_trap_backtrack)->framesize;
13717free_stack(common,
size);
13720set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
13722if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
13728free_stack(common, 3);
13734static void compile_backtrackingpath(compiler_common *common,
struct backtrack_common *
current)
13737then_trap_backtrack *save_then_trap = common->then_trap;
13742 set_jumps(
current->simple_backtracks, LABEL());
13747 free_stack(common, 1);
13818#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
13821 compile_iterator_backtrackingpath(common,
current);
13828 compile_ref_iterator_backtrackingpath(common,
current);
13832 compile_recurse_backtrackingpath(common,
current);
13839 compile_assert_backtrackingpath(common,
current);
13852 compile_bracket_backtrackingpath(common,
current);
13857 compile_bracket_backtrackingpath(common,
current);
13859 compile_assert_backtrackingpath(common,
current);
13867 compile_bracketpos_backtrackingpath(common,
current);
13871 compile_braminzero_backtrackingpath(common,
current);
13876 if (common->has_skip_arg)
13878 free_stack(common, common->has_skip_arg ? 5 : 1);
13880 if (common->has_skip_arg)
13890 compile_control_verb_backtrackingpath(common,
current);
13895 if (!common->local_quit_available)
13897 if (common->quit_label ==
NULL)
13898 add_jump(compiler, &common->quit, JUMP(
SLJIT_JUMP));
13908 set_jumps(
current->own_backtracks, LABEL());
13912 compile_vreverse_backtrackingpath(common,
current);
13917 compile_then_trap_backtrackingpath(common,
current);
13926common->then_trap = save_then_trap;
13929static SLJIT_INLINE void compile_recurse(compiler_common *common)
13932PCRE2_SPTR cc = common->start + common->currententry->start;
13935uint32_t recurse_flags = 0;
13936int private_data_size = get_recurse_data_length(common, ccbegin, ccend, &recurse_flags);
13937int alt_count, alt_max, local_size;
13938backtrack_common altbacktrack;
13946common->then_trap =
NULL;
13950alt_max = no_alternatives(cc);
13954SLJIT_ASSERT(common->currententry->entry_label ==
NULL && common->recursive_head_ptr != 0);
13955common->currententry->entry_label = LABEL();
13956set_jumps(common->currententry->entry_calls, common->currententry->entry_label);
13959count_match(common);
13961local_size = (alt_max > 1) ? 2 : 1;
13966allocate_stack(common, private_data_size + local_size);
13970copy_recurse_data(common, ccbegin, ccend, recurse_copy_from_global, local_size, private_data_size + local_size, recurse_flags);
13975if (recurse_flags & recurse_flag_control_head_found)
13981memset(&altbacktrack, 0,
sizeof(backtrack_common));
13982common->quit_label =
NULL;
13983common->accept_label =
NULL;
13984common->quit =
NULL;
13985common->accept =
NULL;
13986altbacktrack.cc = ccbegin;
13990 altbacktrack.top =
NULL;
13991 altbacktrack.own_backtracks =
NULL;
13993 if (altbacktrack.cc != ccbegin)
13996 compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
14000 allocate_stack(common, (alt_max > 1 || (recurse_flags & recurse_flag_accept_found)) ? 2 : 1);
14003 if (alt_max > 1 || (recurse_flags & recurse_flag_accept_found))
14013 if (alt_count == 0)
14017 common->currententry->backtrack_label = LABEL();
14018 set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label);
14022 if (recurse_flags & recurse_flag_accept_found)
14029 copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, recurse_flags);
14034 free_stack(common, 2);
14046 free_stack(common, (recurse_flags & recurse_flag_accept_found) ? 2 : 1);
14048 else if (alt_max > 3)
14055 JUMPHERE(next_alt);
14056 if (alt_count + 1 < alt_max)
14065 compile_backtrackingpath(common, altbacktrack.top);
14068 set_jumps(altbacktrack.own_backtracks, LABEL());
14081copy_recurse_data(common, ccbegin, ccend, recurse_copy_private_to_global, local_size, private_data_size + local_size, recurse_flags);
14084free_stack(common, private_data_size + local_size);
14088if (common->quit !=
NULL)
14090 SLJIT_ASSERT(recurse_flags & recurse_flag_quit_found);
14092 set_jumps(common->quit, LABEL());
14094 copy_recurse_data(common, ccbegin, ccend, recurse_copy_shared_to_global, local_size, private_data_size + local_size, recurse_flags);
14098if (recurse_flags & recurse_flag_accept_found)
14100 JUMPHERE(accept_exit);
14101 free_stack(common, 2);
14106 copy_recurse_data(common, ccbegin, ccend, recurse_copy_kept_shared_to_global, local_size, private_data_size + local_size, recurse_flags);
14109 free_stack(common, private_data_size + local_size);
14114if (common->accept !=
NULL)
14116 SLJIT_ASSERT(recurse_flags & recurse_flag_accept_found);
14118 set_jumps(common->accept, LABEL());
14123 allocate_stack(common, 2);
14127set_jumps(
match, LABEL());
14131copy_recurse_data(common, ccbegin, ccend, recurse_swap_global, local_size, private_data_size + local_size, recurse_flags);
14138#undef COMPILE_BACKTRACKINGPATH
14141#define PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS \
14142 (PCRE2_JIT_INVALID_UTF)
14148backtrack_common rootbacktrack;
14149compiler_common common_data;
14150compiler_common *common = &common_data;
14153int private_data_size;
14156void *executable_func;
14169jump_list *reqcu_not_found =
NULL;
14173#if HAS_VIRTUAL_REGISTERS == 1
14175#elif HAS_VIRTUAL_REGISTERS == 0
14178#error "Invalid value for HAS_VIRTUAL_REGISTERS"
14181memset(&rootbacktrack, 0,
sizeof(backtrack_common));
14182memset(common, 0,
sizeof(compiler_common));
14187#ifdef SUPPORT_UNICODE
14190mode &= ~PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS;
14192common->start = rootbacktrack.cc;
14193common->read_only_data_head =
NULL;
14196common->mode =
mode;
14210common->nlmax = READ_CHAR_MAX;
14224common->bsr_nlmax = READ_CHAR_MAX;
14225common->bsr_nlmin = 0;
14232#ifdef SUPPORT_UNICODE
14239 common->nlmax = 0x2029;
14245 common->nlmax = common->newline & 0xff;
14249 common->nlmin = common->newline & 0xff;
14254 common->bsr_nlmax = 0x2029;
14260 common->invalid_utf =
FALSE;
14262ccend = bracketend(common->start);
14265common->ovector_start = LIMIT_MATCH +
sizeof(
sljit_sw);
14267if (!common->optimized_cbracket)
14269#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
14276#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
14277common->capture_last_ptr = common->ovector_start;
14278common->ovector_start +=
sizeof(
sljit_sw);
14280if (!check_opcode_types(common, common->start, ccend))
14282 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14289 common->req_char_ptr = common->ovector_start;
14290 common->ovector_start +=
sizeof(
sljit_sw);
14294 common->start_used_ptr = common->ovector_start;
14295 common->ovector_start +=
sizeof(
sljit_sw);
14298 common->hit_start = common->ovector_start;
14299 common->ovector_start +=
sizeof(
sljit_sw);
14304 common->match_end_ptr = common->ovector_start;
14305 common->ovector_start +=
sizeof(
sljit_sw);
14307#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
14308common->control_head_ptr = 1;
14310if (common->control_head_ptr != 0)
14312 common->control_head_ptr = common->ovector_start;
14313 common->ovector_start +=
sizeof(
sljit_sw);
14315if (common->has_set_som)
14318 common->start_ptr = common->ovector_start;
14319 common->ovector_start +=
sizeof(
sljit_sw);
14323if ((common->ovector_start &
sizeof(
sljit_sw)) != 0)
14324 common->ovector_start +=
sizeof(
sljit_sw);
14326if (common->start_ptr == 0)
14327 common->start_ptr = OVECTOR(0);
14330if (common->capture_last_ptr != 0)
14333SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
14336total_length = ccend - common->start;
14338if (!common->private_data_ptrs)
14340 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14343memset(common->private_data_ptrs, 0, total_length *
sizeof(
sljit_s32));
14348 detect_early_fail(common, common->start, &private_data_size, 0, 0);
14350set_private_data_ptrs(common, &private_data_size, ccend);
14352SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr);
14354if (private_data_size > 65536)
14356 SLJIT_FREE(common->private_data_ptrs, allocator_data);
14357 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14361if (common->has_then)
14363 common->then_offsets = (
sljit_u8 *)(common->private_data_ptrs + total_length);
14364 memset(common->then_offsets, 0, total_length);
14365 set_then_offsets(common, common->start,
NULL);
14371 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14372 SLJIT_FREE(common->private_data_ptrs, allocator_data);
14375common->compiler = compiler;
14383if (common->req_char_ptr != 0)
14397if (common->early_fail_start_ptr < common->early_fail_end_ptr)
14398 reset_early_fail(common);
14402if (common->mark_ptr != 0)
14404if (common->control_head_ptr != 0)
14410 mainloop_label = mainloop_entry(common);
14411 continue_match_label = LABEL();
14418 fast_forward_first_char(common);
14420 fast_forward_newline(common);
14422 fast_forward_start_bits(common);
14426 continue_match_label = LABEL();
14434if (common->req_char_ptr != 0)
14441if (common->capture_last_ptr != 0)
14443if (common->fast_forward_bc_ptr !=
NULL)
14446if (common->start_ptr != OVECTOR(0))
14459compile_matchingpath(common, common->start, ccend, &rootbacktrack);
14463 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14464 SLJIT_FREE(common->private_data_ptrs, allocator_data);
14472if (common->might_be_empty)
14475 empty_match_found_label = LABEL();
14478common->accept_label = LABEL();
14479if (common->accept !=
NULL)
14480 set_jumps(common->accept, common->accept_label);
14484common->quit_label = common->abort_label = LABEL();
14485if (common->quit !=
NULL)
14486 set_jumps(common->quit, common->quit_label);
14487if (common->abort !=
NULL)
14488 set_jumps(common->abort, common->abort_label);
14489if (minlength_check_failed !=
NULL)
14490 SET_LABEL(minlength_check_failed, common->abort_label);
14495if (common->failed_match !=
NULL)
14498 set_jumps(common->failed_match, LABEL());
14504 JUMPHERE(end_anchor_failed);
14508 common->partialmatchlabel = LABEL();
14509 set_jumps(common->partialmatch, common->partialmatchlabel);
14510 return_with_partial_match(common, common->quit_label);
14513if (common->might_be_empty)
14514 empty_match_backtrack_label = LABEL();
14515compile_backtrackingpath(common, rootbacktrack.top);
14519 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14520 SLJIT_FREE(common->private_data_ptrs, allocator_data);
14526reset_match_label = LABEL();
14545 (common->fast_forward_bc_ptr !=
NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1) >> 3) : common->start_ptr);
14549 if (common->ff_newline_shortcut !=
NULL)
14554 if (common->match_end_ptr != 0)
14558 CMPTO(
SLJIT_LESS, STR_PTR, 0, TMP1, 0, common->ff_newline_shortcut);
14562 CMPTO(
SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
14566 CMPTO(
SLJIT_LESS, STR_PTR, 0, (common->match_end_ptr == 0) ? STR_END : TMP1, 0, mainloop_label);
14570if (reqcu_not_found !=
NULL)
14571 set_jumps(reqcu_not_found, LABEL());
14579flush_stubs(common);
14581if (common->might_be_empty)
14583 JUMPHERE(empty_match);
14589 JUMPTO(
SLJIT_ZERO, empty_match_found_label);
14591 CMPTO(
SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
14592 JUMPTO(
SLJIT_JUMP, empty_match_backtrack_label);
14595common->fast_forward_bc_ptr =
NULL;
14596common->early_fail_start_ptr = 0;
14597common->early_fail_end_ptr = 0;
14598common->currententry = common->entries;
14599common->local_quit_available =
TRUE;
14600quit_label = common->quit_label;
14601if (common->currententry !=
NULL)
14604 common->recurse_bitset_size = ((private_data_size / SSIZE_OF(sw)) + 7) >> 3;
14606 common->recurse_bitset = (
sljit_u8*)
SLJIT_MALLOC(common->recurse_bitset_size, allocator_data);;
14608 if (common->recurse_bitset !=
NULL)
14613 compile_recurse(common);
14616 flush_stubs(common);
14617 common->currententry = common->currententry->next;
14619 while (common->currententry !=
NULL);
14621 SLJIT_FREE(common->recurse_bitset, allocator_data);
14624 if (common->currententry !=
NULL)
14627 SLJIT_ASSERT(sljit_get_compiler_error(compiler) || common->recurse_bitset ==
NULL);
14630 SLJIT_FREE(common->optimized_cbracket, allocator_data);
14631 SLJIT_FREE(common->private_data_ptrs, allocator_data);
14636common->local_quit_available =
FALSE;
14637common->quit_label = quit_label;
14641set_jumps(common->stackalloc, LABEL());
14651OP1(
SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
14656OP1(
SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
14669set_jumps(common->calllimit, LABEL());
14673if (common->revertframes !=
NULL)
14675 set_jumps(common->revertframes, LABEL());
14676 do_revertframes(common);
14678if (common->wordboundary !=
NULL)
14680 set_jumps(common->wordboundary, LABEL());
14681 check_wordboundary(common,
FALSE);
14683if (common->ucp_wordboundary !=
NULL)
14685 set_jumps(common->ucp_wordboundary, LABEL());
14686 check_wordboundary(common,
TRUE);
14688if (common->anynewline !=
NULL)
14690 set_jumps(common->anynewline, LABEL());
14691 check_anynewline(common);
14693if (common->hspace !=
NULL)
14695 set_jumps(common->hspace, LABEL());
14696 check_hspace(common);
14698if (common->vspace !=
NULL)
14700 set_jumps(common->vspace, LABEL());
14701 check_vspace(common);
14703if (common->casefulcmp !=
NULL)
14705 set_jumps(common->casefulcmp, LABEL());
14706 do_casefulcmp(common);
14708if (common->caselesscmp !=
NULL)
14710 set_jumps(common->caselesscmp, LABEL());
14711 do_caselesscmp(common);
14713if (common->reset_match !=
NULL || common->restart_match !=
NULL)
14715 if (common->restart_match !=
NULL)
14717 set_jumps(common->restart_match, LABEL());
14721 set_jumps(common->reset_match, LABEL());
14722 do_reset_match(common, (re->
top_bracket + 1) * 2);
14724 CMPTO(
SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
14728#ifdef SUPPORT_UNICODE
14729#if PCRE2_CODE_UNIT_WIDTH == 8
14730if (common->utfreadchar !=
NULL)
14732 set_jumps(common->utfreadchar, LABEL());
14733 do_utfreadchar(common);
14735if (common->utfreadtype8 !=
NULL)
14737 set_jumps(common->utfreadtype8, LABEL());
14738 do_utfreadtype8(common);
14740if (common->utfpeakcharback !=
NULL)
14742 set_jumps(common->utfpeakcharback, LABEL());
14743 do_utfpeakcharback(common);
14746#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16
14747if (common->utfreadchar_invalid !=
NULL)
14749 set_jumps(common->utfreadchar_invalid, LABEL());
14750 do_utfreadchar_invalid(common);
14752if (common->utfreadnewline_invalid !=
NULL)
14754 set_jumps(common->utfreadnewline_invalid, LABEL());
14755 do_utfreadnewline_invalid(common);
14757if (common->utfmoveback_invalid)
14759 set_jumps(common->utfmoveback_invalid, LABEL());
14760 do_utfmoveback_invalid(common);
14762if (common->utfpeakcharback_invalid)
14764 set_jumps(common->utfpeakcharback_invalid, LABEL());
14765 do_utfpeakcharback_invalid(common);
14768if (common->getucd !=
NULL)
14770 set_jumps(common->getucd, LABEL());
14773if (common->getucdtype !=
NULL)
14775 set_jumps(common->getucdtype, LABEL());
14776 do_getucdtype(common);
14780SLJIT_FREE(common->optimized_cbracket, allocator_data);
14781SLJIT_FREE(common->private_data_ptrs, allocator_data);
14784executable_size = sljit_get_generated_code_size(compiler);
14787if (executable_func ==
NULL)
14821functions->read_only_data_heads[
mode] = common->read_only_data_head;
14843#define PUBLIC_JIT_COMPILE_OPTIONS \
14844 (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD|PCRE2_JIT_INVALID_UTF)
14852static int executable_allocator_is_working = -1;
14915if (executable_allocator_is_working == -1)
14920 void *
ptr = SLJIT_MALLOC_EXEC(32,
NULL);
14924 executable_allocator_is_working = 1;
14926 else executable_allocator_is_working = 0;
14929if (!executable_allocator_is_working)
14938 int result = jit_compile(code,
options & ~excluded_options);
14946 int result = jit_compile(code,
options & ~excluded_options);
14954 int result = jit_compile(code,
options & ~excluded_options);
14967#define INCLUDED_FROM_PCRE2_JIT_COMPILE
sizeof(Countable|array $value, int $mode=COUNT_NORMAL)
prev(array|object &$array)
count(Countable|array $value, int $mode=COUNT_NORMAL)
assert(mixed $assertion, Throwable|string|null $description=null)
memset(ptr, 0, type->size)
foreach($dp as $el) foreach( $dp as $el) if( $pass2< 2) echo ""
#define PCRE2_DOLLAR_ENDONLY
#define PCRE2_NOTEMPTY_ATSTART
#define PCRE2_ENDANCHORED
#define PCRE2_BSR_ANYCRLF
#define PCRE2_ERROR_NOMATCH
#define PCRE2_ERROR_INTERNAL
#define PCRE2_ERROR_JIT_BADOPTION
#define PCRE2_MATCH_INVALID_UTF
#define PCRE2_NEWLINE_ANYCRLF
#define PCRE2_MATCH_UNSET_BACKREF
#define PCRE2_ERROR_JIT_STACKLIMIT
#define PCRE2_USE_OFFSET_LIMIT
#define PCRE2_ERROR_MATCHLIMIT
#define PCRE2_JIT_PARTIAL_HARD
#define PCRE2_JIT_INVALID_UTF
#define PCRE2_CALL_CONVENTION
#define PCRE2_ALT_CIRCUMFLEX
#define PCRE2_JIT_COMPLETE
#define PCRE2_NEWLINE_CRLF
#define PCRE2_JIT_PARTIAL_SOFT
#define PCRE2_NEWLINE_NUL
#define PCRE2_BSR_UNICODE
#define PCRE2_NO_START_OPTIMIZE
#define pcre2_callout_block
#define PCRE2_ERROR_PARTIAL
#define PCRE2_NEWLINE_ANY
#define pcre2_jit_compile
#define PCRE2_ERROR_NOMEMORY
@ OP_NOT_UCP_WORD_BOUNDARY
#define PCRE2_FIRSTMAPSET
#define PCRE2_FIRSTCASELESS
#define CHAR_GRAVE_ACCENT
#define PCRE2_LASTCASELESS
#define MAX_UTF_CODE_POINT
#define CHAR_COMMERCIAL_AT
#define UCD_BIDICLASS_SHIFT
#define UCD_OTHERCASE(ch)
#define PCRE2_MATCH_EMPTY
#define UCD_GRAPHBREAK(ch)
#define TABLE_GET(c, table, default)
#define GETCHARINCTEST(c, eptr)
#define GETCHARLEN(c, eptr, len)
#define GETCHARINC(c, eptr)
#define PUBLIC_JIT_COMPILE_OPTIONS
void PRIV jit_free_rodata(void *current, void *allocator_data)
unsigned int PRIV ord2utf(uint32_t cvalue, PCRE2_UCHAR *buffer)
BOOL PRIV script_run(PCRE2_SPTR ptr, PCRE2_SPTR endptr, BOOL utf)
@ ucp_gbRegional_Indicator
@ ucp_gbExtended_Pictographic
int PRIV valid_utf(PCRE2_SPTR string, PCRE2_SIZE length, PCRE2_SIZE *erroroffset)
unsigned const char * end
PHP_JSON_API size_t int options
#define SLJIT_UNREACHABLE()
unsigned short int sljit_u16
#define SLJIT_UNLIKELY(x)
#define SLJIT_COMPILE_ASSERT(x, description)
#define SLJIT_MALLOC(size, allocator_data)
#define SLJIT_FREE(ptr, allocator_data)
#define SLJIT_UNUSED_ARG(arg)
#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS
#define SLJIT_EXEC_OFFSET(ptr)
#define SLJIT_ARGS3(ret, arg1, arg2, arg3)
#define SLJIT_SET_SIG_LESS_EQUAL
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void *code, void *exec_allocator_data)
#define SLJIT_FAST_RETURN
#define SLJIT_SET_GREATER_EQUAL
#define SLJIT_HAS_ZERO_REGISTER
SLJIT_API_FUNC_ATTRIBUTE void * sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
#define SLJIT_MEM2(r1, r2)
#define SLJIT_FUNC_ADDR(func_name)
#define SLJIT_CURRENT_FLAGS_COMPARE
#define SLJIT_SET_SIG_GREATER
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label *label)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
#define SLJIT_SIG_LESS_EQUAL
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
#define SLJIT_ARGS1(ret, arg1)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
#define SLJIT_SIG_GREATER
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
#define SLJIT_GREATER_EQUAL
#define SLJIT_GP_REGISTER
#define SLJIT_SKIP_FRAMES_BEFORE_RETURN
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw)
#define SLJIT_OFFSETOF(base, member)
#define SLJIT_SET_LESS_EQUAL
#define SLJIT_SET_GREATER
#define SLJIT_MAX_LOCAL_SIZE
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler * sljit_create_compiler(void *allocator_data)
#define SLJIT_CURRENT_FLAGS_SUB
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
#define SLJIT_ARGS2(ret, arg1, arg2)
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw)
file_private int match(struct magic_set *, struct magic *, size_t, const struct buffer *, size_t, int, int, int, uint16_t *, uint16_t *, int *, int *, int *, int *, int *)
void *(* malloc)(size_t, void *)
void(* free)(void *, void *)
uint16_t newline_convention
struct sljit_label * label
strcmp(string $string1, string $string2)