| 82 |
expressions. The basic blocks of regular expressions are condition checkers |
expressions. The basic blocks of regular expressions are condition checkers |
| 83 |
whose execute different commands depending on the result of the condition check. |
whose execute different commands depending on the result of the condition check. |
| 84 |
The relationship between the operators can be horizontal (concatenation) and |
The relationship between the operators can be horizontal (concatenation) and |
| 85 |
vertical (sub-expression) (See struct fallback_common for more details). |
vertical (sub-expression) (See struct backtrack_common for more details). |
| 86 |
|
|
| 87 |
'ab' - 'a' and 'b' regexps are concatenated |
'ab' - 'a' and 'b' regexps are concatenated |
| 88 |
'a+' - 'a' is the sub-expression of the '+' operator |
'a+' - 'a' is the sub-expression of the '+' operator |
| 89 |
|
|
| 90 |
The condition checkers are boolean (true/false) checkers. Machine code is generated |
The condition checkers are boolean (true/false) checkers. Machine code is generated |
| 91 |
for the checker itself and for the actions depending on the result of the checker. |
for the checker itself and for the actions depending on the result of the checker. |
| 92 |
The 'true' case is called as the hot path (expected path), and the other is called as |
The 'true' case is called as the try path (expected path), and the other is called as |
| 93 |
the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken |
the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken |
| 94 |
branches on the hot path. |
branches on the try path. |
| 95 |
|
|
| 96 |
Greedy star operator (*) : |
Greedy star operator (*) : |
| 97 |
Hot path: match happens. |
Try path: match happens. |
| 98 |
Fallback path: match failed. |
Backtrack path: match failed. |
| 99 |
Non-greedy star operator (*?) : |
Non-greedy star operator (*?) : |
| 100 |
Hot path: no need to perform a match. |
Try path: no need to perform a match. |
| 101 |
Fallback path: match is required. |
Backtrack path: match is required. |
| 102 |
|
|
| 103 |
The following example shows how the code generated for a capturing bracket |
The following example shows how the code generated for a capturing bracket |
| 104 |
with two alternatives. Let A, B, C, D are arbirary regular expressions, and |
with two alternatives. Let A, B, C, D are arbirary regular expressions, and |
| 108 |
|
|
| 109 |
The generated code will be the following: |
The generated code will be the following: |
| 110 |
|
|
| 111 |
A hot path |
A try path |
| 112 |
'(' hot path (pushing arguments to the stack) |
'(' try path (pushing arguments to the stack) |
| 113 |
B hot path |
B try path |
| 114 |
')' hot path (pushing arguments to the stack) |
')' try path (pushing arguments to the stack) |
| 115 |
D hot path |
D try path |
| 116 |
return with successful match |
return with successful match |
| 117 |
|
|
| 118 |
D fallback path |
D backtrack path |
| 119 |
')' fallback path (If we arrived from "C" jump to the fallback of "C") |
')' backtrack path (If we arrived from "C" jump to the backtrack of "C") |
| 120 |
B fallback path |
B backtrack path |
| 121 |
C expected path |
C expected path |
| 122 |
jump to D hot path |
jump to D try path |
| 123 |
C fallback path |
C backtrack path |
| 124 |
A fallback path |
A backtrack path |
| 125 |
|
|
| 126 |
Notice, that the order of fallback code paths are the opposite of the fast |
Notice, that the order of backtrack code paths are the opposite of the fast |
| 127 |
code paths. In this way the topmost value on the stack is always belong |
code paths. In this way the topmost value on the stack is always belong |
| 128 |
to the current fallback code path. The fallback code path must check |
to the current backtrack code path. The backtrack path must check |
| 129 |
whether there is a next alternative. If so, it needs to jump back to |
whether there is a next alternative. If so, it needs to jump back to |
| 130 |
the hot path eventually. Otherwise it needs to clear out its own stack |
the try path eventually. Otherwise it needs to clear out its own stack |
| 131 |
frame and continue the execution on the fallback code paths. |
frame and continue the execution on the backtrack code paths. |
| 132 |
*/ |
*/ |
| 133 |
|
|
| 134 |
/* |
/* |
| 135 |
Saved stack frames: |
Saved stack frames: |
| 136 |
|
|
| 137 |
Atomic blocks and asserts require reloading the values of local variables |
Atomic blocks and asserts require reloading the values of local variables |
| 138 |
when the fallback mechanism performed. Because of OP_RECURSE, the locals |
when the backtrack mechanism performed. Because of OP_RECURSE, the locals |
| 139 |
are not necessarly known in compile time, thus we need a dynamic restore |
are not necessarly known in compile time, thus we need a dynamic restore |
| 140 |
mechanism. |
mechanism. |
| 141 |
|
|
| 188 |
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); |
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); |
| 189 |
|
|
| 190 |
/* The following structure is the key data type for the recursive |
/* The following structure is the key data type for the recursive |
| 191 |
code generator. It is allocated by compile_hotpath, and contains |
code generator. It is allocated by compile_trypath, and contains |
| 192 |
the aguments for compile_fallbackpath. Must be the first member |
the aguments for compile_backtrackpath. Must be the first member |
| 193 |
of its descendants. */ |
of its descendants. */ |
| 194 |
typedef struct fallback_common { |
typedef struct backtrack_common { |
| 195 |
/* Concatenation stack. */ |
/* Concatenation stack. */ |
| 196 |
struct fallback_common *prev; |
struct backtrack_common *prev; |
| 197 |
jump_list *nextfallbacks; |
jump_list *nextbacktracks; |
| 198 |
/* Internal stack (for component operators). */ |
/* Internal stack (for component operators). */ |
| 199 |
struct fallback_common *top; |
struct backtrack_common *top; |
| 200 |
jump_list *topfallbacks; |
jump_list *topbacktracks; |
| 201 |
/* Opcode pointer. */ |
/* Opcode pointer. */ |
| 202 |
pcre_uchar *cc; |
pcre_uchar *cc; |
| 203 |
} fallback_common; |
} backtrack_common; |
| 204 |
|
|
| 205 |
typedef struct assert_fallback { |
typedef struct assert_backtrack { |
| 206 |
fallback_common common; |
backtrack_common common; |
| 207 |
jump_list *condfailed; |
jump_list *condfailed; |
| 208 |
/* Less than 0 (-1) if a frame is not needed. */ |
/* Less than 0 (-1) if a frame is not needed. */ |
| 209 |
int framesize; |
int framesize; |
| 210 |
/* Points to our private memory word on the stack. */ |
/* Points to our private memory word on the stack. */ |
| 211 |
int localptr; |
int localptr; |
| 212 |
/* For iterators. */ |
/* For iterators. */ |
| 213 |
struct sljit_label *hotpath; |
struct sljit_label *trypath; |
| 214 |
} assert_fallback; |
} assert_backtrack; |
| 215 |
|
|
| 216 |
typedef struct bracket_fallback { |
typedef struct bracket_backtrack { |
| 217 |
fallback_common common; |
backtrack_common common; |
| 218 |
/* Where to coninue if an alternative is successfully matched. */ |
/* Where to coninue if an alternative is successfully matched. */ |
| 219 |
struct sljit_label *althotpath; |
struct sljit_label *alttrypath; |
| 220 |
/* For rmin and rmax iterators. */ |
/* For rmin and rmax iterators. */ |
| 221 |
struct sljit_label *recursivehotpath; |
struct sljit_label *recursivetrypath; |
| 222 |
/* For greedy ? operator. */ |
/* For greedy ? operator. */ |
| 223 |
struct sljit_label *zerohotpath; |
struct sljit_label *zerotrypath; |
| 224 |
/* Contains the branches of a failed condition. */ |
/* Contains the branches of a failed condition. */ |
| 225 |
union { |
union { |
| 226 |
/* Both for OP_COND, OP_SCOND. */ |
/* Both for OP_COND, OP_SCOND. */ |
| 227 |
jump_list *condfailed; |
jump_list *condfailed; |
| 228 |
assert_fallback *assert; |
assert_backtrack *assert; |
| 229 |
/* For OP_ONCE. -1 if not needed. */ |
/* For OP_ONCE. -1 if not needed. */ |
| 230 |
int framesize; |
int framesize; |
| 231 |
} u; |
} u; |
| 232 |
/* Points to our private memory word on the stack. */ |
/* Points to our private memory word on the stack. */ |
| 233 |
int localptr; |
int localptr; |
| 234 |
} bracket_fallback; |
} bracket_backtrack; |
| 235 |
|
|
| 236 |
typedef struct bracketpos_fallback { |
typedef struct bracketpos_backtrack { |
| 237 |
fallback_common common; |
backtrack_common common; |
| 238 |
/* Points to our private memory word on the stack. */ |
/* Points to our private memory word on the stack. */ |
| 239 |
int localptr; |
int localptr; |
| 240 |
/* Reverting stack is needed. */ |
/* Reverting stack is needed. */ |
| 241 |
int framesize; |
int framesize; |
| 242 |
/* Allocated stack size. */ |
/* Allocated stack size. */ |
| 243 |
int stacksize; |
int stacksize; |
| 244 |
} bracketpos_fallback; |
} bracketpos_backtrack; |
| 245 |
|
|
| 246 |
typedef struct braminzero_fallback { |
typedef struct braminzero_backtrack { |
| 247 |
fallback_common common; |
backtrack_common common; |
| 248 |
struct sljit_label *hotpath; |
struct sljit_label *trypath; |
| 249 |
} braminzero_fallback; |
} braminzero_backtrack; |
| 250 |
|
|
| 251 |
typedef struct iterator_fallback { |
typedef struct iterator_backtrack { |
| 252 |
fallback_common common; |
backtrack_common common; |
| 253 |
/* Next iteration. */ |
/* Next iteration. */ |
| 254 |
struct sljit_label *hotpath; |
struct sljit_label *trypath; |
| 255 |
} iterator_fallback; |
} iterator_backtrack; |
| 256 |
|
|
| 257 |
typedef struct recurse_entry { |
typedef struct recurse_entry { |
| 258 |
struct recurse_entry *next; |
struct recurse_entry *next; |
| 264 |
int start; |
int start; |
| 265 |
} recurse_entry; |
} recurse_entry; |
| 266 |
|
|
| 267 |
typedef struct recurse_fallback { |
typedef struct recurse_backtrack { |
| 268 |
fallback_common common; |
backtrack_common common; |
| 269 |
} recurse_fallback; |
} recurse_backtrack; |
| 270 |
|
|
| 271 |
typedef struct compiler_common { |
typedef struct compiler_common { |
| 272 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
| 467 |
init_frame |
init_frame |
| 468 |
get_localsize |
get_localsize |
| 469 |
copy_locals |
copy_locals |
| 470 |
compile_hotpath |
compile_trypath |
| 471 |
compile_fallbackpath |
compile_backtrackpath |
| 472 |
*/ |
*/ |
| 473 |
|
|
| 474 |
static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) |
static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) |
| 1622 |
return return_value; |
return return_value; |
| 1623 |
} |
} |
| 1624 |
|
|
| 1625 |
static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks) |
static void detect_partial_match(compiler_common *common, jump_list **backtracks) |
| 1626 |
{ |
{ |
| 1627 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 1628 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 1629 |
|
|
| 1630 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
| 1631 |
{ |
{ |
| 1632 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
| 1633 |
return; |
return; |
| 1634 |
} |
} |
| 1635 |
|
|
| 1636 |
/* Partial matching mode. */ |
/* Partial matching mode. */ |
| 1637 |
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
| 1638 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); |
| 1639 |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
| 1640 |
{ |
{ |
| 1641 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
| 1642 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
| 1643 |
} |
} |
| 1644 |
else |
else |
| 1645 |
{ |
{ |
| 1789 |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
| 1790 |
} |
} |
| 1791 |
|
|
| 1792 |
static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue) |
static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue) |
| 1793 |
{ |
{ |
| 1794 |
/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ |
/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */ |
| 1795 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 1797 |
if (nltype == NLTYPE_ANY) |
if (nltype == NLTYPE_ANY) |
| 1798 |
{ |
{ |
| 1799 |
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); |
| 1800 |
add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 1801 |
} |
} |
| 1802 |
else if (nltype == NLTYPE_ANYCRLF) |
else if (nltype == NLTYPE_ANYCRLF) |
| 1803 |
{ |
{ |
| 1805 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
| 1806 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); |
| 1807 |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); |
| 1808 |
add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 1809 |
} |
} |
| 1810 |
else |
else |
| 1811 |
{ |
{ |
| 1812 |
SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); |
SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); |
| 1813 |
add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); |
add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); |
| 1814 |
} |
} |
| 1815 |
} |
} |
| 1816 |
|
|
| 2733 |
#endif /* SUPPORT_UTF && SUPPORT_UCP */ |
#endif /* SUPPORT_UTF && SUPPORT_UCP */ |
| 2734 |
|
|
| 2735 |
static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc, |
static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc, |
| 2736 |
compare_context* context, jump_list **fallbacks) |
compare_context* context, jump_list **backtracks) |
| 2737 |
{ |
{ |
| 2738 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 2739 |
unsigned int othercasebit = 0; |
unsigned int othercasebit = 0; |
| 2834 |
case 4 / sizeof(pcre_uchar): |
case 4 / sizeof(pcre_uchar): |
| 2835 |
if (context->oc.asint != 0) |
if (context->oc.asint != 0) |
| 2836 |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint); |
| 2837 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); |
| 2838 |
break; |
break; |
| 2839 |
|
|
| 2840 |
case 2 / sizeof(pcre_uchar): |
case 2 / sizeof(pcre_uchar): |
| 2841 |
if (context->oc.asushort != 0) |
if (context->oc.asushort != 0) |
| 2842 |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); |
| 2843 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); |
| 2844 |
break; |
break; |
| 2845 |
|
|
| 2846 |
#ifdef COMPILE_PCRE8 |
#ifdef COMPILE_PCRE8 |
| 2847 |
case 1: |
case 1: |
| 2848 |
if (context->oc.asbyte != 0) |
if (context->oc.asbyte != 0) |
| 2849 |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte); |
| 2850 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); |
| 2851 |
break; |
break; |
| 2852 |
#endif |
#endif |
| 2853 |
|
|
| 2873 |
if (othercasebit != 0 && othercasechar == cc) |
if (othercasebit != 0 && othercasechar == cc) |
| 2874 |
{ |
{ |
| 2875 |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); |
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); |
| 2876 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); |
| 2877 |
} |
} |
| 2878 |
else |
else |
| 2879 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); |
| 2880 |
|
|
| 2881 |
#endif |
#endif |
| 2882 |
|
|
| 2912 |
} \ |
} \ |
| 2913 |
charoffset = (value); |
charoffset = (value); |
| 2914 |
|
|
| 2915 |
static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks) |
static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) |
| 2916 |
{ |
{ |
| 2917 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 2918 |
jump_list *found = NULL; |
jump_list *found = NULL; |
| 2919 |
jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks; |
jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; |
| 2920 |
unsigned int c; |
unsigned int c; |
| 2921 |
int compares; |
int compares; |
| 2922 |
struct sljit_jump *jump = NULL; |
struct sljit_jump *jump = NULL; |
| 2931 |
unsigned int charoffset; |
unsigned int charoffset; |
| 2932 |
|
|
| 2933 |
/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ |
/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ |
| 2934 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 2935 |
read_char(common); |
read_char(common); |
| 2936 |
|
|
| 2937 |
if ((*cc++ & XCL_MAP) != 0) |
if ((*cc++ & XCL_MAP) != 0) |
| 3082 |
while (*cc != XCL_END) |
while (*cc != XCL_END) |
| 3083 |
{ |
{ |
| 3084 |
compares--; |
compares--; |
| 3085 |
invertcmp = (compares == 0 && list != fallbacks); |
invertcmp = (compares == 0 && list != backtracks); |
| 3086 |
jump = NULL; |
jump = NULL; |
| 3087 |
|
|
| 3088 |
if (*cc == XCL_SINGLE) |
if (*cc == XCL_SINGLE) |
| 3164 |
switch(*cc) |
switch(*cc) |
| 3165 |
{ |
{ |
| 3166 |
case PT_ANY: |
case PT_ANY: |
| 3167 |
if (list != fallbacks) |
if (list != backtracks) |
| 3168 |
{ |
{ |
| 3169 |
if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) |
if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) |
| 3170 |
continue; |
continue; |
| 3237 |
#endif |
#endif |
| 3238 |
|
|
| 3239 |
if (jump != NULL) |
if (jump != NULL) |
| 3240 |
add_jump(compiler, compares > 0 ? list : fallbacks, jump); |
add_jump(compiler, compares > 0 ? list : backtracks, jump); |
| 3241 |
} |
} |
| 3242 |
|
|
| 3243 |
if (found != NULL) |
if (found != NULL) |
| 3249 |
|
|
| 3250 |
#endif |
#endif |
| 3251 |
|
|
| 3252 |
static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks) |
static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) |
| 3253 |
{ |
{ |
| 3254 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 3255 |
int length; |
int length; |
| 3268 |
case OP_SOD: |
case OP_SOD: |
| 3269 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
| 3270 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 3271 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); |
| 3272 |
return cc; |
return cc; |
| 3273 |
|
|
| 3274 |
case OP_SOM: |
case OP_SOM: |
| 3275 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
| 3276 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
| 3277 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); |
| 3278 |
return cc; |
return cc; |
| 3279 |
|
|
| 3280 |
case OP_NOT_WORD_BOUNDARY: |
case OP_NOT_WORD_BOUNDARY: |
| 3281 |
case OP_WORD_BOUNDARY: |
case OP_WORD_BOUNDARY: |
| 3282 |
add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); |
| 3283 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 3284 |
return cc; |
return cc; |
| 3285 |
|
|
| 3286 |
case OP_NOT_DIGIT: |
case OP_NOT_DIGIT: |
| 3287 |
case OP_DIGIT: |
case OP_DIGIT: |
| 3288 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3289 |
read_char8_type(common); |
read_char8_type(common); |
| 3290 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); |
| 3291 |
add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
| 3292 |
return cc; |
return cc; |
| 3293 |
|
|
| 3294 |
case OP_NOT_WHITESPACE: |
case OP_NOT_WHITESPACE: |
| 3295 |
case OP_WHITESPACE: |
case OP_WHITESPACE: |
| 3296 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3297 |
read_char8_type(common); |
read_char8_type(common); |
| 3298 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); |
| 3299 |
add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
| 3300 |
return cc; |
return cc; |
| 3301 |
|
|
| 3302 |
case OP_NOT_WORDCHAR: |
case OP_NOT_WORDCHAR: |
| 3303 |
case OP_WORDCHAR: |
case OP_WORDCHAR: |
| 3304 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3305 |
read_char8_type(common); |
read_char8_type(common); |
| 3306 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); |
| 3307 |
add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
| 3308 |
return cc; |
return cc; |
| 3309 |
|
|
| 3310 |
case OP_ANY: |
case OP_ANY: |
| 3311 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3312 |
read_char(common); |
read_char(common); |
| 3313 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 3314 |
{ |
{ |
| 3319 |
jump[1] = check_str_end(common); |
jump[1] = check_str_end(common); |
| 3320 |
|
|
| 3321 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
| 3322 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); |
| 3323 |
if (jump[1] != NULL) |
if (jump[1] != NULL) |
| 3324 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3325 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3326 |
} |
} |
| 3327 |
else |
else |
| 3328 |
check_newlinechar(common, common->nltype, fallbacks, TRUE); |
check_newlinechar(common, common->nltype, backtracks, TRUE); |
| 3329 |
return cc; |
return cc; |
| 3330 |
|
|
| 3331 |
case OP_ALLANY: |
case OP_ALLANY: |
| 3332 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3333 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3334 |
if (common->utf) |
if (common->utf) |
| 3335 |
{ |
{ |
| 3357 |
return cc; |
return cc; |
| 3358 |
|
|
| 3359 |
case OP_ANYBYTE: |
case OP_ANYBYTE: |
| 3360 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3361 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
| 3362 |
return cc; |
return cc; |
| 3363 |
|
|
| 3370 |
propdata[2] = cc[0]; |
propdata[2] = cc[0]; |
| 3371 |
propdata[3] = cc[1]; |
propdata[3] = cc[1]; |
| 3372 |
propdata[4] = XCL_END; |
propdata[4] = XCL_END; |
| 3373 |
compile_xclass_hotpath(common, propdata, fallbacks); |
compile_xclass_trypath(common, propdata, backtracks); |
| 3374 |
return cc + 2; |
return cc + 2; |
| 3375 |
#endif |
#endif |
| 3376 |
#endif |
#endif |
| 3377 |
|
|
| 3378 |
case OP_ANYNL: |
case OP_ANYNL: |
| 3379 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3380 |
read_char(common); |
read_char(common); |
| 3381 |
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
| 3382 |
/* We don't need to handle soft partial matching case. */ |
/* We don't need to handle soft partial matching case. */ |
| 3389 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
| 3390 |
jump[3] = JUMP(SLJIT_JUMP); |
jump[3] = JUMP(SLJIT_JUMP); |
| 3391 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3392 |
check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE); |
check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); |
| 3393 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3394 |
JUMPHERE(jump[2]); |
JUMPHERE(jump[2]); |
| 3395 |
JUMPHERE(jump[3]); |
JUMPHERE(jump[3]); |
| 3397 |
|
|
| 3398 |
case OP_NOT_HSPACE: |
case OP_NOT_HSPACE: |
| 3399 |
case OP_HSPACE: |
case OP_HSPACE: |
| 3400 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3401 |
read_char(common); |
read_char(common); |
| 3402 |
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
| 3403 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 3404 |
return cc; |
return cc; |
| 3405 |
|
|
| 3406 |
case OP_NOT_VSPACE: |
case OP_NOT_VSPACE: |
| 3407 |
case OP_VSPACE: |
case OP_VSPACE: |
| 3408 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3409 |
read_char(common); |
read_char(common); |
| 3410 |
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
| 3411 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 3412 |
return cc; |
return cc; |
| 3413 |
|
|
| 3414 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
| 3415 |
case OP_EXTUNI: |
case OP_EXTUNI: |
| 3416 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3417 |
read_char(common); |
read_char(common); |
| 3418 |
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
| 3419 |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); |
| 3420 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); |
| 3421 |
|
|
| 3422 |
label = LABEL(); |
label = LABEL(); |
| 3423 |
jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
| 3447 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
| 3448 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
| 3449 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
| 3450 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
| 3451 |
else |
else |
| 3452 |
{ |
{ |
| 3453 |
jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); |
jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); |
| 3455 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); |
| 3456 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
| 3457 |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); |
| 3458 |
add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL)); |
add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); |
| 3459 |
check_partial(common, TRUE); |
check_partial(common, TRUE); |
| 3460 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
| 3461 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3462 |
} |
} |
| 3463 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
| 3464 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
| 3465 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
| 3466 |
} |
} |
| 3467 |
else if (common->nltype == NLTYPE_FIXED) |
else if (common->nltype == NLTYPE_FIXED) |
| 3468 |
{ |
{ |
| 3469 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
| 3470 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
| 3471 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
| 3472 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); |
| 3473 |
} |
} |
| 3474 |
else |
else |
| 3475 |
{ |
{ |
| 3478 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
| 3479 |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); |
| 3480 |
jump[2] = JUMP(SLJIT_C_GREATER); |
jump[2] = JUMP(SLJIT_C_GREATER); |
| 3481 |
add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS)); |
add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS)); |
| 3482 |
/* Equal. */ |
/* Equal. */ |
| 3483 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
| 3484 |
jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); |
jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); |
| 3485 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
| 3486 |
|
|
| 3487 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3488 |
if (common->nltype == NLTYPE_ANYCRLF) |
if (common->nltype == NLTYPE_ANYCRLF) |
| 3489 |
{ |
{ |
| 3490 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
| 3491 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); |
| 3492 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); |
| 3493 |
} |
} |
| 3494 |
else |
else |
| 3495 |
{ |
{ |
| 3496 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0); |
| 3497 |
read_char(common); |
read_char(common); |
| 3498 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); |
| 3499 |
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); |
| 3500 |
add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); |
| 3501 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); |
| 3502 |
} |
} |
| 3503 |
JUMPHERE(jump[2]); |
JUMPHERE(jump[2]); |
| 3508 |
return cc; |
return cc; |
| 3509 |
|
|
| 3510 |
case OP_EOD: |
case OP_EOD: |
| 3511 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
| 3512 |
check_partial(common, FALSE); |
check_partial(common, FALSE); |
| 3513 |
return cc; |
return cc; |
| 3514 |
|
|
| 3515 |
case OP_CIRC: |
case OP_CIRC: |
| 3516 |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
| 3517 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 3518 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); |
| 3519 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); |
| 3520 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3521 |
return cc; |
return cc; |
| 3522 |
|
|
| 3523 |
case OP_CIRCM: |
case OP_CIRCM: |
| 3525 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 3526 |
jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); |
jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); |
| 3527 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); |
| 3528 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3529 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
| 3530 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3531 |
|
|
| 3532 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
| 3533 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 3534 |
{ |
{ |
| 3535 |
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
| 3536 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); |
| 3537 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); |
| 3538 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); |
| 3539 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
| 3540 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
| 3541 |
} |
} |
| 3542 |
else |
else |
| 3543 |
{ |
{ |
| 3544 |
skip_char_back(common); |
skip_char_back(common); |
| 3545 |
read_char(common); |
read_char(common); |
| 3546 |
check_newlinechar(common, common->nltype, fallbacks, FALSE); |
check_newlinechar(common, common->nltype, backtracks, FALSE); |
| 3547 |
} |
} |
| 3548 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3549 |
return cc; |
return cc; |
| 3551 |
case OP_DOLL: |
case OP_DOLL: |
| 3552 |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
| 3553 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); |
| 3554 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3555 |
|
|
| 3556 |
if (!common->endonly) |
if (!common->endonly) |
| 3557 |
compile_char1_hotpath(common, OP_EODN, cc, fallbacks); |
compile_char1_trypath(common, OP_EODN, cc, backtracks); |
| 3558 |
else |
else |
| 3559 |
{ |
{ |
| 3560 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
| 3561 |
check_partial(common, FALSE); |
check_partial(common, FALSE); |
| 3562 |
} |
} |
| 3563 |
return cc; |
return cc; |
| 3566 |
jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
| 3567 |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
| 3568 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); |
| 3569 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3570 |
check_partial(common, FALSE); |
check_partial(common, FALSE); |
| 3571 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
| 3572 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3576 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
| 3577 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
| 3578 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
| 3579 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); |
| 3580 |
else |
else |
| 3581 |
{ |
{ |
| 3582 |
jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); |
jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); |
| 3583 |
/* STR_PTR = STR_END - IN_UCHARS(1) */ |
/* STR_PTR = STR_END - IN_UCHARS(1) */ |
| 3584 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
| 3585 |
check_partial(common, TRUE); |
check_partial(common, TRUE); |
| 3586 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
| 3587 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3588 |
} |
} |
| 3589 |
|
|
| 3590 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
| 3591 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
| 3592 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
| 3593 |
} |
} |
| 3594 |
else |
else |
| 3595 |
{ |
{ |
| 3596 |
peek_char(common); |
peek_char(common); |
| 3597 |
check_newlinechar(common, common->nltype, fallbacks, FALSE); |
check_newlinechar(common, common->nltype, backtracks, FALSE); |
| 3598 |
} |
} |
| 3599 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3600 |
return cc; |
return cc; |
| 3608 |
if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) |
if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) |
| 3609 |
{ |
{ |
| 3610 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
| 3611 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
| 3612 |
|
|
| 3613 |
context.length = IN_UCHARS(length); |
context.length = IN_UCHARS(length); |
| 3614 |
context.sourcereg = -1; |
context.sourcereg = -1; |
| 3615 |
#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED |
#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED |
| 3616 |
context.ucharptr = 0; |
context.ucharptr = 0; |
| 3617 |
#endif |
#endif |
| 3618 |
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks); |
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); |
| 3619 |
} |
} |
| 3620 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3621 |
read_char(common); |
read_char(common); |
| 3622 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3623 |
if (common->utf) |
if (common->utf) |
| 3629 |
c = *cc; |
c = *cc; |
| 3630 |
if (type == OP_CHAR || !char_has_othercase(common, cc)) |
if (type == OP_CHAR || !char_has_othercase(common, cc)) |
| 3631 |
{ |
{ |
| 3632 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
| 3633 |
return cc + length; |
return cc + length; |
| 3634 |
} |
} |
| 3635 |
oc = char_othercase(common, c); |
oc = char_othercase(common, c); |
| 3637 |
if (ispowerof2(bit)) |
if (ispowerof2(bit)) |
| 3638 |
{ |
{ |
| 3639 |
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
| 3640 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
| 3641 |
return cc + length; |
return cc + length; |
| 3642 |
} |
} |
| 3643 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); |
| 3644 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
| 3645 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); |
| 3646 |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); |
| 3647 |
add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); |
| 3648 |
return cc + length; |
return cc + length; |
| 3649 |
|
|
| 3650 |
case OP_NOT: |
case OP_NOT: |
| 3651 |
case OP_NOTI: |
case OP_NOTI: |
| 3652 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3653 |
length = 1; |
length = 1; |
| 3654 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3655 |
if (common->utf) |
if (common->utf) |
| 3660 |
{ |
{ |
| 3661 |
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
| 3662 |
if (type == OP_NOT || !char_has_othercase(common, cc)) |
if (type == OP_NOT || !char_has_othercase(common, cc)) |
| 3663 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
| 3664 |
else |
else |
| 3665 |
{ |
{ |
| 3666 |
/* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ |
/* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */ |
| 3667 |
OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); |
OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); |
| 3668 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); |
| 3669 |
} |
} |
| 3670 |
/* Skip the variable-length character. */ |
/* Skip the variable-length character. */ |
| 3671 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
| 3690 |
} |
} |
| 3691 |
|
|
| 3692 |
if (type == OP_NOT || !char_has_othercase(common, cc)) |
if (type == OP_NOT || !char_has_othercase(common, cc)) |
| 3693 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
| 3694 |
else |
else |
| 3695 |
{ |
{ |
| 3696 |
oc = char_othercase(common, c); |
oc = char_othercase(common, c); |
| 3698 |
if (ispowerof2(bit)) |
if (ispowerof2(bit)) |
| 3699 |
{ |
{ |
| 3700 |
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
| 3701 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
| 3702 |
} |
} |
| 3703 |
else |
else |
| 3704 |
{ |
{ |
| 3705 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
| 3706 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); |
| 3707 |
} |
} |
| 3708 |
} |
} |
| 3709 |
return cc + length; |
return cc + length; |
| 3710 |
|
|
| 3711 |
case OP_CLASS: |
case OP_CLASS: |
| 3712 |
case OP_NCLASS: |
case OP_NCLASS: |
| 3713 |
fallback_at_str_end(common, fallbacks); |
detect_partial_match(common, backtracks); |
| 3714 |
read_char(common); |
read_char(common); |
| 3715 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
| 3716 |
jump[0] = NULL; |
jump[0] = NULL; |
| 3723 |
jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); |
jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); |
| 3724 |
if (type == OP_CLASS) |
if (type == OP_CLASS) |
| 3725 |
{ |
{ |
| 3726 |
add_jump(compiler, fallbacks, jump[0]); |
add_jump(compiler, backtracks, jump[0]); |
| 3727 |
jump[0] = NULL; |
jump[0] = NULL; |
| 3728 |
} |
} |
| 3729 |
} |
} |
| 3733 |
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); |
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); |
| 3734 |
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
| 3735 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); |
| 3736 |
add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO)); |
add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); |
| 3737 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
| 3738 |
if (jump[0] != NULL) |
if (jump[0] != NULL) |
| 3739 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3742 |
|
|
| 3743 |
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 |
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 |
| 3744 |
case OP_XCLASS: |
case OP_XCLASS: |
| 3745 |
compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks); |
compile_xclass_trypath(common, cc + LINK_SIZE, backtracks); |
| 3746 |
return cc + GET(cc, 0) - 1; |
return cc + GET(cc, 0) - 1; |
| 3747 |
#endif |
#endif |
| 3748 |
|
|
| 3757 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 3758 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); |
| 3759 |
label = LABEL(); |
label = LABEL(); |
| 3760 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); |
| 3761 |
skip_char_back(common); |
skip_char_back(common); |
| 3762 |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); |
| 3763 |
JUMPTO(SLJIT_C_NOT_ZERO, label); |
JUMPTO(SLJIT_C_NOT_ZERO, label); |
| 3767 |
{ |
{ |
| 3768 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 3769 |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
| 3770 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); |
| 3771 |
} |
} |
| 3772 |
check_start_used_ptr(common); |
check_start_used_ptr(common); |
| 3773 |
return cc + LINK_SIZE; |
return cc + LINK_SIZE; |
| 3776 |
return cc; |
return cc; |
| 3777 |
} |
} |
| 3778 |
|
|
| 3779 |
static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks) |
static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) |
| 3780 |
{ |
{ |
| 3781 |
/* This function consumes at least one input character. */ |
/* This function consumes at least one input character. */ |
| 3782 |
/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ |
/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ |
| 3828 |
{ |
{ |
| 3829 |
/* We have a fixed-length byte sequence. */ |
/* We have a fixed-length byte sequence. */ |
| 3830 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length); |
| 3831 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
| 3832 |
|
|
| 3833 |
context.sourcereg = -1; |
context.sourcereg = -1; |
| 3834 |
#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED |
#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED |
| 3835 |
context.ucharptr = 0; |
context.ucharptr = 0; |
| 3836 |
#endif |
#endif |
| 3837 |
do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0); |
do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0); |
| 3838 |
return cc; |
return cc; |
| 3839 |
} |
} |
| 3840 |
|
|
| 3841 |
/* A non-fixed length character will be checked if length == 0. */ |
/* A non-fixed length character will be checked if length == 0. */ |
| 3842 |
return compile_char1_hotpath(common, *cc, cc + 1, fallbacks); |
return compile_char1_trypath(common, *cc, cc + 1, backtracks); |
| 3843 |
} |
} |
| 3844 |
|
|
| 3845 |
static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks) |
static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) |
| 3846 |
{ |
{ |
| 3847 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 3848 |
int offset = GET2(cc, 1) << 1; |
int offset = GET2(cc, 1) << 1; |
| 3850 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
| 3851 |
if (!common->jscript_compat) |
if (!common->jscript_compat) |
| 3852 |
{ |
{ |
| 3853 |
if (fallbacks == NULL) |
if (backtracks == NULL) |
| 3854 |
{ |
{ |
| 3855 |
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
| 3856 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
| 3859 |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); |
| 3860 |
return JUMP(SLJIT_C_NOT_ZERO); |
return JUMP(SLJIT_C_NOT_ZERO); |
| 3861 |
} |
} |
| 3862 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
| 3863 |
} |
} |
| 3864 |
return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
| 3865 |
} |
} |
| 3866 |
|
|
| 3867 |
/* Forward definitions. */ |
/* Forward definitions. */ |
| 3868 |
static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *); |
static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); |
| 3869 |
static void compile_fallbackpath(compiler_common *, struct fallback_common *); |
static void compile_backtrackpath(compiler_common *, struct backtrack_common *); |
| 3870 |
|
|
| 3871 |
#define PUSH_FALLBACK(size, ccstart, error) \ |
#define PUSH_BACKTRACK(size, ccstart, error) \ |
| 3872 |
do \ |
do \ |
| 3873 |
{ \ |
{ \ |
| 3874 |
fallback = sljit_alloc_memory(compiler, (size)); \ |
backtrack = sljit_alloc_memory(compiler, (size)); \ |
| 3875 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ |
| 3876 |
return error; \ |
return error; \ |
| 3877 |
memset(fallback, 0, size); \ |
memset(backtrack, 0, size); \ |
| 3878 |
fallback->prev = parent->top; \ |
backtrack->prev = parent->top; \ |
| 3879 |
fallback->cc = (ccstart); \ |
backtrack->cc = (ccstart); \ |
| 3880 |
parent->top = fallback; \ |
parent->top = backtrack; \ |
| 3881 |
} \ |
} \ |
| 3882 |
while (0) |
while (0) |
| 3883 |
|
|
| 3884 |
#define PUSH_FALLBACK_NOVALUE(size, ccstart) \ |
#define PUSH_BACKTRACK_NOVALUE(size, ccstart) \ |
| 3885 |
do \ |
do \ |
| 3886 |
{ \ |
{ \ |
| 3887 |
fallback = sljit_alloc_memory(compiler, (size)); \ |
backtrack = sljit_alloc_memory(compiler, (size)); \ |
| 3888 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ |
| 3889 |
return; \ |
return; \ |
| 3890 |
memset(fallback, 0, size); \ |
memset(backtrack, 0, size); \ |
| 3891 |
fallback->prev = parent->top; \ |
backtrack->prev = parent->top; \ |
| 3892 |
fallback->cc = (ccstart); \ |
backtrack->cc = (ccstart); \ |
| 3893 |
parent->top = fallback; \ |
parent->top = backtrack; \ |
| 3894 |
} \ |
} \ |
| 3895 |
while (0) |
while (0) |
| 3896 |
|
|
| 3897 |
#define FALLBACK_AS(type) ((type *)fallback) |
#define BACKTRACK_AS(type) ((type *)backtrack) |
| 3898 |
|
|
| 3899 |
static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail) |
static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) |
| 3900 |
{ |
{ |
| 3901 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 3902 |
int offset = GET2(cc, 1) << 1; |
int offset = GET2(cc, 1) << 1; |
| 3907 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
| 3908 |
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
| 3909 |
if (withchecks && !common->jscript_compat) |
if (withchecks && !common->jscript_compat) |
| 3910 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
| 3911 |
|
|
| 3912 |
#if defined SUPPORT_UTF && defined SUPPORT_UCP |
#if defined SUPPORT_UTF && defined SUPPORT_UCP |
| 3913 |
if (common->utf && *cc == OP_REFI) |
if (common->utf && *cc == OP_REFI) |
| 3924 |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); |
| 3925 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
| 3926 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
| 3927 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); |
| 3928 |
else |
else |
| 3929 |
{ |
{ |
| 3930 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
| 3931 |
nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
| 3932 |
check_partial(common, FALSE); |
check_partial(common, FALSE); |
| 3933 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
| 3934 |
JUMPHERE(nopartial); |
JUMPHERE(nopartial); |
| 3935 |
} |
} |
| 3936 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); |
| 3945 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
| 3946 |
partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); |
partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); |
| 3947 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
| 3948 |
add_jump(compiler, fallbacks, partial); |
add_jump(compiler, backtracks, partial); |
| 3949 |
|
|
| 3950 |
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
| 3951 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3952 |
|
|
| 3953 |
if (common->mode != JIT_COMPILE) |
if (common->mode != JIT_COMPILE) |
| 3954 |
{ |
{ |
| 3960 |
partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); |
partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); |
| 3961 |
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); |
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); |
| 3962 |
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
| 3963 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3964 |
JUMPHERE(partial); |
JUMPHERE(partial); |
| 3965 |
check_partial(common, FALSE); |
check_partial(common, FALSE); |
| 3966 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
| 3967 |
JUMPHERE(nopartial); |
JUMPHERE(nopartial); |
| 3968 |
} |
} |
| 3969 |
} |
} |
| 3971 |
if (jump != NULL) |
if (jump != NULL) |
| 3972 |
{ |
{ |
| 3973 |
if (emptyfail) |
if (emptyfail) |
| 3974 |
add_jump(compiler, fallbacks, jump); |
add_jump(compiler, backtracks, jump); |
| 3975 |
else |
else |
| 3976 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 3977 |
} |
} |
| 3978 |
return cc + 1 + IMM2_SIZE; |
return cc + 1 + IMM2_SIZE; |
| 3979 |
} |
} |
| 3980 |
|
|
| 3981 |
static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent) |
static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
| 3982 |
{ |
{ |
| 3983 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 3984 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 3985 |
pcre_uchar type; |
pcre_uchar type; |
| 3986 |
struct sljit_label *label; |
struct sljit_label *label; |
| 3987 |
struct sljit_jump *zerolength; |
struct sljit_jump *zerolength; |
| 3990 |
int min = 0, max = 0; |
int min = 0, max = 0; |
| 3991 |
BOOL minimize; |
BOOL minimize; |
| 3992 |
|
|
| 3993 |
PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL); |
PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); |
| 3994 |
|
|
| 3995 |
type = cc[1 + IMM2_SIZE]; |
type = cc[1 + IMM2_SIZE]; |
| 3996 |
minimize = (type & 0x1) != 0; |
minimize = (type & 0x1) != 0; |
| 4042 |
{ |
{ |
| 4043 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
| 4044 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 4045 |
zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks); |
zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); |
| 4046 |
} |
} |
| 4047 |
|
|
| 4048 |
if (min > 1 || max > 1) |
if (min > 1 || max > 1) |
| 4049 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); |
| 4050 |
|
|
| 4051 |
label = LABEL(); |
label = LABEL(); |
| 4052 |
compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE); |
compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); |
| 4053 |
|
|
| 4054 |
if (min > 1 || max > 1) |
if (min > 1 || max > 1) |
| 4055 |
{ |
{ |
| 4077 |
} |
} |
| 4078 |
|
|
| 4079 |
JUMPHERE(zerolength); |
JUMPHERE(zerolength); |
| 4080 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); |
| 4081 |
|
|
| 4082 |
decrease_call_count(common); |
decrease_call_count(common); |
| 4083 |
return cc; |
return cc; |
| 4095 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
| 4096 |
} |
} |
| 4097 |
else |
else |
| 4098 |
zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks); |
zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); |
| 4099 |
|
|
| 4100 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); |
| 4101 |
if (max > 0) |
if (max > 0) |
| 4102 |
add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); |
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); |
| 4103 |
|
|
| 4104 |
compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE); |
compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); |
| 4105 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 4106 |
|
|
| 4107 |
if (min > 1) |
if (min > 1) |
| 4109 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 4110 |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
| 4111 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
| 4112 |
CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath); |
CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath); |
| 4113 |
} |
} |
| 4114 |
else if (max > 0) |
else if (max > 0) |
| 4115 |
OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); |
OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); |
| 4122 |
return cc; |
return cc; |
| 4123 |
} |
} |
| 4124 |
|
|
| 4125 |
static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent) |
static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
| 4126 |
{ |
{ |
| 4127 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 4128 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 4129 |
recurse_entry *entry = common->entries; |
recurse_entry *entry = common->entries; |
| 4130 |
recurse_entry *prev = NULL; |
recurse_entry *prev = NULL; |
| 4131 |
int start = GET(cc, 1); |
int start = GET(cc, 1); |
| 4132 |
|
|
| 4133 |
PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL); |
PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); |
| 4134 |
while (entry != NULL) |
while (entry != NULL) |
| 4135 |
{ |
{ |
| 4136 |
if (entry->start == start) |
if (entry->start == start) |
| 4175 |
else |
else |
| 4176 |
JUMPTO(SLJIT_FAST_CALL, entry->entry); |
JUMPTO(SLJIT_FAST_CALL, entry->entry); |
| 4177 |
/* Leave if the match is failed. */ |
/* Leave if the match is failed. */ |
| 4178 |
add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); |
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); |
| 4179 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
| 4180 |
} |
} |
| 4181 |
|
|
| 4182 |
static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional) |
static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) |
| 4183 |
{ |
{ |
| 4184 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 4185 |
int framesize; |
int framesize; |
| 4186 |
int localptr; |
int localptr; |
| 4187 |
fallback_common altfallback; |
backtrack_common altbacktrack; |
| 4188 |
pcre_uchar *ccbegin; |
pcre_uchar *ccbegin; |
| 4189 |
pcre_uchar opcode; |
pcre_uchar opcode; |
| 4190 |
pcre_uchar bra = OP_BRA; |
pcre_uchar bra = OP_BRA; |
| 4191 |
jump_list *tmp = NULL; |
jump_list *tmp = NULL; |
| 4192 |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; |
| 4193 |
jump_list **found; |
jump_list **found; |
| 4194 |
/* Saving previous accept variables. */ |
/* Saving previous accept variables. */ |
| 4195 |
struct sljit_label *save_leavelabel = common->leavelabel; |
struct sljit_label *save_leavelabel = common->leavelabel; |
| 4208 |
localptr = PRIV_DATA(cc); |
localptr = PRIV_DATA(cc); |
| 4209 |
SLJIT_ASSERT(localptr != 0); |
SLJIT_ASSERT(localptr != 0); |
| 4210 |
framesize = get_framesize(common, cc, FALSE); |
framesize = get_framesize(common, cc, FALSE); |
| 4211 |
fallback->framesize = framesize; |
backtrack->framesize = framesize; |
| 4212 |
fallback->localptr = localptr; |
backtrack->localptr = localptr; |
| 4213 |
opcode = *cc; |
opcode = *cc; |
| 4214 |
SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); |
SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); |
| 4215 |
found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; |
found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; |
| 4218 |
|
|
| 4219 |
if (bra == OP_BRAMINZERO) |
if (bra == OP_BRAMINZERO) |
| 4220 |
{ |
{ |
| 4221 |
/* This is a braminzero fallback path. */ |
/* This is a braminzero backtrack path. */ |
| 4222 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 4223 |
free_stack(common, 1); |
free_stack(common, 1); |
| 4224 |
brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
| 4241 |
init_frame(common, ccbegin, framesize + 1, 2, FALSE); |
init_frame(common, ccbegin, framesize + 1, 2, FALSE); |
| 4242 |
} |
} |
| 4243 |
|
|
| 4244 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altbacktrack, 0, sizeof(backtrack_common)); |
| 4245 |
common->leavelabel = NULL; |
common->leavelabel = NULL; |
| 4246 |
common->leave = NULL; |
common->leave = NULL; |
| 4247 |
while (1) |
while (1) |
| 4248 |
{ |
{ |
| 4249 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
| 4250 |
common->accept = NULL; |
common->accept = NULL; |
| 4251 |
altfallback.top = NULL; |
altbacktrack.top = NULL; |
| 4252 |
altfallback.topfallbacks = NULL; |
altbacktrack.topbacktracks = NULL; |
| 4253 |
|
|
| 4254 |
if (*ccbegin == OP_ALT) |
if (*ccbegin == OP_ALT) |
| 4255 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 4256 |
|
|
| 4257 |
altfallback.cc = ccbegin; |
altbacktrack.cc = ccbegin; |
| 4258 |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); |
| 4259 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 4260 |
{ |
{ |
| 4261 |
common->leavelabel = save_leavelabel; |
common->leavelabel = save_leavelabel; |
| 4310 |
} |
} |
| 4311 |
add_jump(compiler, found, JUMP(SLJIT_JUMP)); |
add_jump(compiler, found, JUMP(SLJIT_JUMP)); |
| 4312 |
|
|
| 4313 |
compile_fallbackpath(common, altfallback.top); |
compile_backtrackpath(common, altbacktrack.top); |
| 4314 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 4315 |
{ |
{ |
| 4316 |
common->leavelabel = save_leavelabel; |
common->leavelabel = save_leavelabel; |
| 4319 |
common->accept = save_accept; |
common->accept = save_accept; |
| 4320 |
return NULL; |
return NULL; |
| 4321 |
} |
} |
| 4322 |
set_jumps(altfallback.topfallbacks, LABEL()); |
set_jumps(altbacktrack.topbacktracks, LABEL()); |
| 4323 |
|
|
| 4324 |
if (*cc != OP_ALT) |
if (*cc != OP_ALT) |
| 4325 |
break; |
break; |
| 4396 |
|
|
| 4397 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 4398 |
{ |
{ |
| 4399 |
fallback->hotpath = LABEL(); |
backtrack->trypath = LABEL(); |
| 4400 |
sljit_set_label(jump, fallback->hotpath); |
sljit_set_label(jump, backtrack->trypath); |
| 4401 |
} |
} |
| 4402 |
else if (bra == OP_BRAMINZERO) |
else if (bra == OP_BRAMINZERO) |
| 4403 |
{ |
{ |
| 4404 |
JUMPTO(SLJIT_JUMP, fallback->hotpath); |
JUMPTO(SLJIT_JUMP, backtrack->trypath); |
| 4405 |
JUMPHERE(brajump); |
JUMPHERE(brajump); |
| 4406 |
if (framesize >= 0) |
if (framesize >= 0) |
| 4407 |
{ |
{ |
| 4409 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
| 4410 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); |
| 4411 |
} |
} |
| 4412 |
set_jumps(fallback->common.topfallbacks, LABEL()); |
set_jumps(backtrack->common.topbacktracks, LABEL()); |
| 4413 |
} |
} |
| 4414 |
} |
} |
| 4415 |
else |
else |
| 4439 |
} |
} |
| 4440 |
|
|
| 4441 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 4442 |
fallback->hotpath = LABEL(); |
backtrack->trypath = LABEL(); |
| 4443 |
else if (bra == OP_BRAMINZERO) |
else if (bra == OP_BRAMINZERO) |
| 4444 |
{ |
{ |
| 4445 |
JUMPTO(SLJIT_JUMP, fallback->hotpath); |
JUMPTO(SLJIT_JUMP, backtrack->trypath); |
| 4446 |
JUMPHERE(brajump); |
JUMPHERE(brajump); |
| 4447 |
} |
} |
| 4448 |
|
|
| 4449 |
if (bra != OP_BRA) |
if (bra != OP_BRA) |
| 4450 |
{ |
{ |
| 4451 |
SLJIT_ASSERT(found == &fallback->common.topfallbacks); |
SLJIT_ASSERT(found == &backtrack->common.topbacktracks); |
| 4452 |
set_jumps(fallback->common.topfallbacks, LABEL()); |
set_jumps(backtrack->common.topbacktracks, LABEL()); |
| 4453 |
fallback->common.topfallbacks = NULL; |
backtrack->common.topbacktracks = NULL; |
| 4454 |
} |
} |
| 4455 |
} |
} |
| 4456 |
|
|
| 4625 |
Or nothing, if trace is unnecessary |
Or nothing, if trace is unnecessary |
| 4626 |
*/ |
*/ |
| 4627 |
|
|
| 4628 |
static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent) |
static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
| 4629 |
{ |
{ |
| 4630 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 4631 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 4632 |
pcre_uchar opcode; |
pcre_uchar opcode; |
| 4633 |
int localptr = 0; |
int localptr = 0; |
| 4634 |
int offset = 0; |
int offset = 0; |
| 4635 |
int stacksize; |
int stacksize; |
| 4636 |
pcre_uchar *ccbegin; |
pcre_uchar *ccbegin; |
| 4637 |
pcre_uchar *hotpath; |
pcre_uchar *trypath; |
| 4638 |
pcre_uchar bra = OP_BRA; |
pcre_uchar bra = OP_BRA; |
| 4639 |
pcre_uchar ket; |
pcre_uchar ket; |
| 4640 |
assert_fallback *assert; |
assert_backtrack *assert; |
| 4641 |
BOOL has_alternatives; |
BOOL has_alternatives; |
| 4642 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 4643 |
struct sljit_jump *skip; |
struct sljit_jump *skip; |
| 4644 |
struct sljit_label *rmaxlabel = NULL; |
struct sljit_label *rmaxlabel = NULL; |
| 4645 |
struct sljit_jump *braminzerojump = NULL; |
struct sljit_jump *braminzerojump = NULL; |
| 4646 |
|
|
| 4647 |
PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL); |
PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); |
| 4648 |
|
|
| 4649 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
| 4650 |
{ |
{ |
| 4655 |
|
|
| 4656 |
opcode = *cc; |
opcode = *cc; |
| 4657 |
ccbegin = cc; |
ccbegin = cc; |
| 4658 |
hotpath = ccbegin + 1 + LINK_SIZE; |
trypath = ccbegin + 1 + LINK_SIZE; |
| 4659 |
|
|
| 4660 |
if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) |
if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) |
| 4661 |
{ |
{ |
| 4662 |
/* Drop this bracket_fallback. */ |
/* Drop this bracket_backtrack. */ |
| 4663 |
parent->top = fallback->prev; |
parent->top = backtrack->prev; |
| 4664 |
return bracketend(cc); |
return bracketend(cc); |
| 4665 |
} |
} |
| 4666 |
|
|
| 4672 |
has_alternatives = *cc == OP_ALT; |
has_alternatives = *cc == OP_ALT; |
| 4673 |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
| 4674 |
{ |
{ |
| 4675 |
has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE; |
has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE; |
| 4676 |
if (*hotpath == OP_NRREF) |
if (*trypath == OP_NRREF) |
| 4677 |
{ |
{ |
| 4678 |
stacksize = GET2(hotpath, 1); |
stacksize = GET2(trypath, 1); |
| 4679 |
if (common->currententry == NULL || stacksize == RREF_ANY) |
if (common->currententry == NULL || stacksize == RREF_ANY) |
| 4680 |
has_alternatives = FALSE; |
has_alternatives = FALSE; |
| 4681 |
else if (common->currententry->start == 0) |
else if (common->currententry->start == 0) |
| 4696 |
offset = GET2(ccbegin, 1 + LINK_SIZE); |
offset = GET2(ccbegin, 1 + LINK_SIZE); |
| 4697 |
localptr = OVECTOR_PRIV(offset); |
localptr = OVECTOR_PRIV(offset); |
| 4698 |
offset <<= 1; |
offset <<= 1; |
| 4699 |
FALLBACK_AS(bracket_fallback)->localptr = localptr; |
BACKTRACK_AS(bracket_backtrack)->localptr = localptr; |
| 4700 |
hotpath += IMM2_SIZE; |
trypath += IMM2_SIZE; |
| 4701 |
} |
} |
| 4702 |
else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) |
else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) |
| 4703 |
{ |
{ |
| 4704 |
/* Other brackets simply allocate the next entry. */ |
/* Other brackets simply allocate the next entry. */ |
| 4705 |
localptr = PRIV_DATA(ccbegin); |
localptr = PRIV_DATA(ccbegin); |
| 4706 |
SLJIT_ASSERT(localptr != 0); |
SLJIT_ASSERT(localptr != 0); |
| 4707 |
FALLBACK_AS(bracket_fallback)->localptr = localptr; |
BACKTRACK_AS(bracket_backtrack)->localptr = localptr; |
| 4708 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
| 4709 |
FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE); |
BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); |
| 4710 |
} |
} |
| 4711 |
|
|
| 4712 |
/* Instructions before the first alternative. */ |
/* Instructions before the first alternative. */ |
| 4731 |
|
|
| 4732 |
if (bra == OP_BRAMINZERO) |
if (bra == OP_BRAMINZERO) |
| 4733 |
{ |
{ |
| 4734 |
/* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */ |
/* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */ |
| 4735 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 4736 |
if (ket != OP_KETRMIN) |
if (ket != OP_KETRMIN) |
| 4737 |
{ |
{ |
| 4748 |
skip = JUMP(SLJIT_JUMP); |
skip = JUMP(SLJIT_JUMP); |
| 4749 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 4750 |
/* Checking zero-length iteration. */ |
/* Checking zero-length iteration. */ |
| 4751 |
if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0) |
if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
| 4752 |
{ |
{ |
| 4753 |
/* When we come from outside, localptr contains the previous STR_PTR. */ |
/* When we come from outside, localptr contains the previous STR_PTR. */ |
| 4754 |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4757 |
{ |
{ |
| 4758 |
/* Except when the whole stack frame must be saved. */ |
/* Except when the whole stack frame must be saved. */ |
| 4759 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4760 |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w)); |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w)); |
| 4761 |
} |
} |
| 4762 |
JUMPHERE(skip); |
JUMPHERE(skip); |
| 4763 |
} |
} |
| 4771 |
} |
} |
| 4772 |
|
|
| 4773 |
if (ket == OP_KETRMIN) |
if (ket == OP_KETRMIN) |
| 4774 |
FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); |
| 4775 |
|
|
| 4776 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
| 4777 |
{ |
{ |
| 4778 |
rmaxlabel = LABEL(); |
rmaxlabel = LABEL(); |
| 4779 |
if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) |
if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) |
| 4780 |
FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel; |
BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel; |
| 4781 |
} |
} |
| 4782 |
|
|
| 4783 |
/* Handling capturing brackets and alternatives. */ |
/* Handling capturing brackets and alternatives. */ |
| 4784 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
| 4785 |
{ |
{ |
| 4786 |
if (FALLBACK_AS(bracket_fallback)->u.framesize < 0) |
if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
| 4787 |
{ |
{ |
| 4788 |
/* Neither capturing brackets nor recursions are not found in the block. */ |
/* Neither capturing brackets nor recursions are not found in the block. */ |
| 4789 |
if (ket == OP_KETRMIN) |
if (ket == OP_KETRMIN) |
| 4807 |
{ |
{ |
| 4808 |
if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) |
if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) |
| 4809 |
{ |
{ |
| 4810 |
allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2); |
allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); |
| 4811 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4812 |
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1)); |
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1)); |
| 4813 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 4814 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); |
| 4815 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
| 4816 |
init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE); |
init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE); |
| 4817 |
} |
} |
| 4818 |
else |
else |
| 4819 |
{ |
{ |
| 4820 |
allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1); |
allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); |
| 4821 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4822 |
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize)); |
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize)); |
| 4823 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); |
| 4824 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
| 4825 |
init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE); |
init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE); |
| 4826 |
} |
} |
| 4827 |
} |
} |
| 4828 |
} |
} |
| 4856 |
/* Generating code for the first alternative. */ |
/* Generating code for the first alternative. */ |
| 4857 |
if (opcode == OP_COND || opcode == OP_SCOND) |
if (opcode == OP_COND || opcode == OP_SCOND) |
| 4858 |
{ |
{ |
| 4859 |
if (*hotpath == OP_CREF) |
if (*trypath == OP_CREF) |
| 4860 |
{ |
{ |
| 4861 |
SLJIT_ASSERT(has_alternatives); |
SLJIT_ASSERT(has_alternatives); |
| 4862 |
add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), |
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), |
| 4863 |
CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
| 4864 |
hotpath += 1 + IMM2_SIZE; |
trypath += 1 + IMM2_SIZE; |
| 4865 |
} |
} |
| 4866 |
else if (*hotpath == OP_NCREF) |
else if (*trypath == OP_NCREF) |
| 4867 |
{ |
{ |
| 4868 |
SLJIT_ASSERT(has_alternatives); |
SLJIT_ASSERT(has_alternatives); |
| 4869 |
stacksize = GET2(hotpath, 1); |
stacksize = GET2(trypath, 1); |
| 4870 |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
| 4871 |
|
|
| 4872 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
| 4877 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
| 4878 |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); |
| 4879 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
| 4880 |
add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); |
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); |
| 4881 |
|
|
| 4882 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 4883 |
hotpath += 1 + IMM2_SIZE; |
trypath += 1 + IMM2_SIZE; |
| 4884 |
} |
} |
| 4885 |
else if (*hotpath == OP_RREF || *hotpath == OP_NRREF) |
else if (*trypath == OP_RREF || *trypath == OP_NRREF) |
| 4886 |
{ |
{ |
| 4887 |
/* Never has other case. */ |
/* Never has other case. */ |
| 4888 |
FALLBACK_AS(bracket_fallback)->u.condfailed = NULL; |
BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; |
| 4889 |
|
|
| 4890 |
stacksize = GET2(hotpath, 1); |
stacksize = GET2(trypath, 1); |
| 4891 |
if (common->currententry == NULL) |
if (common->currententry == NULL) |
| 4892 |
stacksize = 0; |
stacksize = 0; |
| 4893 |
else if (stacksize == RREF_ANY) |
else if (stacksize == RREF_ANY) |
| 4897 |
else |
else |
| 4898 |
stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); |
stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); |
| 4899 |
|
|
| 4900 |
if (*hotpath == OP_RREF || stacksize || common->currententry == NULL) |
if (*trypath == OP_RREF || stacksize || common->currententry == NULL) |
| 4901 |
{ |
{ |
| 4902 |
SLJIT_ASSERT(!has_alternatives); |
SLJIT_ASSERT(!has_alternatives); |
| 4903 |
if (stacksize != 0) |
if (stacksize != 0) |
| 4904 |
hotpath += 1 + IMM2_SIZE; |
trypath += 1 + IMM2_SIZE; |
| 4905 |
else |
else |
| 4906 |
{ |
{ |
| 4907 |
if (*cc == OP_ALT) |
if (*cc == OP_ALT) |
| 4908 |
{ |
{ |
| 4909 |
hotpath = cc + 1 + LINK_SIZE; |
trypath = cc + 1 + LINK_SIZE; |
| 4910 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 4911 |
} |
} |
| 4912 |
else |
else |
| 4913 |
hotpath = cc; |
trypath = cc; |
| 4914 |
} |
} |
| 4915 |
} |
} |
| 4916 |
else |
else |
| 4917 |
{ |
{ |
| 4918 |
SLJIT_ASSERT(has_alternatives); |
SLJIT_ASSERT(has_alternatives); |
| 4919 |
|
|
| 4920 |
stacksize = GET2(hotpath, 1); |
stacksize = GET2(trypath, 1); |
| 4921 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
| 4922 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); |
| 4923 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
| 4927 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
| 4928 |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); |
| 4929 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
| 4930 |
add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); |
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); |
| 4931 |
hotpath += 1 + IMM2_SIZE; |
trypath += 1 + IMM2_SIZE; |
| 4932 |
} |
} |
| 4933 |
} |
} |
| 4934 |
else |
else |
| 4935 |
{ |
{ |
| 4936 |
SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT); |
SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT); |
| 4937 |
/* Similar code as PUSH_FALLBACK macro. */ |
/* Similar code as PUSH_BACKTRACK macro. */ |
| 4938 |
assert = sljit_alloc_memory(compiler, sizeof(assert_fallback)); |
assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); |
| 4939 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 4940 |
return NULL; |
return NULL; |
| 4941 |
memset(assert, 0, sizeof(assert_fallback)); |
memset(assert, 0, sizeof(assert_backtrack)); |
| 4942 |
assert->common.cc = hotpath; |
assert->common.cc = trypath; |
| 4943 |
FALLBACK_AS(bracket_fallback)->u.assert = assert; |
BACKTRACK_AS(bracket_backtrack)->u.assert = assert; |
| 4944 |
hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE); |
trypath = compile_assert_trypath(common, trypath, assert, TRUE); |
| 4945 |
} |
} |
| 4946 |
} |
} |
| 4947 |
|
|
| 4948 |
compile_hotpath(common, hotpath, cc, fallback); |
compile_trypath(common, trypath, cc, backtrack); |
| 4949 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 4950 |
return NULL; |
return NULL; |
| 4951 |
|
|
| 4952 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
| 4953 |
{ |
{ |
| 4954 |
if (FALLBACK_AS(bracket_fallback)->u.framesize < 0) |
if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
| 4955 |
{ |
{ |
| 4956 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4957 |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
| 4966 |
else |
else |
| 4967 |
{ |
{ |
| 4968 |
stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; |
stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; |
| 4969 |
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w)); |
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w)); |
| 4970 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
| 4971 |
{ |
{ |
| 4972 |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
| 5001 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
| 5002 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); |
| 5003 |
if (ket != OP_KETRMAX) |
if (ket != OP_KETRMAX) |
| 5004 |
FALLBACK_AS(bracket_fallback)->althotpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); |
| 5005 |
} |
} |
| 5006 |
|
|
| 5007 |
/* Must be after the hotpath label. */ |
/* Must be after the trypath label. */ |
| 5008 |
if (offset != 0) |
if (offset != 0) |
| 5009 |
{ |
{ |
| 5010 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 5017 |
if (opcode == OP_ONCE || opcode >= OP_SBRA) |
if (opcode == OP_ONCE || opcode >= OP_SBRA) |
| 5018 |
{ |
{ |
| 5019 |
if (has_alternatives) |
if (has_alternatives) |
| 5020 |
FALLBACK_AS(bracket_fallback)->althotpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); |
| 5021 |
/* Checking zero-length iteration. */ |
/* Checking zero-length iteration. */ |
| 5022 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
| 5023 |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); |
| 5027 |
} |
} |
| 5028 |
else |
else |
| 5029 |
JUMPTO(SLJIT_JUMP, rmaxlabel); |
JUMPTO(SLJIT_JUMP, rmaxlabel); |
| 5030 |
FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); |
| 5031 |
} |
} |
| 5032 |
|
|
| 5033 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 5034 |
FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL(); |
| 5035 |
|
|
| 5036 |
if (bra == OP_BRAMINZERO) |
if (bra == OP_BRAMINZERO) |
| 5037 |
{ |
{ |
| 5038 |
/* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */ |
/* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ |
| 5039 |
JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath); |
JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath); |
| 5040 |
if (braminzerojump != NULL) |
if (braminzerojump != NULL) |
| 5041 |
{ |
{ |
| 5042 |
JUMPHERE(braminzerojump); |
JUMPHERE(braminzerojump); |
| 5043 |
/* We need to release the end pointer to perform the |
/* We need to release the end pointer to perform the |
| 5044 |
fallback for the zero-length iteration. When |
backtrack for the zero-length iteration. When |
| 5045 |
framesize is < 0, OP_ONCE will do the release itself. */ |
framesize is < 0, OP_ONCE will do the release itself. */ |
| 5046 |
if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0) |
if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) |
| 5047 |
{ |
{ |
| 5048 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 5049 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
| 5051 |
else if (ket == OP_KETRMIN && opcode != OP_ONCE) |
else if (ket == OP_KETRMIN && opcode != OP_ONCE) |
| 5052 |
free_stack(common, 1); |
free_stack(common, 1); |
| 5053 |
} |
} |
| 5054 |
/* Continue to the normal fallback. */ |
/* Continue to the normal backtrack. */ |
| 5055 |
} |
} |
| 5056 |
|
|
| 5057 |
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) |
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) |
| 5064 |
return cc; |
return cc; |
| 5065 |
} |
} |
| 5066 |
|
|
| 5067 |
static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent) |
static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
| 5068 |
{ |
{ |
| 5069 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 5070 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 5071 |
pcre_uchar opcode; |
pcre_uchar opcode; |
| 5072 |
int localptr; |
int localptr; |
| 5073 |
int cbraprivptr = 0; |
int cbraprivptr = 0; |
| 5080 |
struct sljit_label *loop = NULL; |
struct sljit_label *loop = NULL; |
| 5081 |
struct jump_list *emptymatch = NULL; |
struct jump_list *emptymatch = NULL; |
| 5082 |
|
|
| 5083 |
PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL); |
PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL); |
| 5084 |
if (*cc == OP_BRAPOSZERO) |
if (*cc == OP_BRAPOSZERO) |
| 5085 |
{ |
{ |
| 5086 |
zero = TRUE; |
zero = TRUE; |
| 5090 |
opcode = *cc; |
opcode = *cc; |
| 5091 |
localptr = PRIV_DATA(cc); |
localptr = PRIV_DATA(cc); |
| 5092 |
SLJIT_ASSERT(localptr != 0); |
SLJIT_ASSERT(localptr != 0); |
| 5093 |
FALLBACK_AS(bracketpos_fallback)->localptr = localptr; |
BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr; |
| 5094 |
switch(opcode) |
switch(opcode) |
| 5095 |
{ |
{ |
| 5096 |
case OP_BRAPOS: |
case OP_BRAPOS: |
| 5112 |
} |
} |
| 5113 |
|
|
| 5114 |
framesize = get_framesize(common, cc, FALSE); |
framesize = get_framesize(common, cc, FALSE); |
| 5115 |
FALLBACK_AS(bracketpos_fallback)->framesize = framesize; |
BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; |
| 5116 |
if (framesize < 0) |
if (framesize < 0) |
| 5117 |
{ |
{ |
| 5118 |
stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; |
stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; |
| 5119 |
if (!zero) |
if (!zero) |
| 5120 |
stacksize++; |
stacksize++; |
| 5121 |
FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize; |
BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; |
| 5122 |
allocate_stack(common, stacksize); |
allocate_stack(common, stacksize); |
| 5123 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); |
| 5124 |
|
|
| 5142 |
stacksize++; |
stacksize++; |
| 5143 |
if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) |
if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) |
| 5144 |
stacksize++; |
stacksize++; |
| 5145 |
FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize; |
BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; |
| 5146 |
allocate_stack(common, stacksize); |
allocate_stack(common, stacksize); |
| 5147 |
|
|
| 5148 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 5169 |
loop = LABEL(); |
loop = LABEL(); |
| 5170 |
while (*cc != OP_KETRPOS) |
while (*cc != OP_KETRPOS) |
| 5171 |
{ |
{ |
| 5172 |
fallback->top = NULL; |
backtrack->top = NULL; |
| 5173 |
fallback->topfallbacks = NULL; |
backtrack->topbacktracks = NULL; |
| 5174 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 5175 |
|
|
| 5176 |
compile_hotpath(common, ccbegin, cc, fallback); |
compile_trypath(common, ccbegin, cc, backtrack); |
| 5177 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 5178 |
return NULL; |
return NULL; |
| 5179 |
|
|
| 5234 |
JUMPTO(SLJIT_JUMP, loop); |
JUMPTO(SLJIT_JUMP, loop); |
| 5235 |
flush_stubs(common); |
flush_stubs(common); |
| 5236 |
|
|
| 5237 |
compile_fallbackpath(common, fallback->top); |
compile_backtrackpath(common, backtrack->top); |
| 5238 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 5239 |
return NULL; |
return NULL; |
| 5240 |
set_jumps(fallback->topfallbacks, LABEL()); |
set_jumps(backtrack->topbacktracks, LABEL()); |
| 5241 |
|
|
| 5242 |
if (framesize < 0) |
if (framesize < 0) |
| 5243 |
{ |
{ |
| 5267 |
ccbegin = cc + 1 + LINK_SIZE; |
ccbegin = cc + 1 + LINK_SIZE; |
| 5268 |
} |
} |
| 5269 |
|
|
| 5270 |
fallback->topfallbacks = NULL; |
backtrack->topbacktracks = NULL; |
| 5271 |
if (!zero) |
if (!zero) |
| 5272 |
{ |
{ |
| 5273 |
if (framesize < 0) |
if (framesize < 0) |
| 5274 |
add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); |
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); |
| 5275 |
else /* TMP2 is set to [localptr] above. */ |
else /* TMP2 is set to [localptr] above. */ |
| 5276 |
add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); |
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); |
| 5277 |
} |
} |
| 5278 |
|
|
| 5279 |
/* None of them matched. */ |
/* None of them matched. */ |
| 5374 |
return cc; |
return cc; |
| 5375 |
} |
} |
| 5376 |
|
|
| 5377 |
static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent) |
static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
| 5378 |
{ |
{ |
| 5379 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 5380 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 5381 |
pcre_uchar opcode; |
pcre_uchar opcode; |
| 5382 |
pcre_uchar type; |
pcre_uchar type; |
| 5383 |
int arg1 = -1, arg2 = -1; |
int arg1 = -1, arg2 = -1; |
| 5386 |
struct sljit_jump *jump = NULL; |
struct sljit_jump *jump = NULL; |
| 5387 |
struct sljit_label *label; |
struct sljit_label *label; |
| 5388 |
|
|
| 5389 |
PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL); |
PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); |
| 5390 |
|
|
| 5391 |
cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); |
cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); |
| 5392 |
|
|
| 5413 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); |
| 5414 |
|
|
| 5415 |
label = LABEL(); |
label = LABEL(); |
| 5416 |
compile_char1_hotpath(common, type, cc, &fallback->topfallbacks); |
compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); |
| 5417 |
if (opcode == OP_UPTO || opcode == OP_CRRANGE) |
if (opcode == OP_UPTO || opcode == OP_CRRANGE) |
| 5418 |
{ |
{ |
| 5419 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); |
| 5437 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5438 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); |
| 5439 |
label = LABEL(); |
label = LABEL(); |
| 5440 |
compile_char1_hotpath(common, type, cc, &nomatch); |
compile_char1_trypath(common, type, cc, &nomatch); |
| 5441 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5442 |
if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) |
if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) |
| 5443 |
{ |
{ |
| 5453 |
} |
} |
| 5454 |
set_jumps(nomatch, LABEL()); |
set_jumps(nomatch, LABEL()); |
| 5455 |
if (opcode == OP_PLUS || opcode == OP_CRRANGE) |
if (opcode == OP_PLUS || opcode == OP_CRRANGE) |
| 5456 |
add_jump(compiler, &fallback->topfallbacks, |
add_jump(compiler, &backtrack->topbacktracks, |
| 5457 |
CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1)); |
CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1)); |
| 5458 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5459 |
} |
} |
| 5460 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); |
| 5461 |
break; |
break; |
| 5462 |
|
|
| 5463 |
case OP_MINSTAR: |
case OP_MINSTAR: |
| 5465 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
| 5466 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5467 |
if (opcode == OP_MINPLUS) |
if (opcode == OP_MINPLUS) |
| 5468 |
add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); |
| 5469 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); |
| 5470 |
break; |
break; |
| 5471 |
|
|
| 5472 |
case OP_MINUPTO: |
case OP_MINUPTO: |
| 5475 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5476 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); |
| 5477 |
if (opcode == OP_CRMINRANGE) |
if (opcode == OP_CRMINRANGE) |
| 5478 |
add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); |
| 5479 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); |
| 5480 |
break; |
break; |
| 5481 |
|
|
| 5482 |
case OP_QUERY: |
case OP_QUERY: |
| 5484 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
| 5485 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5486 |
if (opcode == OP_QUERY) |
if (opcode == OP_QUERY) |
| 5487 |
compile_char1_hotpath(common, type, cc, &fallback->topfallbacks); |
compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); |
| 5488 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); |
| 5489 |
break; |
break; |
| 5490 |
|
|
| 5491 |
case OP_EXACT: |
case OP_EXACT: |
| 5492 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); |
| 5493 |
label = LABEL(); |
label = LABEL(); |
| 5494 |
compile_char1_hotpath(common, type, cc, &fallback->topfallbacks); |
compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); |
| 5495 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); |
| 5496 |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
| 5497 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); |
| 5505 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); |
| 5506 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
| 5507 |
label = LABEL(); |
label = LABEL(); |
| 5508 |
compile_char1_hotpath(common, type, cc, &nomatch); |
compile_char1_trypath(common, type, cc, &nomatch); |
| 5509 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
| 5510 |
if (opcode != OP_POSUPTO) |
if (opcode != OP_POSUPTO) |
| 5511 |
{ |
{ |
| 5522 |
} |
} |
| 5523 |
set_jumps(nomatch, LABEL()); |
set_jumps(nomatch, LABEL()); |
| 5524 |
if (opcode == OP_POSPLUS) |
if (opcode == OP_POSPLUS) |
| 5525 |
add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); |
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); |
| 5526 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
| 5527 |
break; |
break; |
| 5528 |
|
|
| 5529 |
case OP_POSQUERY: |
case OP_POSQUERY: |
| 5530 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
| 5531 |
compile_char1_hotpath(common, type, cc, &nomatch); |
compile_char1_trypath(common, type, cc, &nomatch); |
| 5532 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); |
| 5533 |
set_jumps(nomatch, LABEL()); |
set_jumps(nomatch, LABEL()); |
| 5534 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
| 5543 |
return end; |
return end; |
| 5544 |
} |
} |
| 5545 |
|
|
| 5546 |
static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent) |
static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
| 5547 |
{ |
{ |
| 5548 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 5549 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 5550 |
|
|
| 5551 |
PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL); |
PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); |
| 5552 |
|
|
| 5553 |
if (*cc == OP_FAIL) |
if (*cc == OP_FAIL) |
| 5554 |
{ |
{ |
| 5555 |
add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); |
| 5556 |
return cc + 1; |
return cc + 1; |
| 5557 |
} |
} |
| 5558 |
|
|
| 5572 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel); |
| 5573 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
| 5574 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); |
| 5575 |
add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 5576 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); |
| 5577 |
if (common->acceptlabel == NULL) |
if (common->acceptlabel == NULL) |
| 5578 |
add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 5583 |
add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); |
add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); |
| 5584 |
else |
else |
| 5585 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel); |
| 5586 |
add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); |
| 5587 |
return cc + 1; |
return cc + 1; |
| 5588 |
} |
} |
| 5589 |
|
|
| 5590 |
static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc) |
static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc) |
| 5591 |
{ |
{ |
| 5592 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 5593 |
int offset = GET2(cc, 1); |
int offset = GET2(cc, 1); |
| 5603 |
return cc + 1 + IMM2_SIZE; |
return cc + 1 + IMM2_SIZE; |
| 5604 |
} |
} |
| 5605 |
|
|
| 5606 |
static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent) |
static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) |
| 5607 |
{ |
{ |
| 5608 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 5609 |
fallback_common *fallback; |
backtrack_common *backtrack; |
| 5610 |
|
|
| 5611 |
while (cc < ccend) |
while (cc < ccend) |
| 5612 |
{ |
{ |
| 5642 |
case OP_NOT: |
case OP_NOT: |
| 5643 |
case OP_NOTI: |
case OP_NOTI: |
| 5644 |
case OP_REVERSE: |
case OP_REVERSE: |
| 5645 |
cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); |
| 5646 |
break; |
break; |
| 5647 |
|
|
| 5648 |
case OP_SET_SOM: |
case OP_SET_SOM: |
| 5649 |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
| 5650 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
| 5651 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
| 5652 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); |
| 5657 |
case OP_CHAR: |
case OP_CHAR: |
| 5658 |
case OP_CHARI: |
case OP_CHARI: |
| 5659 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
| 5660 |
cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); |
| 5661 |
else |
else |
| 5662 |
cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); |
| 5663 |
break; |
break; |
| 5664 |
|
|
| 5665 |
case OP_STAR: |
case OP_STAR: |
| 5727 |
case OP_TYPEPOSPLUS: |
case OP_TYPEPOSPLUS: |
| 5728 |
case OP_TYPEPOSQUERY: |
case OP_TYPEPOSQUERY: |
| 5729 |
case OP_TYPEPOSUPTO: |
case OP_TYPEPOSUPTO: |
| 5730 |
cc = compile_iterator_hotpath(common, cc, parent); |
cc = compile_iterator_trypath(common, cc, parent); |
| 5731 |
break; |
break; |
| 5732 |
|
|
| 5733 |
case OP_CLASS: |
case OP_CLASS: |
| 5734 |
case OP_NCLASS: |
case OP_NCLASS: |
| 5735 |
if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) |
if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) |
| 5736 |
cc = compile_iterator_hotpath(common, cc, parent); |
cc = compile_iterator_trypath(common, cc, parent); |
| 5737 |
else |
else |
| 5738 |
cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); |
| 5739 |
break; |
break; |
| 5740 |
|
|
| 5741 |
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 |
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 |
| 5742 |
case OP_XCLASS: |
case OP_XCLASS: |
| 5743 |
if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) |
if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) |
| 5744 |
cc = compile_iterator_hotpath(common, cc, parent); |
cc = compile_iterator_trypath(common, cc, parent); |
| 5745 |
else |
else |
| 5746 |
cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); |
| 5747 |
break; |
break; |
| 5748 |
#endif |
#endif |
| 5749 |
|
|
| 5750 |
case OP_REF: |
case OP_REF: |
| 5751 |
case OP_REFI: |
case OP_REFI: |
| 5752 |
if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) |
if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) |
| 5753 |
cc = compile_ref_iterator_hotpath(common, cc, parent); |
cc = compile_ref_iterator_trypath(common, cc, parent); |
| 5754 |
else |
else |
| 5755 |
cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE); |
cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); |
| 5756 |
break; |
break; |
| 5757 |
|
|
| 5758 |
case OP_RECURSE: |
case OP_RECURSE: |
| 5759 |
cc = compile_recurse_hotpath(common, cc, parent); |
cc = compile_recurse_trypath(common, cc, parent); |
| 5760 |
break; |
break; |
| 5761 |
|
|
| 5762 |
case OP_ASSERT: |
case OP_ASSERT: |
| 5763 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
| 5764 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
| 5765 |
case OP_ASSERTBACK_NOT: |
case OP_ASSERTBACK_NOT: |
| 5766 |
PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); |
| 5767 |
cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE); |
cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); |
| 5768 |
break; |
break; |
| 5769 |
|
|
| 5770 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
| 5771 |
PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc); |
| 5772 |
cc = bracketend(cc + 1); |
cc = bracketend(cc + 1); |
| 5773 |
if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) |
if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN) |
| 5774 |
{ |
{ |
| 5781 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 5782 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); |
| 5783 |
} |
} |
| 5784 |
FALLBACK_AS(braminzero_fallback)->hotpath = LABEL(); |
BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL(); |
| 5785 |
if (cc[1] > OP_ASSERTBACK_NOT) |
if (cc[1] > OP_ASSERTBACK_NOT) |
| 5786 |
decrease_call_count(common); |
decrease_call_count(common); |
| 5787 |
break; |
break; |
| 5794 |
case OP_SBRA: |
case OP_SBRA: |
| 5795 |
case OP_SCBRA: |
case OP_SCBRA: |
| 5796 |
case OP_SCOND: |
case OP_SCOND: |
| 5797 |
cc = compile_bracket_hotpath(common, cc, parent); |
cc = compile_bracket_trypath(common, cc, parent); |
| 5798 |
break; |
break; |
| 5799 |
|
|
| 5800 |
case OP_BRAZERO: |
case OP_BRAZERO: |
| 5801 |
if (cc[1] > OP_ASSERTBACK_NOT) |
if (cc[1] > OP_ASSERTBACK_NOT) |
| 5802 |
cc = compile_bracket_hotpath(common, cc, parent); |
cc = compile_bracket_trypath(common, cc, parent); |
| 5803 |
else |
else |
| 5804 |
{ |
{ |
| 5805 |
PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); |
| 5806 |
cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE); |
cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); |
| 5807 |
} |
} |
| 5808 |
break; |
break; |
| 5809 |
|
|
| 5812 |
case OP_SBRAPOS: |
case OP_SBRAPOS: |
| 5813 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
| 5814 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
| 5815 |
cc = compile_bracketpos_hotpath(common, cc, parent); |
cc = compile_bracketpos_trypath(common, cc, parent); |
| 5816 |
break; |
break; |
| 5817 |
|
|
| 5818 |
case OP_MARK: |
case OP_MARK: |
| 5819 |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
| 5820 |
SLJIT_ASSERT(common->mark_ptr != 0); |
SLJIT_ASSERT(common->mark_ptr != 0); |
| 5821 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
| 5822 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
| 5829 |
break; |
break; |
| 5830 |
|
|
| 5831 |
case OP_COMMIT: |
case OP_COMMIT: |
| 5832 |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
| 5833 |
cc += 1; |
cc += 1; |
| 5834 |
break; |
break; |
| 5835 |
|
|
| 5836 |
case OP_FAIL: |
case OP_FAIL: |
| 5837 |
case OP_ACCEPT: |
case OP_ACCEPT: |
| 5838 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
| 5839 |
cc = compile_fail_accept_hotpath(common, cc, parent); |
cc = compile_fail_accept_trypath(common, cc, parent); |
| 5840 |
break; |
break; |
| 5841 |
|
|
| 5842 |
case OP_CLOSE: |
case OP_CLOSE: |
| 5843 |
cc = compile_close_hotpath(common, cc); |
cc = compile_close_trypath(common, cc); |
| 5844 |
break; |
break; |
| 5845 |
|
|
| 5846 |
case OP_SKIPZERO: |
case OP_SKIPZERO: |
| 5857 |
SLJIT_ASSERT(cc == ccend); |
SLJIT_ASSERT(cc == ccend); |
| 5858 |
} |
} |
| 5859 |
|
|
| 5860 |
#undef PUSH_FALLBACK |
#undef PUSH_BACKTRACK |
| 5861 |
#undef PUSH_FALLBACK_NOVALUE |
#undef PUSH_BACKTRACK_NOVALUE |
| 5862 |
#undef FALLBACK_AS |
#undef BACKTRACK_AS |
| 5863 |
|
|
| 5864 |
#define COMPILE_FALLBACKPATH(current) \ |
#define COMPILE_BACKTRACKPATH(current) \ |
| 5865 |
do \ |
do \ |
| 5866 |
{ \ |
{ \ |
| 5867 |
compile_fallbackpath(common, (current)); \ |
compile_backtrackpath(common, (current)); \ |
| 5868 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ |
| 5869 |
return; \ |
return; \ |
| 5870 |
} \ |
} \ |
| 5872 |
|
|
| 5873 |
#define CURRENT_AS(type) ((type *)current) |
#define CURRENT_AS(type) ((type *)current) |
| 5874 |
|
|
| 5875 |
static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 5876 |
{ |
{ |
| 5877 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 5878 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
| 5892 |
case OP_CRRANGE: |
case OP_CRRANGE: |
| 5893 |
if (type == OP_ANYNL || type == OP_EXTUNI) |
if (type == OP_ANYNL || type == OP_EXTUNI) |
| 5894 |
{ |
{ |
| 5895 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5896 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5897 |
free_stack(common, 1); |
free_stack(common, 1); |
| 5898 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); |
| 5899 |
} |
} |
| 5900 |
else |
else |
| 5901 |
{ |
{ |
| 5908 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5909 |
skip_char_back(common); |
skip_char_back(common); |
| 5910 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5911 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); |
| 5912 |
if (opcode == OP_PLUS || opcode == OP_CRRANGE) |
if (opcode == OP_PLUS || opcode == OP_CRRANGE) |
| 5913 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5914 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 5915 |
free_stack(common, 2); |
free_stack(common, 2); |
| 5916 |
} |
} |
| 5921 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5922 |
if (opcode == OP_MINPLUS) |
if (opcode == OP_MINPLUS) |
| 5923 |
{ |
{ |
| 5924 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5925 |
current->topfallbacks = NULL; |
current->topbacktracks = NULL; |
| 5926 |
} |
} |
| 5927 |
compile_char1_hotpath(common, type, cc, ¤t->topfallbacks); |
compile_char1_trypath(common, type, cc, ¤t->topbacktracks); |
| 5928 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5929 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); |
| 5930 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5931 |
free_stack(common, 1); |
free_stack(common, 1); |
| 5932 |
break; |
break; |
| 5933 |
|
|
| 5935 |
case OP_CRMINRANGE: |
case OP_CRMINRANGE: |
| 5936 |
if (opcode == OP_CRMINRANGE) |
if (opcode == OP_CRMINRANGE) |
| 5937 |
{ |
{ |
| 5938 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5939 |
current->topfallbacks = NULL; |
current->topbacktracks = NULL; |
| 5940 |
label = LABEL(); |
label = LABEL(); |
| 5941 |
} |
} |
| 5942 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5943 |
compile_char1_hotpath(common, type, cc, ¤t->topfallbacks); |
compile_char1_trypath(common, type, cc, ¤t->topbacktracks); |
| 5944 |
|
|
| 5945 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 5946 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 5951 |
CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); |
CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); |
| 5952 |
|
|
| 5953 |
if (opcode == OP_CRMINRANGE && arg1 == 0) |
if (opcode == OP_CRMINRANGE && arg1 == 0) |
| 5954 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); |
| 5955 |
else |
else |
| 5956 |
CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_fallback)->hotpath); |
CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath); |
| 5957 |
|
|
| 5958 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5959 |
free_stack(common, 2); |
free_stack(common, 2); |
| 5960 |
break; |
break; |
| 5961 |
|
|
| 5962 |
case OP_QUERY: |
case OP_QUERY: |
| 5963 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5964 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 5965 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); |
| 5966 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
| 5967 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5968 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5969 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 5970 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); |
| 5971 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 5972 |
free_stack(common, 1); |
free_stack(common, 1); |
| 5973 |
break; |
break; |
| 5976 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5977 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 5978 |
jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
| 5979 |
compile_char1_hotpath(common, type, cc, ¤t->topfallbacks); |
compile_char1_trypath(common, type, cc, ¤t->topbacktracks); |
| 5980 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); |
| 5981 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5982 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 5983 |
free_stack(common, 1); |
free_stack(common, 1); |
| 5984 |
break; |
break; |
| 5985 |
|
|
| 5986 |
case OP_EXACT: |
case OP_EXACT: |
| 5987 |
case OP_POSPLUS: |
case OP_POSPLUS: |
| 5988 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 5989 |
break; |
break; |
| 5990 |
|
|
| 5991 |
case OP_POSSTAR: |
case OP_POSSTAR: |
| 5999 |
} |
} |
| 6000 |
} |
} |
| 6001 |
|
|
| 6002 |
static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6003 |
{ |
{ |
| 6004 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 6005 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
| 6008 |
type = cc[1 + IMM2_SIZE]; |
type = cc[1 + IMM2_SIZE]; |
| 6009 |
if ((type & 0x1) == 0) |
if ((type & 0x1) == 0) |
| 6010 |
{ |
{ |
| 6011 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6012 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6013 |
free_stack(common, 1); |
free_stack(common, 1); |
| 6014 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); |
| 6015 |
return; |
return; |
| 6016 |
} |
} |
| 6017 |
|
|
| 6018 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6019 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); |
| 6020 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6021 |
free_stack(common, 2); |
free_stack(common, 2); |
| 6022 |
} |
} |
| 6023 |
|
|
| 6024 |
static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6025 |
{ |
{ |
| 6026 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 6027 |
|
|
| 6028 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6029 |
|
|
| 6030 |
if (common->has_set_som && common->mark_ptr != 0) |
if (common->has_set_som && common->mark_ptr != 0) |
| 6031 |
{ |
{ |
| 6043 |
} |
} |
| 6044 |
} |
} |
| 6045 |
|
|
| 6046 |
static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6047 |
{ |
{ |
| 6048 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 6049 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
| 6059 |
|
|
| 6060 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 6061 |
{ |
{ |
| 6062 |
SLJIT_ASSERT(current->topfallbacks == NULL); |
SLJIT_ASSERT(current->topbacktracks == NULL); |
| 6063 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6064 |
} |
} |
| 6065 |
|
|
| 6066 |
if (CURRENT_AS(assert_fallback)->framesize < 0) |
if (CURRENT_AS(assert_backtrack)->framesize < 0) |
| 6067 |
{ |
{ |
| 6068 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6069 |
|
|
| 6070 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 6071 |
{ |
{ |
| 6072 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 6073 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); |
| 6074 |
free_stack(common, 1); |
free_stack(common, 1); |
| 6075 |
} |
} |
| 6076 |
return; |
return; |
| 6081 |
if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) |
if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) |
| 6082 |
{ |
{ |
| 6083 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 6084 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); |
| 6085 |
free_stack(common, 1); |
free_stack(common, 1); |
| 6086 |
return; |
return; |
| 6087 |
} |
} |
| 6091 |
|
|
| 6092 |
if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) |
if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) |
| 6093 |
{ |
{ |
| 6094 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr); |
| 6095 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
| 6096 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w)); |
| 6097 |
|
|
| 6098 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6099 |
} |
} |
| 6100 |
else |
else |
| 6101 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6102 |
|
|
| 6103 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 6104 |
{ |
{ |
| 6105 |
/* We know there is enough place on the stack. */ |
/* We know there is enough place on the stack. */ |
| 6106 |
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); |
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); |
| 6107 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
| 6108 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath); |
| 6109 |
JUMPHERE(brajump); |
JUMPHERE(brajump); |
| 6110 |
} |
} |
| 6111 |
} |
} |
| 6112 |
|
|
| 6113 |
static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6114 |
{ |
{ |
| 6115 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 6116 |
int opcode; |
int opcode; |
| 6117 |
int offset = 0; |
int offset = 0; |
| 6118 |
int localptr = CURRENT_AS(bracket_fallback)->localptr; |
int localptr = CURRENT_AS(bracket_backtrack)->localptr; |
| 6119 |
int stacksize; |
int stacksize; |
| 6120 |
int count; |
int count; |
| 6121 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
| 6125 |
jump_list *jumplistitem = NULL; |
jump_list *jumplistitem = NULL; |
| 6126 |
pcre_uchar bra = OP_BRA; |
pcre_uchar bra = OP_BRA; |
| 6127 |
pcre_uchar ket; |
pcre_uchar ket; |
| 6128 |
assert_fallback *assert; |
assert_backtrack *assert; |
| 6129 |
BOOL has_alternatives; |
BOOL has_alternatives; |
| 6130 |
struct sljit_jump *brazero = NULL; |
struct sljit_jump *brazero = NULL; |
| 6131 |
struct sljit_jump *once = NULL; |
struct sljit_jump *once = NULL; |
| 6144 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 6145 |
has_alternatives = *cc == OP_ALT; |
has_alternatives = *cc == OP_ALT; |
| 6146 |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
| 6147 |
has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL; |
has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL; |
| 6148 |
if (opcode == OP_CBRA || opcode == OP_SCBRA) |
if (opcode == OP_CBRA || opcode == OP_SCBRA) |
| 6149 |
offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; |
offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1; |
| 6150 |
if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) |
if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) |
| 6171 |
if (opcode >= OP_SBRA || opcode == OP_ONCE) |
if (opcode >= OP_SBRA || opcode == OP_ONCE) |
| 6172 |
{ |
{ |
| 6173 |
/* Checking zero-length iteration. */ |
/* Checking zero-length iteration. */ |
| 6174 |
if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0) |
if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) |
| 6175 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_fallback)->recursivehotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath); |
| 6176 |
else |
else |
| 6177 |
{ |
{ |
| 6178 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 6179 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_fallback)->recursivehotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath); |
| 6180 |
} |
} |
| 6181 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
| 6182 |
free_stack(common, 1); |
free_stack(common, 1); |
| 6183 |
} |
} |
| 6184 |
else |
else |
| 6185 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath); |
| 6186 |
} |
} |
| 6187 |
rminlabel = LABEL(); |
rminlabel = LABEL(); |
| 6188 |
} |
} |
| 6195 |
|
|
| 6196 |
if (SLJIT_UNLIKELY(opcode == OP_ONCE)) |
if (SLJIT_UNLIKELY(opcode == OP_ONCE)) |
| 6197 |
{ |
{ |
| 6198 |
if (CURRENT_AS(bracket_fallback)->u.framesize >= 0) |
if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
| 6199 |
{ |
{ |
| 6200 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 6201 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
| 6250 |
cc = ccbegin + GET(ccbegin, 1); |
cc = ccbegin + GET(ccbegin, 1); |
| 6251 |
} |
} |
| 6252 |
|
|
| 6253 |
COMPILE_FALLBACKPATH(current->top); |
COMPILE_BACKTRACKPATH(current->top); |
| 6254 |
if (current->topfallbacks) |
if (current->topbacktracks) |
| 6255 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6256 |
|
|
| 6257 |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
| 6258 |
{ |
{ |
| 6260 |
if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) |
if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) |
| 6261 |
{ |
{ |
| 6262 |
SLJIT_ASSERT(has_alternatives); |
SLJIT_ASSERT(has_alternatives); |
| 6263 |
assert = CURRENT_AS(bracket_fallback)->u.assert; |
assert = CURRENT_AS(bracket_backtrack)->u.assert; |
| 6264 |
if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) |
if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) |
| 6265 |
{ |
{ |
| 6266 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); |
| 6268 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); |
| 6269 |
} |
} |
| 6270 |
cond = JUMP(SLJIT_JUMP); |
cond = JUMP(SLJIT_JUMP); |
| 6271 |
set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL()); |
set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); |
| 6272 |
} |
} |
| 6273 |
else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL) |
else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL) |
| 6274 |
{ |
{ |
| 6275 |
SLJIT_ASSERT(has_alternatives); |
SLJIT_ASSERT(has_alternatives); |
| 6276 |
cond = JUMP(SLJIT_JUMP); |
cond = JUMP(SLJIT_JUMP); |
| 6277 |
set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL()); |
set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL()); |
| 6278 |
} |
} |
| 6279 |
else |
else |
| 6280 |
SLJIT_ASSERT(!has_alternatives); |
SLJIT_ASSERT(!has_alternatives); |
| 6286 |
do |
do |
| 6287 |
{ |
{ |
| 6288 |
current->top = NULL; |
current->top = NULL; |
| 6289 |
current->topfallbacks = NULL; |
current->topbacktracks = NULL; |
| 6290 |
current->nextfallbacks = NULL; |
current->nextbacktracks = NULL; |
| 6291 |
if (*cc == OP_ALT) |
if (*cc == OP_ALT) |
| 6292 |
{ |
{ |
| 6293 |
ccprev = cc + 1 + LINK_SIZE; |
ccprev = cc + 1 + LINK_SIZE; |
| 6299 |
else |
else |
| 6300 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6301 |
} |
} |
| 6302 |
compile_hotpath(common, ccprev, cc, current); |
compile_trypath(common, ccprev, cc, current); |
| 6303 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6304 |
return; |
return; |
| 6305 |
} |
} |
| 6306 |
|
|
| 6307 |
/* Instructions after the current alternative is succesfully matched. */ |
/* Instructions after the current alternative is succesfully matched. */ |
| 6308 |
/* There is a similar code in compile_bracket_hotpath. */ |
/* There is a similar code in compile_bracket_trypath. */ |
| 6309 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
| 6310 |
{ |
{ |
| 6311 |
if (CURRENT_AS(bracket_fallback)->u.framesize < 0) |
if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) |
| 6312 |
{ |
{ |
| 6313 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 6314 |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
| 6322 |
} |
} |
| 6323 |
else |
else |
| 6324 |
{ |
{ |
| 6325 |
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w)); |
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w)); |
| 6326 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
| 6327 |
{ |
{ |
| 6328 |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
| 6338 |
stacksize++; |
stacksize++; |
| 6339 |
|
|
| 6340 |
if (stacksize > 0) { |
if (stacksize > 0) { |
| 6341 |
if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0) |
if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
| 6342 |
allocate_stack(common, stacksize); |
allocate_stack(common, stacksize); |
| 6343 |
else |
else |
| 6344 |
{ |
{ |
| 6368 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); |
| 6369 |
} |
} |
| 6370 |
|
|
| 6371 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath); |
| 6372 |
|
|
| 6373 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
| 6374 |
{ |
{ |
| 6377 |
jumplist = jumplist->next; |
jumplist = jumplist->next; |
| 6378 |
} |
} |
| 6379 |
|
|
| 6380 |
COMPILE_FALLBACKPATH(current->top); |
COMPILE_BACKTRACKPATH(current->top); |
| 6381 |
if (current->topfallbacks) |
if (current->topbacktracks) |
| 6382 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6383 |
SLJIT_ASSERT(!current->nextfallbacks); |
SLJIT_ASSERT(!current->nextbacktracks); |
| 6384 |
} |
} |
| 6385 |
while (*cc == OP_ALT); |
while (*cc == OP_ALT); |
| 6386 |
SLJIT_ASSERT(!jumplist); |
SLJIT_ASSERT(!jumplist); |
| 6388 |
if (cond != NULL) |
if (cond != NULL) |
| 6389 |
{ |
{ |
| 6390 |
SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); |
SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND); |
| 6391 |
assert = CURRENT_AS(bracket_fallback)->u.assert; |
assert = CURRENT_AS(bracket_backtrack)->u.assert; |
| 6392 |
if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) |
if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) |
| 6393 |
|
|
| 6394 |
{ |
{ |
| 6422 |
else if (opcode == OP_ONCE) |
else if (opcode == OP_ONCE) |
| 6423 |
{ |
{ |
| 6424 |
cc = ccbegin + GET(ccbegin, 1); |
cc = ccbegin + GET(ccbegin, 1); |
| 6425 |
if (CURRENT_AS(bracket_fallback)->u.framesize >= 0) |
if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
| 6426 |
{ |
{ |
| 6427 |
/* Reset head and drop saved frame. */ |
/* Reset head and drop saved frame. */ |
| 6428 |
stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; |
stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; |
| 6429 |
free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize); |
free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize); |
| 6430 |
} |
} |
| 6431 |
else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) |
else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) |
| 6432 |
{ |
{ |
| 6436 |
|
|
| 6437 |
JUMPHERE(once); |
JUMPHERE(once); |
| 6438 |
/* Restore previous localptr */ |
/* Restore previous localptr */ |
| 6439 |
if (CURRENT_AS(bracket_fallback)->u.framesize >= 0) |
if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
| 6440 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_fallback)->u.framesize * sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w)); |
| 6441 |
else if (ket == OP_KETRMIN) |
else if (ket == OP_KETRMIN) |
| 6442 |
{ |
{ |
| 6443 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 6450 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
| 6451 |
{ |
{ |
| 6452 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6453 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath); |
| 6454 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
| 6455 |
{ |
{ |
| 6456 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 6457 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); |
| 6458 |
JUMPHERE(brazero); |
JUMPHERE(brazero); |
| 6459 |
} |
} |
| 6460 |
free_stack(common, 1); |
free_stack(common, 1); |
| 6463 |
{ |
{ |
| 6464 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6465 |
|
|
| 6466 |
/* OP_ONCE removes everything in case of a fallback, so we don't |
/* OP_ONCE removes everything in case of a backtrack, so we don't |
| 6467 |
need to explicitly release the STR_PTR. The extra release would |
need to explicitly release the STR_PTR. The extra release would |
| 6468 |
affect badly the free_stack(2) above. */ |
affect badly the free_stack(2) above. */ |
| 6469 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
| 6477 |
else if (bra == OP_BRAZERO) |
else if (bra == OP_BRAZERO) |
| 6478 |
{ |
{ |
| 6479 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6480 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); |
| 6481 |
JUMPHERE(brazero); |
JUMPHERE(brazero); |
| 6482 |
} |
} |
| 6483 |
} |
} |
| 6484 |
|
|
| 6485 |
static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6486 |
{ |
{ |
| 6487 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 6488 |
int offset; |
int offset; |
| 6489 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 6490 |
|
|
| 6491 |
if (CURRENT_AS(bracketpos_fallback)->framesize < 0) |
if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) |
| 6492 |
{ |
{ |
| 6493 |
if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) |
if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) |
| 6494 |
{ |
{ |
| 6498 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 6499 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); |
| 6500 |
} |
} |
| 6501 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6502 |
free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); |
free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); |
| 6503 |
return; |
return; |
| 6504 |
} |
} |
| 6505 |
|
|
| 6506 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr); |
| 6507 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
| 6508 |
|
|
| 6509 |
if (current->topfallbacks) |
if (current->topbacktracks) |
| 6510 |
{ |
{ |
| 6511 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
| 6512 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6513 |
/* Drop the stack frame. */ |
/* Drop the stack frame. */ |
| 6514 |
free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); |
free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); |
| 6515 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 6516 |
} |
} |
| 6517 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w)); |
| 6518 |
} |
} |
| 6519 |
|
|
| 6520 |
static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6521 |
{ |
{ |
| 6522 |
assert_fallback fallback; |
assert_backtrack backtrack; |
| 6523 |
|
|
| 6524 |
current->top = NULL; |
current->top = NULL; |
| 6525 |
current->topfallbacks = NULL; |
current->topbacktracks = NULL; |
| 6526 |
current->nextfallbacks = NULL; |
current->nextbacktracks = NULL; |
| 6527 |
if (current->cc[1] > OP_ASSERTBACK_NOT) |
if (current->cc[1] > OP_ASSERTBACK_NOT) |
| 6528 |
{ |
{ |
| 6529 |
/* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */ |
/* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */ |
| 6530 |
compile_bracket_hotpath(common, current->cc, current); |
compile_bracket_trypath(common, current->cc, current); |
| 6531 |
compile_bracket_fallbackpath(common, current->top); |
compile_bracket_backtrackpath(common, current->top); |
| 6532 |
} |
} |
| 6533 |
else |
else |
| 6534 |
{ |
{ |
| 6535 |
memset(&fallback, 0, sizeof(fallback)); |
memset(&backtrack, 0, sizeof(backtrack)); |
| 6536 |
fallback.common.cc = current->cc; |
backtrack.common.cc = current->cc; |
| 6537 |
fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath; |
backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath; |
| 6538 |
/* Manual call of compile_assert_hotpath. */ |
/* Manual call of compile_assert_trypath. */ |
| 6539 |
compile_assert_hotpath(common, current->cc, &fallback, FALSE); |
compile_assert_trypath(common, current->cc, &backtrack, FALSE); |
| 6540 |
} |
} |
| 6541 |
SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks); |
SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); |
| 6542 |
} |
} |
| 6543 |
|
|
| 6544 |
static void compile_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current) |
| 6545 |
{ |
{ |
| 6546 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 6547 |
|
|
| 6548 |
while (current) |
while (current) |
| 6549 |
{ |
{ |
| 6550 |
if (current->nextfallbacks != NULL) |
if (current->nextbacktracks != NULL) |
| 6551 |
set_jumps(current->nextfallbacks, LABEL()); |
set_jumps(current->nextbacktracks, LABEL()); |
| 6552 |
switch(*current->cc) |
switch(*current->cc) |
| 6553 |
{ |
{ |
| 6554 |
case OP_SET_SOM: |
case OP_SET_SOM: |
| 6627 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
| 6628 |
case OP_XCLASS: |
case OP_XCLASS: |
| 6629 |
#endif |
#endif |
| 6630 |
compile_iterator_fallbackpath(common, current); |
compile_iterator_backtrackpath(common, current); |
| 6631 |
break; |
break; |
| 6632 |
|
|
| 6633 |
case OP_REF: |
case OP_REF: |
| 6634 |
case OP_REFI: |
case OP_REFI: |
| 6635 |
compile_ref_iterator_fallbackpath(common, current); |
compile_ref_iterator_backtrackpath(common, current); |
| 6636 |
break; |
break; |
| 6637 |
|
|
| 6638 |
case OP_RECURSE: |
case OP_RECURSE: |
| 6639 |
compile_recurse_fallbackpath(common, current); |
compile_recurse_backtrackpath(common, current); |
| 6640 |
break; |
break; |
| 6641 |
|
|
| 6642 |
case OP_ASSERT: |
case OP_ASSERT: |
| 6643 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
| 6644 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
| 6645 |
case OP_ASSERTBACK_NOT: |
case OP_ASSERTBACK_NOT: |
| 6646 |
compile_assert_fallbackpath(common, current); |
compile_assert_backtrackpath(common, current); |
| 6647 |
break; |
break; |
| 6648 |
|
|
| 6649 |
case OP_ONCE: |
case OP_ONCE: |
| 6654 |
case OP_SBRA: |
case OP_SBRA: |
| 6655 |
case OP_SCBRA: |
case OP_SCBRA: |
| 6656 |
case OP_SCOND: |
case OP_SCOND: |
| 6657 |
compile_bracket_fallbackpath(common, current); |
compile_bracket_backtrackpath(common, current); |
| 6658 |
break; |
break; |
| 6659 |
|
|
| 6660 |
case OP_BRAZERO: |
case OP_BRAZERO: |
| 6661 |
if (current->cc[1] > OP_ASSERTBACK_NOT) |
if (current->cc[1] > OP_ASSERTBACK_NOT) |
| 6662 |
compile_bracket_fallbackpath(common, current); |
compile_bracket_backtrackpath(common, current); |
| 6663 |
else |
else |
| 6664 |
compile_assert_fallbackpath(common, current); |
compile_assert_backtrackpath(common, current); |
| 6665 |
break; |
break; |
| 6666 |
|
|
| 6667 |
case OP_BRAPOS: |
case OP_BRAPOS: |
| 6669 |
case OP_SBRAPOS: |
case OP_SBRAPOS: |
| 6670 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
| 6671 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
| 6672 |
compile_bracketpos_fallbackpath(common, current); |
compile_bracketpos_backtrackpath(common, current); |
| 6673 |
break; |
break; |
| 6674 |
|
|
| 6675 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
| 6676 |
compile_braminzero_fallbackpath(common, current); |
compile_braminzero_backtrackpath(common, current); |
| 6677 |
break; |
break; |
| 6678 |
|
|
| 6679 |
case OP_MARK: |
case OP_MARK: |
| 6693 |
case OP_FAIL: |
case OP_FAIL: |
| 6694 |
case OP_ACCEPT: |
case OP_ACCEPT: |
| 6695 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
| 6696 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
| 6697 |
break; |
break; |
| 6698 |
|
|
| 6699 |
default: |
default: |
| 6714 |
int framesize = get_framesize(common, cc, TRUE); |
int framesize = get_framesize(common, cc, TRUE); |
| 6715 |
int alternativesize; |
int alternativesize; |
| 6716 |
BOOL needsframe; |
BOOL needsframe; |
| 6717 |
fallback_common altfallback; |
backtrack_common altbacktrack; |
| 6718 |
struct sljit_label *save_leavelabel = common->leavelabel; |
struct sljit_label *save_leavelabel = common->leavelabel; |
| 6719 |
jump_list *save_leave = common->leave; |
jump_list *save_leave = common->leave; |
| 6720 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 6740 |
if (alternativesize > 0) |
if (alternativesize > 0) |
| 6741 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 6742 |
|
|
| 6743 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altbacktrack, 0, sizeof(backtrack_common)); |
| 6744 |
common->leavelabel = NULL; |
common->leavelabel = NULL; |
| 6745 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
| 6746 |
common->leave = NULL; |
common->leave = NULL; |
| 6747 |
common->accept = NULL; |
common->accept = NULL; |
| 6748 |
altfallback.cc = ccbegin; |
altbacktrack.cc = ccbegin; |
| 6749 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 6750 |
while (1) |
while (1) |
| 6751 |
{ |
{ |
| 6752 |
altfallback.top = NULL; |
altbacktrack.top = NULL; |
| 6753 |
altfallback.topfallbacks = NULL; |
altbacktrack.topbacktracks = NULL; |
| 6754 |
|
|
| 6755 |
if (altfallback.cc != ccbegin) |
if (altbacktrack.cc != ccbegin) |
| 6756 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6757 |
|
|
| 6758 |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
compile_trypath(common, altbacktrack.cc, cc, &altbacktrack); |
| 6759 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6760 |
{ |
{ |
| 6761 |
common->leavelabel = save_leavelabel; |
common->leavelabel = save_leavelabel; |
| 6765 |
|
|
| 6766 |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
| 6767 |
|
|
| 6768 |
compile_fallbackpath(common, altfallback.top); |
compile_backtrackpath(common, altbacktrack.top); |
| 6769 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6770 |
{ |
{ |
| 6771 |
common->leavelabel = save_leavelabel; |
common->leavelabel = save_leavelabel; |
| 6772 |
common->leave = save_leave; |
common->leave = save_leave; |
| 6773 |
return; |
return; |
| 6774 |
} |
} |
| 6775 |
set_jumps(altfallback.topfallbacks, LABEL()); |
set_jumps(altbacktrack.topbacktracks, LABEL()); |
| 6776 |
|
|
| 6777 |
if (*cc != OP_ALT) |
if (*cc != OP_ALT) |
| 6778 |
break; |
break; |
| 6779 |
|
|
| 6780 |
altfallback.cc = cc + 1 + LINK_SIZE; |
altbacktrack.cc = cc + 1 + LINK_SIZE; |
| 6781 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 6782 |
} |
} |
| 6783 |
/* None of them matched. */ |
/* None of them matched. */ |
| 6809 |
common->leave = save_leave; |
common->leave = save_leave; |
| 6810 |
} |
} |
| 6811 |
|
|
| 6812 |
#undef COMPILE_FALLBACKPATH |
#undef COMPILE_BACKTRACKPATH |
| 6813 |
#undef CURRENT_AS |
#undef CURRENT_AS |
| 6814 |
|
|
| 6815 |
void |
void |
| 6816 |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) |
| 6817 |
{ |
{ |
| 6818 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
| 6819 |
fallback_common rootfallback; |
backtrack_common rootbacktrack; |
| 6820 |
compiler_common common_data; |
compiler_common common_data; |
| 6821 |
compiler_common *common = &common_data; |
compiler_common *common = &common_data; |
| 6822 |
const pcre_uint8 *tables = re->tables; |
const pcre_uint8 *tables = re->tables; |
| 6828 |
sljit_uw executable_size; |
sljit_uw executable_size; |
| 6829 |
struct sljit_label *mainloop = NULL; |
struct sljit_label *mainloop = NULL; |
| 6830 |
struct sljit_label *empty_match_found; |
struct sljit_label *empty_match_found; |
| 6831 |
struct sljit_label *empty_match_fallback; |
struct sljit_label *empty_match_backtrack; |
| 6832 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 6833 |
struct sljit_jump *reqbyte_notfound = NULL; |
struct sljit_jump *reqbyte_notfound = NULL; |
| 6834 |
struct sljit_jump *empty_match; |
struct sljit_jump *empty_match; |
| 6839 |
if (!tables) |
if (!tables) |
| 6840 |
tables = PRIV(default_tables); |
tables = PRIV(default_tables); |
| 6841 |
|
|
| 6842 |
memset(&rootfallback, 0, sizeof(fallback_common)); |
memset(&rootbacktrack, 0, sizeof(backtrack_common)); |
| 6843 |
memset(common, 0, sizeof(compiler_common)); |
memset(common, 0, sizeof(compiler_common)); |
| 6844 |
rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; |
rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; |
| 6845 |
|
|
| 6846 |
common->start = rootfallback.cc; |
common->start = rootbacktrack.cc; |
| 6847 |
common->fcc = tables + fcc_offset; |
common->fcc = tables + fcc_offset; |
| 6848 |
common->lcc = (sljit_w)(tables + lcc_offset); |
common->lcc = (sljit_w)(tables + lcc_offset); |
| 6849 |
common->mode = mode; |
common->mode = mode; |
| 6892 |
common->use_ucp = (re->options & PCRE_UCP) != 0; |
common->use_ucp = (re->options & PCRE_UCP) != 0; |
| 6893 |
#endif |
#endif |
| 6894 |
#endif /* SUPPORT_UTF */ |
#endif /* SUPPORT_UTF */ |
| 6895 |
ccend = bracketend(rootfallback.cc); |
ccend = bracketend(rootbacktrack.cc); |
| 6896 |
|
|
| 6897 |
/* Calculate the local space size on the stack. */ |
/* Calculate the local space size on the stack. */ |
| 6898 |
common->ovector_start = CALL_LIMIT + sizeof(sljit_w); |
common->ovector_start = CALL_LIMIT + sizeof(sljit_w); |
| 6899 |
|
|
| 6900 |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
| 6901 |
localsize = get_localspace(common, rootfallback.cc, ccend); |
localsize = get_localspace(common, rootbacktrack.cc, ccend); |
| 6902 |
if (localsize < 0) |
if (localsize < 0) |
| 6903 |
return; |
return; |
| 6904 |
|
|
| 6933 |
localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
| 6934 |
if (localsize > SLJIT_MAX_LOCAL_SIZE) |
if (localsize > SLJIT_MAX_LOCAL_SIZE) |
| 6935 |
return; |
return; |
| 6936 |
common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int)); |
common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); |
| 6937 |
if (!common->localptrs) |
if (!common->localptrs) |
| 6938 |
return; |
return; |
| 6939 |
memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int)); |
memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); |
| 6940 |
set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); |
set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); |
| 6941 |
|
|
| 6942 |
compiler = sljit_create_compiler(); |
compiler = sljit_create_compiler(); |
| 7002 |
else if (mode == JIT_PARTIAL_HARD_COMPILE) |
else if (mode == JIT_PARTIAL_HARD_COMPILE) |
| 7003 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 7004 |
|
|
| 7005 |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack); |
| 7006 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 7007 |
{ |
{ |
| 7008 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
| 7031 |
return_with_partial_match(common, common->leavelabel); |
return_with_partial_match(common, common->leavelabel); |
| 7032 |
} |
} |
| 7033 |
|
|
| 7034 |
empty_match_fallback = LABEL(); |
empty_match_backtrack = LABEL(); |
| 7035 |
compile_fallbackpath(common, rootfallback.top); |
compile_backtrackpath(common, rootbacktrack.top); |
| 7036 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 7037 |
{ |
{ |
| 7038 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
| 7040 |
return; |
return; |
| 7041 |
} |
} |
| 7042 |
|
|
| 7043 |
SLJIT_ASSERT(rootfallback.prev == NULL); |
SLJIT_ASSERT(rootbacktrack.prev == NULL); |
| 7044 |
|
|
| 7045 |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
| 7046 |
{ |
{ |
| 7099 |
JUMPHERE(empty_match); |
JUMPHERE(empty_match); |
| 7100 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
| 7101 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); |
| 7102 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_fallback); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack); |
| 7103 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); |
| 7104 |
CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found); |
CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found); |
| 7105 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
| 7106 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found); |
| 7107 |
JUMPTO(SLJIT_JUMP, empty_match_fallback); |
JUMPTO(SLJIT_JUMP, empty_match_backtrack); |
| 7108 |
|
|
| 7109 |
common->currententry = common->entries; |
common->currententry = common->entries; |
| 7110 |
while (common->currententry != NULL) |
while (common->currententry != NULL) |