Parent Directory
|
Revision Log
|
Patch
revision 1491 by zherczeg, Mon Jul 7 07:11:16 2014 UTC | revision 1624 by zherczeg, Fri Feb 5 13:47:43 2016 UTC | |
---|---|---|
# | Line 52 POSSIBILITY OF SUCH DAMAGE. | Line 52 POSSIBILITY OF SUCH DAMAGE. |
52 | we just include it. This way we don't need to touch the build | we just include it. This way we don't need to touch the build |
53 | system files. */ | system files. */ |
54 | ||
55 | #define SLJIT_MALLOC(size) (PUBL(malloc))(size) | #define SLJIT_MALLOC(size, allocator_data) (PUBL(malloc))(size) |
56 | #define SLJIT_FREE(ptr) (PUBL(free))(ptr) | #define SLJIT_FREE(ptr, allocator_data) (PUBL(free))(ptr) |
57 | #define SLJIT_CONFIG_AUTO 1 | #define SLJIT_CONFIG_AUTO 1 |
58 | #define SLJIT_CONFIG_STATIC 1 | #define SLJIT_CONFIG_STATIC 1 |
59 | #define SLJIT_VERBOSE 0 | #define SLJIT_VERBOSE 0 |
# | Line 179 typedef struct jit_arguments { | Line 179 typedef struct jit_arguments { |
179 | ||
180 | typedef struct executable_functions { | typedef struct executable_functions { |
181 | void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; | void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; |
182 | sljit_uw *read_only_data[JIT_NUMBER_OF_COMPILE_MODES]; | void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES]; |
183 | sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; | sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; |
184 | PUBL(jit_callback) callback; | PUBL(jit_callback) callback; |
185 | void *userdata; | void *userdata; |
# | Line 322 typedef struct compiler_common { | Line 322 typedef struct compiler_common { |
322 | pcre_uchar *start; | pcre_uchar *start; |
323 | /* Maps private data offset to each opcode. */ | /* Maps private data offset to each opcode. */ |
324 | sljit_si *private_data_ptrs; | sljit_si *private_data_ptrs; |
325 | /* This read-only data is available during runtime. */ | /* Chain list of read-only data ptrs. */ |
326 | sljit_uw *read_only_data; | void *read_only_data_head; |
/* The total size of the read-only data. */ | ||
sljit_uw read_only_data_size; | ||
/* The next free entry of the read_only_data. */ | ||
sljit_uw *read_only_data_ptr; | ||
327 | /* Tells whether the capturing bracket is optimized. */ | /* Tells whether the capturing bracket is optimized. */ |
328 | pcre_uint8 *optimized_cbracket; | pcre_uint8 *optimized_cbracket; |
329 | /* Tells whether the starting offset is a target of then. */ | /* Tells whether the starting offset is a target of then. */ |
# | Line 545 the start pointers when the end of the c | Line 541 the start pointers when the end of the c |
541 | ||
542 | #define READ_CHAR_MAX 0x7fffffff | #define READ_CHAR_MAX 0x7fffffff |
543 | ||
544 | static pcre_uchar* bracketend(pcre_uchar* cc) | static pcre_uchar *bracketend(pcre_uchar *cc) |
545 | { | { |
546 | SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); | SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); |
547 | do cc += GET(cc, 1); while (*cc == OP_ALT); | do cc += GET(cc, 1); while (*cc == OP_ALT); |
# | Line 554 cc += 1 + LINK_SIZE; | Line 550 cc += 1 + LINK_SIZE; |
550 | return cc; | return cc; |
551 | } | } |
552 | ||
553 | static int no_alternatives(pcre_uchar* cc) | static int no_alternatives(pcre_uchar *cc) |
554 | { | { |
555 | int count = 0; | int count = 0; |
556 | SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); | SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)); |
# | Line 802 while (cc < ccend) | Line 798 while (cc < ccend) |
798 | cc += 1 + IMM2_SIZE; | cc += 1 + IMM2_SIZE; |
799 | break; | break; |
800 | ||
case OP_BRA: | ||
case OP_CBRA: | ||
case OP_SBRA: | ||
case OP_SCBRA: | ||
count = no_alternatives(cc); | ||
if (count > 4) | ||
common->read_only_data_size += count * sizeof(sljit_uw); | ||
cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0); | ||
break; | ||
801 | case OP_CBRAPOS: | case OP_CBRAPOS: |
802 | case OP_SCBRAPOS: | case OP_SCBRAPOS: |
803 | common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; | common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; |
# | Line 1078 pcre_uchar *alternative; | Line 1064 pcre_uchar *alternative; |
1064 | pcre_uchar *end = NULL; | pcre_uchar *end = NULL; |
1065 | int private_data_ptr = *private_data_start; | int private_data_ptr = *private_data_start; |
1066 | int space, size, bracketlen; | int space, size, bracketlen; |
1067 | BOOL repeat_check = TRUE; | |
1068 | ||
1069 | while (cc < ccend) | while (cc < ccend) |
1070 | { | { |
# | Line 1085 while (cc < ccend) | Line 1072 while (cc < ccend) |
1072 | size = 0; | size = 0; |
1073 | bracketlen = 0; | bracketlen = 0; |
1074 | if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) | if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) |
1075 | return; | break; |
1076 | ||
1077 | if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND) | if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)) |
1078 | { | |
1079 | if (detect_repeat(common, cc)) | if (detect_repeat(common, cc)) |
1080 | { | { |
1081 | /* These brackets are converted to repeats, so no global | /* These brackets are converted to repeats, so no global |
# | Line 1095 while (cc < ccend) | Line 1083 while (cc < ccend) |
1083 | if (cc >= end) | if (cc >= end) |
1084 | end = bracketend(cc); | end = bracketend(cc); |
1085 | } | } |
1086 | } | |
1087 | repeat_check = TRUE; | |
1088 | ||
1089 | switch(*cc) | switch(*cc) |
1090 | { | { |
# | Line 1150 while (cc < ccend) | Line 1140 while (cc < ccend) |
1140 | bracketlen = 1 + LINK_SIZE + IMM2_SIZE; | bracketlen = 1 + LINK_SIZE + IMM2_SIZE; |
1141 | break; | break; |
1142 | ||
1143 | case OP_BRAZERO: | |
1144 | case OP_BRAMINZERO: | |
1145 | case OP_BRAPOSZERO: | |
1146 | repeat_check = FALSE; | |
1147 | size = 1; | |
1148 | break; | |
1149 | ||
1150 | CASE_ITERATOR_PRIVATE_DATA_1 | CASE_ITERATOR_PRIVATE_DATA_1 |
1151 | space = 1; | space = 1; |
1152 | size = -2; | size = -2; |
# | Line 1176 while (cc < ccend) | Line 1173 while (cc < ccend) |
1173 | size = 1; | size = 1; |
1174 | break; | break; |
1175 | ||
1176 | CASE_ITERATOR_TYPE_PRIVATE_DATA_2B | case OP_TYPEUPTO: |
1177 | if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) | if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) |
1178 | space = 2; | space = 2; |
1179 | size = 1 + IMM2_SIZE; | size = 1 + IMM2_SIZE; |
1180 | break; | break; |
1181 | ||
1182 | case OP_TYPEMINUPTO: | |
1183 | space = 2; | |
1184 | size = 1 + IMM2_SIZE; | |
1185 | break; | |
1186 | ||
1187 | case OP_CLASS: | case OP_CLASS: |
1188 | case OP_NCLASS: | case OP_NCLASS: |
1189 | size += 1 + 32 / sizeof(pcre_uchar); | size += 1 + 32 / sizeof(pcre_uchar); |
# | Line 1237 while (cc < ccend) | Line 1239 while (cc < ccend) |
1239 | } | } |
1240 | ||
1241 | /* Returns with a frame_types (always < 0) if no need for frame. */ | /* Returns with a frame_types (always < 0) if no need for frame. */ |
1242 | static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head) | static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL *needs_control_head) |
1243 | { | { |
1244 | int length = 0; | int length = 0; |
1245 | int possessive = 0; | int possessive = 0; |
# | Line 1330 while (cc < ccend) | Line 1332 while (cc < ccend) |
1332 | cc += 1 + LINK_SIZE + IMM2_SIZE; | cc += 1 + LINK_SIZE + IMM2_SIZE; |
1333 | break; | break; |
1334 | ||
1335 | case OP_THEN: | |
1336 | stack_restore = TRUE; | |
1337 | if (common->control_head_ptr != 0) | |
1338 | *needs_control_head = TRUE; | |
1339 | cc ++; | |
1340 | break; | |
1341 | ||
1342 | default: | default: |
1343 | stack_restore = TRUE; | stack_restore = TRUE; |
1344 | /* Fall through. */ | /* Fall through. */ |
# | Line 1397 while (cc < ccend) | Line 1406 while (cc < ccend) |
1406 | case OP_CLASS: | case OP_CLASS: |
1407 | case OP_NCLASS: | case OP_NCLASS: |
1408 | case OP_XCLASS: | case OP_XCLASS: |
1409 | case OP_CALLOUT: | |
1410 | ||
1411 | cc = next_opcode(common, cc); | cc = next_opcode(common, cc); |
1412 | SLJIT_ASSERT(cc != NULL); | SLJIT_ASSERT(cc != NULL); |
# | Line 1547 while (cc < ccend) | Line 1557 while (cc < ccend) |
1557 | { | { |
1558 | case OP_KET: | case OP_KET: |
1559 | if (PRIVATE_DATA(cc) != 0) | if (PRIVATE_DATA(cc) != 0) |
1560 | { | |
1561 | private_data_length++; | private_data_length++; |
1562 | SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); | |
1563 | cc += PRIVATE_DATA(cc + 1); | |
1564 | } | |
1565 | cc += 1 + LINK_SIZE; | cc += 1 + LINK_SIZE; |
1566 | break; | break; |
1567 | ||
# | Line 1562 while (cc < ccend) | Line 1576 while (cc < ccend) |
1576 | case OP_SBRAPOS: | case OP_SBRAPOS: |
1577 | case OP_SCOND: | case OP_SCOND: |
1578 | private_data_length++; | private_data_length++; |
1579 | SLJIT_ASSERT(PRIVATE_DATA(cc) != 0); | |
1580 | cc += 1 + LINK_SIZE; | cc += 1 + LINK_SIZE; |
1581 | break; | break; |
1582 | ||
# | Line 1724 do | Line 1739 do |
1739 | { | { |
1740 | count = 1; | count = 1; |
1741 | srcw[0] = PRIVATE_DATA(cc); | srcw[0] = PRIVATE_DATA(cc); |
1742 | SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0); | |
1743 | cc += PRIVATE_DATA(cc + 1); | |
1744 | } | } |
1745 | cc += 1 + LINK_SIZE; | cc += 1 + LINK_SIZE; |
1746 | break; | break; |
# | Line 2030 while (list) | Line 2047 while (list) |
2047 | } | } |
2048 | } | } |
2049 | ||
2050 | static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump) | static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump) |
2051 | { | { |
2052 | jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); | jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list)); |
2053 | if (list_item) | if (list_item) |
# | Line 2044 if (list_item) | Line 2061 if (list_item) |
2061 | static void add_stub(compiler_common *common, struct sljit_jump *start) | static void add_stub(compiler_common *common, struct sljit_jump *start) |
2062 | { | { |
2063 | DEFINE_COMPILER; | DEFINE_COMPILER; |
2064 | stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); | stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list)); |
2065 | ||
2066 | if (list_item) | if (list_item) |
2067 | { | { |
# | Line 2058 if (list_item) | Line 2075 if (list_item) |
2075 | static void flush_stubs(compiler_common *common) | static void flush_stubs(compiler_common *common) |
2076 | { | { |
2077 | DEFINE_COMPILER; | DEFINE_COMPILER; |
2078 | stub_list* list_item = common->stubs; | stub_list *list_item = common->stubs; |
2079 | ||
2080 | while (list_item) | while (list_item) |
2081 | { | { |
# | Line 2089 static SLJIT_INLINE void count_match(com | Line 2106 static SLJIT_INLINE void count_match(com |
2106 | DEFINE_COMPILER; | DEFINE_COMPILER; |
2107 | ||
2108 | OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); |
2109 | add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); | add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO)); |
2110 | } | } |
2111 | ||
2112 | static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) | static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) |
# | Line 2097 static SLJIT_INLINE void allocate_stack( | Line 2114 static SLJIT_INLINE void allocate_stack( |
2114 | /* May destroy all locals and registers except TMP2. */ | /* May destroy all locals and registers except TMP2. */ |
2115 | DEFINE_COMPILER; | DEFINE_COMPILER; |
2116 | ||
2117 | SLJIT_ASSERT(size > 0); | |
2118 | OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); | OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); |
2119 | #ifdef DESTROY_REGISTERS | #ifdef DESTROY_REGISTERS |
2120 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); |
# | Line 2105 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); | Line 2123 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); |
2123 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0); |
2124 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); |
2125 | #endif | #endif |
2126 | add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); | add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); |
2127 | } | } |
2128 | ||
2129 | static SLJIT_INLINE void free_stack(compiler_common *common, int size) | static SLJIT_INLINE void free_stack(compiler_common *common, int size) |
2130 | { | { |
2131 | DEFINE_COMPILER; | DEFINE_COMPILER; |
2132 | ||
2133 | SLJIT_ASSERT(size > 0); | |
2134 | OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); | OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); |
2135 | } | } |
2136 | ||
2137 | static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size) | |
2138 | { | |
2139 | DEFINE_COMPILER; | |
2140 | sljit_uw *result; | |
2141 | ||
2142 | if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) | |
2143 | return NULL; | |
2144 | ||
2145 | result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data); | |
2146 | if (SLJIT_UNLIKELY(result == NULL)) | |
2147 | { | |
2148 | sljit_set_compiler_memory_error(compiler); | |
2149 | return NULL; | |
2150 | } | |
2151 | ||
2152 | *(void**)result = common->read_only_data_head; | |
2153 | common->read_only_data_head = (void *)result; | |
2154 | return result + 1; | |
2155 | } | |
2156 | ||
2157 | static void free_read_only_data(void *current, void *allocator_data) | |
2158 | { | |
2159 | void *next; | |
2160 | ||
2161 | SLJIT_UNUSED_ARG(allocator_data); | |
2162 | ||
2163 | while (current != NULL) | |
2164 | { | |
2165 | next = *(void**)current; | |
2166 | SLJIT_FREE(current, allocator_data); | |
2167 | current = next; | |
2168 | } | |
2169 | } | |
2170 | ||
2171 | static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) | static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) |
2172 | { | { |
2173 | DEFINE_COMPILER; | DEFINE_COMPILER; |
# | Line 2136 else | Line 2190 else |
2190 | loop = LABEL(); | loop = LABEL(); |
2191 | OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0); | OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0); |
2192 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1); |
2193 | JUMPTO(SLJIT_C_NOT_ZERO, loop); | JUMPTO(SLJIT_NOT_ZERO, loop); |
2194 | } | } |
2195 | } | } |
2196 | ||
# | Line 2162 else | Line 2216 else |
2216 | loop = LABEL(); | loop = LABEL(); |
2217 | OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); | OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); |
2218 | OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1); |
2219 | JUMPTO(SLJIT_C_NOT_ZERO, loop); | JUMPTO(SLJIT_NOT_ZERO, loop); |
2220 | } | } |
2221 | ||
2222 | OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); |
# | Line 2193 while (current != NULL) | Line 2247 while (current != NULL) |
2247 | SLJIT_ASSERT_STOP(); | SLJIT_ASSERT_STOP(); |
2248 | break; | break; |
2249 | } | } |
2250 | SLJIT_ASSERT(current > (sljit_sw*)current[-1]); | |
2251 | current = (sljit_sw*)current[-1]; | current = (sljit_sw*)current[-1]; |
2252 | } | } |
2253 | return -1; | return -1; |
# | Line 2218 OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(S | Line 2273 OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(S |
2273 | OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin)); | OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin)); |
2274 | GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START); | GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START); |
2275 | /* Unlikely, but possible */ | /* Unlikely, but possible */ |
2276 | early_quit = CMP(SLJIT_C_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0); | early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0); |
2277 | loop = LABEL(); | loop = LABEL(); |
2278 | OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); | OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0); |
2279 | OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw)); | OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw)); |
# | Line 2228 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0 | Line 2283 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0 |
2283 | #endif | #endif |
2284 | OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0); | OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0); |
2285 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); |
2286 | JUMPTO(SLJIT_C_NOT_ZERO, loop); | JUMPTO(SLJIT_NOT_ZERO, loop); |
2287 | JUMPHERE(early_quit); | JUMPHERE(early_quit); |
2288 | ||
2289 | /* Calculate the return value, which is the maximum ovector value. */ | /* Calculate the return value, which is the maximum ovector value. */ |
# | Line 2241 if (topbracket > 1) | Line 2296 if (topbracket > 1) |
2296 | loop = LABEL(); | loop = LABEL(); |
2297 | OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))); | OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))); |
2298 | OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); |
2299 | CMPTO(SLJIT_C_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop); | CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop); |
2300 | OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0); | OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0); |
2301 | } | } |
2302 | else | else |
# | Line 2260 SLJIT_ASSERT(common->start_used_ptr != 0 | Line 2315 SLJIT_ASSERT(common->start_used_ptr != 0 |
2315 | OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); |
2316 | OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); | OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); |
2317 | OP1(SLJIT_MOV_SI, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count)); | OP1(SLJIT_MOV_SI, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count)); |
2318 | CMPTO(SLJIT_C_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit); | CMPTO(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit); |
2319 | ||
2320 | /* Store match begin and end. */ | /* Store match begin and end. */ |
2321 | OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin)); | OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin)); |
2322 | OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, offsets)); | OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, offsets)); |
2323 | ||
2324 | jump = CMP(SLJIT_C_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 3); | jump = CMP(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 3); |
2325 | OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_S0, 0); | OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_S0, 0); |
2326 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
2327 | OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); | OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); |
# | Line 2302 if (common->mode == JIT_PARTIAL_SOFT_COM | Line 2357 if (common->mode == JIT_PARTIAL_SOFT_COM |
2357 | OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1); | OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1); |
2358 | /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting | /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting |
2359 | is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ | is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ |
2360 | jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); | jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0); |
2361 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); |
2362 | JUMPHERE(jump); | JUMPHERE(jump); |
2363 | } | } |
2364 | else if (common->mode == JIT_PARTIAL_HARD_COMPILE) | else if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
2365 | { | { |
2366 | jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); | jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); |
2367 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); |
2368 | JUMPHERE(jump); | JUMPHERE(jump); |
2369 | } | } |
2370 | } | } |
2371 | ||
2372 | static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) | static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar *cc) |
2373 | { | { |
2374 | /* Detects if the character has an othercase. */ | /* Detects if the character has an othercase. */ |
2375 | unsigned int c; | unsigned int c; |
# | Line 2357 if (common->utf && c > 127) | Line 2412 if (common->utf && c > 127) |
2412 | return TABLE_GET(c, common->fcc, c); | return TABLE_GET(c, common->fcc, c); |
2413 | } | } |
2414 | ||
2415 | static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc) | static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar *cc) |
2416 | { | { |
2417 | /* Detects if the character and its othercase has only 1 bit difference. */ | /* Detects if the character and its othercase has only 1 bit difference. */ |
2418 | unsigned int c, oc, bit; | unsigned int c, oc, bit; |
# | Line 2445 if (common->mode == JIT_COMPILE) | Line 2500 if (common->mode == JIT_COMPILE) |
2500 | return; | return; |
2501 | ||
2502 | if (!force) | if (!force) |
2503 | jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); | jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); |
2504 | else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) | else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
2505 | jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); | jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); |
2506 | ||
2507 | if (common->mode == JIT_PARTIAL_SOFT_COMPILE) | if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
2508 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); |
# | Line 2471 struct sljit_jump *jump; | Line 2526 struct sljit_jump *jump; |
2526 | ||
2527 | if (common->mode == JIT_COMPILE) | if (common->mode == JIT_COMPILE) |
2528 | { | { |
2529 | add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); | add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
2530 | return; | return; |
2531 | } | } |
2532 | ||
2533 | jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); | jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); |
2534 | if (common->mode == JIT_PARTIAL_SOFT_COMPILE) | if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
2535 | { | { |
2536 | add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); | add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); |
2537 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); |
2538 | add_jump(compiler, end_reached, JUMP(SLJIT_JUMP)); | add_jump(compiler, end_reached, JUMP(SLJIT_JUMP)); |
2539 | } | } |
2540 | else | else |
2541 | { | { |
2542 | add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); | add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); |
2543 | if (common->partialmatchlabel != NULL) | if (common->partialmatchlabel != NULL) |
2544 | JUMPTO(SLJIT_JUMP, common->partialmatchlabel); | JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
2545 | else | else |
# | Line 2500 struct sljit_jump *jump; | Line 2555 struct sljit_jump *jump; |
2555 | ||
2556 | if (common->mode == JIT_COMPILE) | if (common->mode == JIT_COMPILE) |
2557 | { | { |
2558 | add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
2559 | return; | return; |
2560 | } | } |
2561 | ||
2562 | /* Partial matching mode. */ | /* Partial matching mode. */ |
2563 | jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); | jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); |
2564 | add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); |
2565 | if (common->mode == JIT_PARTIAL_SOFT_COMPILE) | if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
2566 | { | { |
2567 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); |
# | Line 2539 if (common->utf) | Line 2594 if (common->utf) |
2594 | { | { |
2595 | if (max < 128) return; | if (max < 128) return; |
2596 | ||
2597 | jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); | jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); |
2598 | 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)); |
2599 | add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); |
2600 | OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); | OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
# | Line 2553 if (common->utf) | Line 2608 if (common->utf) |
2608 | if (max < 0xd800) return; | if (max < 0xd800) return; |
2609 | ||
2610 | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); |
2611 | jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); | jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); |
2612 | /* TMP2 contains the high surrogate. */ | /* TMP2 contains the high surrogate. */ |
2613 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
2614 | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); |
# | Line 2572 static BOOL is_char7_bitset(const pcre_u | Line 2627 static BOOL is_char7_bitset(const pcre_u |
2627 | /* Tells whether the character codes below 128 are enough | /* Tells whether the character codes below 128 are enough |
2628 | to determine a match. */ | to determine a match. */ |
2629 | const pcre_uint8 value = nclass ? 0xff : 0; | const pcre_uint8 value = nclass ? 0xff : 0; |
2630 | const pcre_uint8* end = bitset + 32; | const pcre_uint8 *end = bitset + 32; |
2631 | ||
2632 | bitset += 16; | bitset += 16; |
2633 | do | do |
# | Line 2601 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TM | Line 2656 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TM |
2656 | ||
2657 | if (full_read) | if (full_read) |
2658 | { | { |
2659 | jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); | jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); |
2660 | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
2661 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
2662 | JUMPHERE(jump); | JUMPHERE(jump); |
# | Line 2636 if (common->utf) | Line 2691 if (common->utf) |
2691 | { | { |
2692 | if (max < 128 && !update_str_ptr) return; | if (max < 128 && !update_str_ptr) return; |
2693 | ||
2694 | jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); | jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); |
2695 | if (min >= 0x10000) | if (min >= 0x10000) |
2696 | { | { |
2697 | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); |
2698 | if (update_str_ptr) | if (update_str_ptr) |
2699 | OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
2700 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
2701 | jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x7); | jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7); |
2702 | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); |
2703 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); |
2704 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); |
# | Line 2667 if (common->utf) | Line 2722 if (common->utf) |
2722 | if (update_str_ptr) | if (update_str_ptr) |
2723 | OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
2724 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
2725 | jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xf); | jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf); |
2726 | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); |
2727 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); |
2728 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); |
# | Line 2712 if (common->utf) | Line 2767 if (common->utf) |
2767 | if (max >= 0x10000) | if (max >= 0x10000) |
2768 | { | { |
2769 | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); |
2770 | jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); | jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); |
2771 | /* TMP2 contains the high surrogate. */ | /* TMP2 contains the high surrogate. */ |
2772 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
2773 | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); |
# | Line 2728 if (common->utf) | Line 2783 if (common->utf) |
2783 | ||
2784 | /* Skip low surrogate if necessary. */ | /* Skip low surrogate if necessary. */ |
2785 | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); |
2786 | jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); | jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); |
2787 | if (update_str_ptr) | if (update_str_ptr) |
2788 | 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)); |
2789 | if (max >= 0xd800) | if (max >= 0xd800) |
# | Line 2765 if (common->utf) | Line 2820 if (common->utf) |
2820 | /* This can be an extra read in some situations, but hopefully | /* This can be an extra read in some situations, but hopefully |
2821 | it is needed in most cases. */ | it is needed in most cases. */ |
2822 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); |
2823 | jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); | jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); |
2824 | if (!update_str_ptr) | if (!update_str_ptr) |
2825 | { | { |
2826 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
# | Line 2775 if (common->utf) | Line 2830 if (common->utf) |
2830 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); |
2831 | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); |
2832 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); |
2833 | jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); | jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); |
2834 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); |
2835 | JUMPHERE(jump2); | JUMPHERE(jump2); |
2836 | } | } |
# | Line 2789 if (common->utf) | Line 2844 if (common->utf) |
2844 | #if !defined COMPILE_PCRE8 | #if !defined COMPILE_PCRE8 |
2845 | /* The ctypes array contains only 256 values. */ | /* The ctypes array contains only 256 values. */ |
2846 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); |
2847 | jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); |
2848 | #endif | #endif |
2849 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); |
2850 | #if !defined COMPILE_PCRE8 | #if !defined COMPILE_PCRE8 |
# | Line 2801 if (common->utf && update_str_ptr) | Line 2856 if (common->utf && update_str_ptr) |
2856 | { | { |
2857 | /* Skip low surrogate if necessary. */ | /* Skip low surrogate if necessary. */ |
2858 | OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); |
2859 | jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); | jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); |
2860 | 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)); |
2861 | JUMPHERE(jump); | JUMPHERE(jump); |
2862 | } | } |
# | Line 2822 if (common->utf) | Line 2877 if (common->utf) |
2877 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); |
2878 | 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)); |
2879 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); |
2880 | CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); | CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); |
2881 | return; | return; |
2882 | } | } |
2883 | #elif defined COMPILE_PCRE16 | #elif defined COMPILE_PCRE16 |
# | Line 2833 if (common->utf) | Line 2888 if (common->utf) |
2888 | /* Skip low surrogate if necessary. */ | /* Skip low surrogate if necessary. */ |
2889 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); |
2890 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); |
2891 | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
2892 | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
2893 | OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
2894 | return; | return; |
# | Line 2852 struct sljit_jump *jump; | Line 2907 struct sljit_jump *jump; |
2907 | if (nltype == NLTYPE_ANY) | if (nltype == NLTYPE_ANY) |
2908 | { | { |
2909 | add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); |
2910 | add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); | add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO)); |
2911 | } | } |
2912 | else if (nltype == NLTYPE_ANYCRLF) | else if (nltype == NLTYPE_ANYCRLF) |
2913 | { | { |
2914 | if (jumpifmatch) | if (jumpifmatch) |
2915 | { | { |
2916 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR)); |
2917 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); |
2918 | } | } |
2919 | else | else |
2920 | { | { |
2921 | jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); | jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
2922 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); |
2923 | JUMPHERE(jump); | JUMPHERE(jump); |
2924 | } | } |
2925 | } | } |
2926 | else | else |
2927 | { | { |
2928 | SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); | SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256); |
2929 | add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); | add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); |
2930 | } | } |
2931 | } | } |
2932 | ||
# | Line 2894 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0) | Line 2949 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0) |
2949 | ||
2950 | /* Searching for the first zero. */ | /* Searching for the first zero. */ |
2951 | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); |
2952 | jump = JUMP(SLJIT_C_NOT_ZERO); | jump = JUMP(SLJIT_NOT_ZERO); |
2953 | /* Two byte sequence. */ | /* Two byte sequence. */ |
2954 | 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)); |
2955 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); |
# | Line 2908 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_I | Line 2963 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_I |
2963 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); |
2964 | ||
2965 | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); |
2966 | jump = JUMP(SLJIT_C_NOT_ZERO); | jump = JUMP(SLJIT_NOT_ZERO); |
2967 | /* Three byte sequence. */ | /* Three byte sequence. */ |
2968 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
2969 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); |
# | Line 2942 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0) | Line 2997 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0) |
2997 | ||
2998 | /* Searching for the first zero. */ | /* Searching for the first zero. */ |
2999 | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); |
3000 | jump = JUMP(SLJIT_C_NOT_ZERO); | jump = JUMP(SLJIT_NOT_ZERO); |
3001 | /* Two byte sequence. */ | /* Two byte sequence. */ |
3002 | 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)); |
3003 | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
3004 | ||
3005 | JUMPHERE(jump); | JUMPHERE(jump); |
3006 | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); |
3007 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO); |
3008 | /* This code runs only in 8 bit mode. No need to shift the value. */ | /* This code runs only in 8 bit mode. No need to shift the value. */ |
3009 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
3010 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
# | Line 2973 struct sljit_jump *compare; | Line 3028 struct sljit_jump *compare; |
3028 | sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); | sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
3029 | ||
3030 | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); | OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20); |
3031 | jump = JUMP(SLJIT_C_NOT_ZERO); | jump = JUMP(SLJIT_NOT_ZERO); |
3032 | /* Two byte sequence. */ | /* Two byte sequence. */ |
3033 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
3034 | 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)); |
3035 | OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); | OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f); |
3036 | /* The upper 5 bits are known at this point. */ | /* The upper 5 bits are known at this point. */ |
3037 | compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3); | compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3); |
3038 | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); |
3039 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); |
3040 | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); |
# | Line 3059 if (firstline) | Line 3114 if (firstline) |
3114 | { | { |
3115 | mainloop = LABEL(); | mainloop = LABEL(); |
3116 | 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)); |
3117 | end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3118 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); |
3119 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
3120 | CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); | CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); |
3121 | CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); | CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); |
3122 | JUMPHERE(end); | JUMPHERE(end); |
3123 | OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); | OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
3124 | } | } |
3125 | else | else |
3126 | { | { |
3127 | end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3128 | mainloop = LABEL(); | mainloop = LABEL(); |
3129 | /* Continual stores does not cause data dependency. */ | /* Continual stores does not cause data dependency. */ |
3130 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); |
3131 | read_char_range(common, common->nlmin, common->nlmax, TRUE); | read_char_range(common, common->nlmin, common->nlmax, TRUE); |
3132 | check_newlinechar(common, common->nltype, &newline, TRUE); | check_newlinechar(common, common->nltype, &newline, TRUE); |
3133 | CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); | CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
3134 | JUMPHERE(end); | JUMPHERE(end); |
3135 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); |
3136 | set_jumps(newline, LABEL()); | set_jumps(newline, LABEL()); |
# | Line 3090 if (newlinecheck) | Line 3145 if (newlinecheck) |
3145 | { | { |
3146 | newlinelabel = LABEL(); | newlinelabel = LABEL(); |
3147 | 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)); |
3148 | end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3149 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3150 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); |
3151 | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
3152 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
3153 | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); |
3154 | #endif | #endif |
# | Line 3113 if (readuchar) | Line 3168 if (readuchar) |
3168 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3169 | ||
3170 | if (newlinecheck) | if (newlinecheck) |
3171 | CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); | CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); |
3172 | ||
3173 | 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)); |
3174 | #if defined SUPPORT_UTF && !defined COMPILE_PCRE32 | #if defined SUPPORT_UTF && !defined COMPILE_PCRE32 |
3175 | #if defined COMPILE_PCRE8 | #if defined COMPILE_PCRE8 |
3176 | if (common->utf) | if (common->utf) |
3177 | { | { |
3178 | singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); | singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); |
3179 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
3180 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
3181 | JUMPHERE(singlechar); | JUMPHERE(singlechar); |
# | Line 3128 if (common->utf) | Line 3183 if (common->utf) |
3183 | #elif defined COMPILE_PCRE16 | #elif defined COMPILE_PCRE16 |
3184 | if (common->utf) | if (common->utf) |
3185 | { | { |
3186 | singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); | singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); |
3187 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); |
3188 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); |
3189 | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
3190 | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
3191 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
3192 | JUMPHERE(singlechar); | JUMPHERE(singlechar); |
# | Line 3182 bytes[len] = byte; | Line 3237 bytes[len] = byte; |
3237 | bytes[0] = len; | bytes[0] = len; |
3238 | } | } |
3239 | ||
3240 | static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars) | static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count) |
3241 | { | { |
3242 | /* Recursive function, which scans prefix literals. */ | /* Recursive function, which scans prefix literals. */ |
3243 | BOOL last, any, caseless; | BOOL last, any, caseless; |
# | Line 3200 pcre_uchar othercase[1]; | Line 3255 pcre_uchar othercase[1]; |
3255 | repeat = 1; | repeat = 1; |
3256 | while (TRUE) | while (TRUE) |
3257 | { | { |
3258 | if (*rec_count == 0) | |
3259 | return 0; | |
3260 | (*rec_count)--; | |
3261 | ||
3262 | last = TRUE; | last = TRUE; |
3263 | any = FALSE; | any = FALSE; |
3264 | caseless = FALSE; | caseless = FALSE; |
3265 | ||
3266 | switch (*cc) | switch (*cc) |
3267 | { | { |
3268 | case OP_CHARI: | case OP_CHARI: |
# | Line 3264 while (TRUE) | Line 3324 while (TRUE) |
3324 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
3325 | if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); | if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); |
3326 | #endif | #endif |
3327 | max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars); | max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count); |
3328 | if (max_chars == 0) | if (max_chars == 0) |
3329 | return consumed; | return consumed; |
3330 | last = FALSE; | last = FALSE; |
# | Line 3287 while (TRUE) | Line 3347 while (TRUE) |
3347 | alternative = cc + GET(cc, 1); | alternative = cc + GET(cc, 1); |
3348 | while (*alternative == OP_ALT) | while (*alternative == OP_ALT) |
3349 | { | { |
3350 | max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars); | max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count); |
3351 | if (max_chars == 0) | if (max_chars == 0) |
3352 | return consumed; | return consumed; |
3353 | alternative += GET(alternative, 1); | alternative += GET(alternative, 1); |
# | Line 3529 int i, max, from; | Line 3589 int i, max, from; |
3589 | int range_right = -1, range_len = 3 - 1; | int range_right = -1, range_len = 3 - 1; |
3590 | sljit_ub *update_table = NULL; | sljit_ub *update_table = NULL; |
3591 | BOOL in_range; | BOOL in_range; |
3592 | pcre_uint32 rec_count; | |
/* This is even TRUE, if both are NULL. */ | ||
SLJIT_ASSERT(common->read_only_data_ptr == common->read_only_data); | ||
3593 | ||
3594 | for (i = 0; i < MAX_N_CHARS; i++) | for (i = 0; i < MAX_N_CHARS; i++) |
3595 | { | { |
# | Line 3540 for (i = 0; i < MAX_N_CHARS; i++) | Line 3598 for (i = 0; i < MAX_N_CHARS; i++) |
3598 | bytes[i * MAX_N_BYTES] = 0; | bytes[i * MAX_N_BYTES] = 0; |
3599 | } | } |
3600 | ||
3601 | max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS); | rec_count = 10000; |
3602 | max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count); | |
3603 | ||
3604 | if (max <= 1) | if (max <= 1) |
3605 | return FALSE; | return FALSE; |
# | Line 3581 for (i = 0; i <= max; i++) | Line 3640 for (i = 0; i <= max; i++) |
3640 | ||
3641 | if (range_right >= 0) | if (range_right >= 0) |
3642 | { | { |
3643 | /* Since no data is consumed (see the assert in the beginning | update_table = (sljit_ub *)allocate_read_only_data(common, 256); |
3644 | of this function), this space can be reallocated. */ | if (update_table == NULL) |
if (common->read_only_data) | ||
SLJIT_FREE(common->read_only_data); | ||
common->read_only_data_size += 256; | ||
common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size); | ||
if (common->read_only_data == NULL) | ||
3645 | return TRUE; | return TRUE; |
update_table = (sljit_ub *)common->read_only_data; | ||
common->read_only_data_ptr = (sljit_uw *)(update_table + 256); | ||
3646 | memset(update_table, IN_UCHARS(range_len), 256); | memset(update_table, IN_UCHARS(range_len), 256); |
3647 | ||
3648 | for (i = 0; i < range_len; i++) | for (i = 0; i < range_len; i++) |
# | Line 3683 if (firstline) | Line 3733 if (firstline) |
3733 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); |
3734 | OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); | OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); |
3735 | OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); | OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); |
3736 | quit = CMP(SLJIT_C_LESS_EQUAL, STR_END, 0, TMP1, 0); | quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0); |
3737 | OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); | OP1(SLJIT_MOV, STR_END, 0, TMP1, 0); |
3738 | JUMPHERE(quit); | JUMPHERE(quit); |
3739 | } | } |
# | Line 3696 if (range_right >= 0) | Line 3746 if (range_right >= 0) |
3746 | #endif | #endif |
3747 | ||
3748 | start = LABEL(); | start = LABEL(); |
3749 | quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3750 | ||
3751 | SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0); | SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0); |
3752 | ||
# | Line 3714 if (range_right >= 0) | Line 3764 if (range_right >= 0) |
3764 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); |
3765 | #endif | #endif |
3766 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
3767 | CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); | CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); |
3768 | } | } |
3769 | ||
3770 | if (offsets[0] >= 0) | if (offsets[0] >= 0) |
# | Line 3726 if (offsets[0] >= 0) | Line 3776 if (offsets[0] >= 0) |
3776 | ||
3777 | if (chars[1] != 0) | if (chars[1] != 0) |
3778 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); |
3779 | CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); | CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); |
3780 | if (offsets[2] >= 0) | if (offsets[2] >= 0) |
3781 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1)); |
3782 | ||
# | Line 3734 if (offsets[0] >= 0) | Line 3784 if (offsets[0] >= 0) |
3784 | { | { |
3785 | if (chars[5] != 0) | if (chars[5] != 0) |
3786 | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]); | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]); |
3787 | CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start); | CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start); |
3788 | } | } |
3789 | ||
3790 | if (offsets[2] >= 0) | if (offsets[2] >= 0) |
3791 | { | { |
3792 | if (chars[3] != 0) | if (chars[3] != 0) |
3793 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]); |
3794 | CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start); | CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start); |
3795 | } | } |
3796 | 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)); |
3797 | } | } |
# | Line 3755 if (firstline) | Line 3805 if (firstline) |
3805 | OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); | OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); |
3806 | if (range_right >= 0) | if (range_right >= 0) |
3807 | { | { |
3808 | quit = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); | quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); |
3809 | OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); | OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); |
3810 | JUMPHERE(quit); | JUMPHERE(quit); |
3811 | } | } |
# | Line 3784 if (firstline) | Line 3834 if (firstline) |
3834 | } | } |
3835 | ||
3836 | start = LABEL(); | start = LABEL(); |
3837 | quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3838 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3839 | ||
3840 | oc = first_char; | oc = first_char; |
# | Line 3797 if (caseless) | Line 3847 if (caseless) |
3847 | #endif | #endif |
3848 | } | } |
3849 | if (first_char == oc) | if (first_char == oc) |
3850 | found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char); | found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, first_char); |
3851 | else | else |
3852 | { | { |
3853 | bit = first_char ^ oc; | bit = first_char ^ oc; |
3854 | if (is_powerof2(bit)) | if (is_powerof2(bit)) |
3855 | { | { |
3856 | OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); | OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); |
3857 | found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); | found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); |
3858 | } | } |
3859 | else | else |
3860 | { | { |
3861 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); |
3862 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
3863 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); |
3864 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
3865 | found = JUMP(SLJIT_C_NOT_ZERO); | found = JUMP(SLJIT_NOT_ZERO); |
3866 | } | } |
3867 | } | } |
3868 | ||
# | Line 3845 if (firstline) | Line 3895 if (firstline) |
3895 | ||
3896 | if (common->nltype == NLTYPE_FIXED && common->newline > 255) | if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3897 | { | { |
3898 | lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3899 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
3900 | 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)); |
3901 | 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)); |
3902 | firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); | firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); |
3903 | ||
3904 | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); |
3905 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); |
3906 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL); |
3907 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
3908 | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); | OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); |
3909 | #endif | #endif |
# | Line 3861 if (common->nltype == NLTYPE_FIXED && co | Line 3911 if (common->nltype == NLTYPE_FIXED && co |
3911 | ||
3912 | loop = LABEL(); | loop = LABEL(); |
3913 | 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)); |
3914 | quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3915 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); |
3916 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); |
3917 | CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); | CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); |
3918 | CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); | CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); |
3919 | ||
3920 | JUMPHERE(quit); | JUMPHERE(quit); |
3921 | JUMPHERE(firstchar); | JUMPHERE(firstchar); |
# | Line 3878 if (common->nltype == NLTYPE_FIXED && co | Line 3928 if (common->nltype == NLTYPE_FIXED && co |
3928 | ||
3929 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
3930 | 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)); |
3931 | firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0); | firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); |
3932 | skip_char_back(common); | skip_char_back(common); |
3933 | ||
3934 | loop = LABEL(); | loop = LABEL(); |
3935 | common->ff_newline_shortcut = loop; | common->ff_newline_shortcut = loop; |
3936 | ||
3937 | read_char_range(common, common->nlmin, common->nlmax, TRUE); | read_char_range(common, common->nlmin, common->nlmax, TRUE); |
3938 | lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3939 | if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) | if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) |
3940 | foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); | foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
3941 | check_newlinechar(common, common->nltype, &newline, FALSE); | check_newlinechar(common, common->nltype, &newline, FALSE); |
3942 | set_jumps(newline, loop); | set_jumps(newline, loop); |
3943 | ||
# | Line 3895 if (common->nltype == NLTYPE_ANY || comm | Line 3945 if (common->nltype == NLTYPE_ANY || comm |
3945 | { | { |
3946 | quit = JUMP(SLJIT_JUMP); | quit = JUMP(SLJIT_JUMP); |
3947 | JUMPHERE(foundcr); | JUMPHERE(foundcr); |
3948 | notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3949 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3950 | 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); |
3951 | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
3952 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
3953 | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); |
3954 | #endif | #endif |
# | Line 3934 if (firstline) | Line 3984 if (firstline) |
3984 | } | } |
3985 | ||
3986 | start = LABEL(); | start = LABEL(); |
3987 | quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3988 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3989 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
3990 | if (common->utf) | if (common->utf) |
# | Line 3944 if (common->utf) | Line 3994 if (common->utf) |
3994 | if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches)) | if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches)) |
3995 | { | { |
3996 | #ifndef COMPILE_PCRE8 | #ifndef COMPILE_PCRE8 |
3997 | jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255); |
3998 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255); |
3999 | JUMPHERE(jump); | JUMPHERE(jump); |
4000 | #endif | #endif |
# | Line 3953 if (!check_class_ranges(common, start_bi | Line 4003 if (!check_class_ranges(common, start_bi |
4003 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); |
4004 | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
4005 | 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); |
4006 | found = JUMP(SLJIT_C_NOT_ZERO); | found = JUMP(SLJIT_NOT_ZERO); |
4007 | } | } |
4008 | ||
4009 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
# | Line 3965 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, S | Line 4015 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, S |
4015 | #if defined COMPILE_PCRE8 | #if defined COMPILE_PCRE8 |
4016 | if (common->utf) | if (common->utf) |
4017 | { | { |
4018 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); |
4019 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
4020 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
4021 | } | } |
4022 | #elif defined COMPILE_PCRE16 | #elif defined COMPILE_PCRE16 |
4023 | if (common->utf) | if (common->utf) |
4024 | { | { |
4025 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); |
4026 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); |
4027 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); |
4028 | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
4029 | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
4030 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
4031 | } | } |
# | Line 4006 pcre_uint32 oc, bit; | Line 4056 pcre_uint32 oc, bit; |
4056 | SLJIT_ASSERT(common->req_char_ptr != 0); | SLJIT_ASSERT(common->req_char_ptr != 0); |
4057 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); |
4058 | OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); | OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX); |
4059 | toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); | toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0); |
4060 | alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); | alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); |
4061 | ||
4062 | if (has_firstchar) | if (has_firstchar) |
4063 | OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); | OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
# | Line 4015 else | Line 4065 else |
4065 | OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); | OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0); |
4066 | ||
4067 | loop = LABEL(); | loop = LABEL(); |
4068 | notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0); | notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0); |
4069 | ||
4070 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0); |
4071 | oc = req_char; | oc = req_char; |
# | Line 4028 if (caseless) | Line 4078 if (caseless) |
4078 | #endif | #endif |
4079 | } | } |
4080 | if (req_char == oc) | if (req_char == oc) |
4081 | found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); | found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); |
4082 | else | else |
4083 | { | { |
4084 | bit = req_char ^ oc; | bit = req_char ^ oc; |
4085 | if (is_powerof2(bit)) | if (is_powerof2(bit)) |
4086 | { | { |
4087 | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); |
4088 | found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); | found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); |
4089 | } | } |
4090 | else | else |
4091 | { | { |
4092 | found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char); | found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char); |
4093 | foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc); | foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc); |
4094 | } | } |
4095 | } | } |
4096 | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); |
# | Line 4069 GET_LOCAL_BASE(TMP3, 0, 0); | Line 4119 GET_LOCAL_BASE(TMP3, 0, 0); |
4119 | mainloop = LABEL(); | mainloop = LABEL(); |
4120 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); |
4121 | OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); | OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); |
4122 | jump = JUMP(SLJIT_C_SIG_LESS_EQUAL); | jump = JUMP(SLJIT_SIG_LESS_EQUAL); |
4123 | ||
4124 | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); |
4125 | OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); | OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); |
# | Line 4078 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I | Line 4128 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I |
4128 | JUMPTO(SLJIT_JUMP, mainloop); | JUMPTO(SLJIT_JUMP, mainloop); |
4129 | ||
4130 | JUMPHERE(jump); | JUMPHERE(jump); |
4131 | jump = JUMP(SLJIT_C_SIG_LESS); | jump = JUMP(SLJIT_SIG_LESS); |
4132 | /* End of dropping frames. */ | /* End of dropping frames. */ |
4133 | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
4134 | ||
# | Line 4106 sljit_emit_fast_enter(compiler, SLJIT_ME | Line 4156 sljit_emit_fast_enter(compiler, SLJIT_ME |
4156 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
4157 | 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)); |
4158 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0); |
4159 | skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); | skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); |
4160 | skip_char_back(common); | skip_char_back(common); |
4161 | check_start_used_ptr(common); | check_start_used_ptr(common); |
4162 | read_char(common); | read_char(common); |
# | Line 4116 read_char(common); | Line 4166 read_char(common); |
4166 | if (common->use_ucp) | if (common->use_ucp) |
4167 | { | { |
4168 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); |
4169 | jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); | jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); |
4170 | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
4171 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); |
4172 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); |
4173 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
4174 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); |
4175 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); |
4176 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
4177 | JUMPHERE(jump); | JUMPHERE(jump); |
4178 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); |
4179 | } | } |
# | Line 4131 else | Line 4181 else |
4181 | #endif | #endif |
4182 | { | { |
4183 | #ifndef COMPILE_PCRE8 | #ifndef COMPILE_PCRE8 |
4184 | jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
4185 | #elif defined SUPPORT_UTF | #elif defined SUPPORT_UTF |
4186 | /* Here LOCALS1 has already been zeroed. */ | /* Here LOCALS1 has already been zeroed. */ |
4187 | jump = NULL; | jump = NULL; |
4188 | if (common->utf) | if (common->utf) |
4189 | jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
4190 | #endif /* COMPILE_PCRE8 */ | #endif /* COMPILE_PCRE8 */ |
4191 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); |
4192 | OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); | OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); |
# | Line 4160 peek_char(common, READ_CHAR_MAX); | Line 4210 peek_char(common, READ_CHAR_MAX); |
4210 | if (common->use_ucp) | if (common->use_ucp) |
4211 | { | { |
4212 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); |
4213 | jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); | jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); |
4214 | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
4215 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); |
4216 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); |
4217 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
4218 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); |
4219 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); |
4220 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
4221 | JUMPHERE(jump); | JUMPHERE(jump); |
4222 | } | } |
4223 | else | else |
# | Line 4176 else | Line 4226 else |
4226 | #ifndef COMPILE_PCRE8 | #ifndef COMPILE_PCRE8 |
4227 | /* TMP2 may be destroyed by peek_char. */ | /* TMP2 may be destroyed by peek_char. */ |
4228 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
4229 | jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
4230 | #elif defined SUPPORT_UTF | #elif defined SUPPORT_UTF |
4231 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
4232 | jump = NULL; | jump = NULL; |
4233 | if (common->utf) | if (common->utf) |
4234 | jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
4235 | #endif | #endif |
4236 | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); |
4237 | OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); | OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); |
# | Line 4256 switch(length) | Line 4306 switch(length) |
4306 | return TRUE; | return TRUE; |
4307 | ||
4308 | case 1: | case 1: |
4309 | add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); | add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); |
4310 | return TRUE; | return TRUE; |
4311 | ||
4312 | case 2: | case 2: |
4313 | if (ranges[0] + 1 != ranges[1]) | if (ranges[0] + 1 != ranges[1]) |
4314 | { | { |
4315 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); |
4316 | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); |
4317 | } | } |
4318 | else | else |
4319 | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); |
4320 | return TRUE; | return TRUE; |
4321 | ||
4322 | case 3: | case 3: |
4323 | if (bit != 0) | if (bit != 0) |
4324 | { | { |
4325 | add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); | add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); |
4326 | if (ranges[0] + 1 != ranges[1]) | if (ranges[0] + 1 != ranges[1]) |
4327 | { | { |
4328 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); |
4329 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); |
4330 | } | } |
4331 | else | else |
4332 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); |
4333 | return TRUE; | return TRUE; |
4334 | } | } |
4335 | ||
4336 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0])); |
4337 | if (ranges[1] + 1 != ranges[2]) | if (ranges[1] + 1 != ranges[2]) |
4338 | { | { |
4339 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]); |
4340 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); |
4341 | } | } |
4342 | else | else |
4343 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1])); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1])); |
4344 | return TRUE; | return TRUE; |
4345 | ||
4346 | case 4: | case 4: |
4347 | if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) | if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) |
4348 | && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] | && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] |
4349 | && (ranges[1] & (ranges[2] - ranges[0])) == 0 | |
4350 | && is_powerof2(ranges[2] - ranges[0])) | && is_powerof2(ranges[2] - ranges[0])) |
4351 | { | { |
4352 | SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0); | |
4353 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); |
4354 | if (ranges[2] + 1 != ranges[3]) | if (ranges[2] + 1 != ranges[3]) |
4355 | { | { |
4356 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); |
4357 | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); |
4358 | } | } |
4359 | else | else |
4360 | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); | add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); |
4361 | return TRUE; | return TRUE; |
4362 | } | } |
4363 | ||
# | Line 4315 switch(length) | Line 4367 switch(length) |
4367 | if (ranges[0] + 1 != ranges[1]) | if (ranges[0] + 1 != ranges[1]) |
4368 | { | { |
4369 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); |
4370 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); |
4371 | i = ranges[0]; | i = ranges[0]; |
4372 | } | } |
4373 | else | else |
4374 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0])); |
4375 | ||
4376 | if (ranges[2] + 1 != ranges[3]) | if (ranges[2] + 1 != ranges[3]) |
4377 | { | { |
4378 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i); |
4379 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); |
4380 | } | } |
4381 | else | else |
4382 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i)); |
4383 | return TRUE; | return TRUE; |
4384 | } | } |
4385 | ||
4386 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]); |
4387 | add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0])); |
4388 | if (ranges[1] + 1 != ranges[2]) | if (ranges[1] + 1 != ranges[2]) |
4389 | { | { |
4390 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]); |
4391 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1])); |
4392 | } | } |
4393 | else | else |
4394 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0])); |
4395 | return TRUE; | return TRUE; |
4396 | ||
4397 | default: | default: |
# | Line 4357 sljit_emit_fast_enter(compiler, RETURN_A | Line 4409 sljit_emit_fast_enter(compiler, RETURN_A |
4409 | ||
4410 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); |
4411 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); |
4412 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
4413 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); |
4414 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
4415 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4416 | if (common->utf) | if (common->utf) |
4417 | { | { |
4418 | #endif | #endif |
4419 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4420 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); |
4421 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); |
4422 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4423 | } | } |
4424 | #endif | #endif |
4425 | #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ | #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ |
4426 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4427 | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
4428 | } | } |
4429 | ||
# | Line 4383 DEFINE_COMPILER; | Line 4435 DEFINE_COMPILER; |
4435 | sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); | sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
4436 | ||
4437 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); |
4438 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
4439 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); |
4440 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4441 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); |
4442 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
4443 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4444 | if (common->utf) | if (common->utf) |
4445 | { | { |
4446 | #endif | #endif |
4447 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4448 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); |
4449 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4450 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); |
4451 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4452 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); |
4453 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); |
4454 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
4455 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); |
4456 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4457 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); |
4458 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4459 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); |
4460 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4461 | } | } |
4462 | #endif | #endif |
4463 | #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ | #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ |
4464 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4465 | ||
4466 | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
4467 | } | } |
# | Line 4423 sljit_emit_fast_enter(compiler, RETURN_A | Line 4475 sljit_emit_fast_enter(compiler, RETURN_A |
4475 | ||
4476 | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); | OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); |
4477 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); |
4478 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
4479 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); |
4480 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
4481 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4482 | if (common->utf) | if (common->utf) |
4483 | { | { |
4484 | #endif | #endif |
4485 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4486 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); |
4487 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); |
4488 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4489 | } | } |
4490 | #endif | #endif |
4491 | #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ | #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ |
4492 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
4493 | ||
4494 | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); | sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
4495 | } | } |
# | Line 4461 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, S | Line 4513 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, S |
4513 | label = LABEL(); | label = LABEL(); |
4514 | OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); | OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); |
4515 | OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
4516 | jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); | jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0); |
4517 | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); |
4518 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
4519 | ||
4520 | JUMPHERE(jump); | JUMPHERE(jump); |
4521 | 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)); |
# | Line 4494 label = LABEL(); | Line 4546 label = LABEL(); |
4546 | OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); | OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1)); |
4547 | OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
4548 | #ifndef COMPILE_PCRE8 | #ifndef COMPILE_PCRE8 |
4549 | jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255); |
4550 | #endif | #endif |
4551 | OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); | OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); |
4552 | #ifndef COMPILE_PCRE8 | #ifndef COMPILE_PCRE8 |
4553 | JUMPHERE(jump); | JUMPHERE(jump); |
4554 | jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255); |
4555 | #endif | #endif |
4556 | OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); | OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); |
4557 | #ifndef COMPILE_PCRE8 | #ifndef COMPILE_PCRE8 |
4558 | JUMPHERE(jump); | JUMPHERE(jump); |
4559 | #endif | #endif |
4560 | jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0); | jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0); |
4561 | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); |
4562 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
4563 | ||
4564 | JUMPHERE(jump); | JUMPHERE(jump); |
4565 | 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)); |
# | Line 4555 return src2; | Line 4607 return src2; |
4607 | #endif /* SUPPORT_UTF && SUPPORT_UCP */ | #endif /* SUPPORT_UTF && SUPPORT_UCP */ |
4608 | ||
4609 | 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, |
4610 | compare_context* context, jump_list **backtracks) | compare_context *context, jump_list **backtracks) |
4611 | { | { |
4612 | DEFINE_COMPILER; | DEFINE_COMPILER; |
4613 | unsigned int othercasebit = 0; | unsigned int othercasebit = 0; |
# | Line 4655 do | Line 4707 do |
4707 | case 4 / sizeof(pcre_uchar): | case 4 / sizeof(pcre_uchar): |
4708 | if (context->oc.asint != 0) | if (context->oc.asint != 0) |
4709 | 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); |
4710 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); |
4711 | break; | break; |
4712 | ||
4713 | case 2 / sizeof(pcre_uchar): | case 2 / sizeof(pcre_uchar): |
4714 | if (context->oc.asushort != 0) | if (context->oc.asushort != 0) |
4715 | 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); |
4716 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort)); |
4717 | break; | break; |
4718 | ||
4719 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4720 | case 1: | case 1: |
4721 | if (context->oc.asbyte != 0) | if (context->oc.asbyte != 0) |
4722 | 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); |
4723 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte)); |
4724 | break; | break; |
4725 | #endif | #endif |
4726 | ||
# | Line 4690 do | Line 4742 do |
4742 | if (othercasebit != 0 && othercasechar == cc) | if (othercasebit != 0 && othercasechar == cc) |
4743 | { | { |
4744 | OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); | OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit); |
4745 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit)); |
4746 | } | } |
4747 | else | else |
4748 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc)); |
4749 | ||
4750 | #endif | #endif |
4751 | ||
# | Line 4847 while (*cc != XCL_END) | Line 4899 while (*cc != XCL_END) |
4899 | ||
4900 | /* We are not necessary in utf mode even in 8 bit mode. */ | /* We are not necessary in utf mode even in 8 bit mode. */ |
4901 | cc = ccbegin; | cc = ccbegin; |
detect_partial_match(common, backtracks); | ||
4902 | read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); | read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); |
4903 | ||
4904 | if ((cc[-1] & XCL_HASPROP) == 0) | if ((cc[-1] & XCL_HASPROP) == 0) |
4905 | { | { |
4906 | if ((cc[-1] & XCL_MAP) != 0) | if ((cc[-1] & XCL_MAP) != 0) |
4907 | { | { |
4908 | jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
4909 | if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found)) | if (!check_class_ranges(common, (const sljit_ub *)cc, (((const sljit_ub *)cc)[31] & 0x80) != 0, TRUE, &found)) |
4910 | { | { |
4911 | OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); | OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); |
4912 | OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); | OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); |
4913 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); |
4914 | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
4915 | 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); |
4916 | add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO)); | add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); |
4917 | } | } |
4918 | ||
4919 | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
# | Line 4873 if ((cc[-1] & XCL_HASPROP) == 0) | Line 4924 if ((cc[-1] & XCL_HASPROP) == 0) |
4924 | else | else |
4925 | { | { |
4926 | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); | OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min); |
4927 | add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, max - min)); | add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min)); |
4928 | } | } |
4929 | } | } |
4930 | else if ((cc[-1] & XCL_MAP) != 0) | else if ((cc[-1] & XCL_MAP) != 0) |
# | Line 4885 else if ((cc[-1] & XCL_MAP) != 0) | Line 4936 else if ((cc[-1] & XCL_MAP) != 0) |
4936 | if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list)) | if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list)) |
4937 | { | { |
4938 | #ifdef COMPILE_PCRE8 | #ifdef COMPILE_PCRE8 |
4939 | SLJIT_ASSERT(common->utf); | jump = NULL; |
4940 | if (common->utf) | |
4941 | #endif | #endif |
4942 | jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
4943 | ||
4944 | OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); | OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); |
4945 | OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); | OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); |
4946 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); |
4947 | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
4948 | 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); |
4949 | add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); | add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); |
4950 | ||
4951 | JUMPHERE(jump); | #ifdef COMPILE_PCRE8 |
4952 | if (common->utf) | |
4953 | #endif | |
4954 | JUMPHERE(jump); | |
4955 | } | } |
4956 | ||
4957 | OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); | OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
# | Line 4964 while (*cc != XCL_END) | Line 5019 while (*cc != XCL_END) |
5019 | if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) | if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) |
5020 | { | { |
5021 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); |
5022 | OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL); |
5023 | numberofcmps++; | numberofcmps++; |
5024 | } | } |
5025 | else if (numberofcmps > 0) | else if (numberofcmps > 0) |
5026 | { | { |
5027 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); |
5028 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5029 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5030 | numberofcmps = 0; | numberofcmps = 0; |
5031 | } | } |
5032 | else | else |
5033 | { | { |
5034 | jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); | jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); |
5035 | numberofcmps = 0; | numberofcmps = 0; |
5036 | } | } |
5037 | } | } |
# | Line 4990 while (*cc != XCL_END) | Line 5045 while (*cc != XCL_END) |
5045 | if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) | if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) |
5046 | { | { |
5047 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); |
5048 | OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL); |
5049 | numberofcmps++; | numberofcmps++; |
5050 | } | } |
5051 | else if (numberofcmps > 0) | else if (numberofcmps > 0) |
5052 | { | { |
5053 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); |
5054 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
5055 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5056 | numberofcmps = 0; | numberofcmps = 0; |
5057 | } | } |
5058 | else | else |
5059 | { | { |
5060 | jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); | jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset)); |
5061 | numberofcmps = 0; | numberofcmps = 0; |
5062 | } | } |
5063 | } | } |
# | Line 5027 while (*cc != XCL_END) | Line 5082 while (*cc != XCL_END) |
5082 | ||
5083 | case PT_LAMP: | case PT_LAMP: |
5084 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); |
5085 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5086 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); |
5087 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5088 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); |
5089 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5090 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5091 | break; | break; |
5092 | ||
5093 | case PT_GC: | case PT_GC: |
5094 | c = PRIV(ucp_typerange)[(int)cc[1] * 2]; | c = PRIV(ucp_typerange)[(int)cc[1] * 2]; |
5095 | SET_TYPE_OFFSET(c); | SET_TYPE_OFFSET(c); |
5096 | jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); | jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); |
5097 | break; | break; |
5098 | ||
5099 | case PT_PC: | case PT_PC: |
5100 | jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); | jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); |
5101 | break; | break; |
5102 | ||
5103 | case PT_SC: | case PT_SC: |
5104 | jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); | jump = CMP(SLJIT_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); |
5105 | break; | break; |
5106 | ||
5107 | case PT_SPACE: | case PT_SPACE: |
5108 | case PT_PXSPACE: | case PT_PXSPACE: |
5109 | SET_CHAR_OFFSET(9); | SET_CHAR_OFFSET(9); |
5110 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9); |
5111 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
5112 | ||
5113 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9); |
5114 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5115 | ||
5116 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); |
5117 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5118 | ||
5119 | SET_TYPE_OFFSET(ucp_Zl); | SET_TYPE_OFFSET(ucp_Zl); |
5120 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); |
5121 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
5122 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5123 | break; | break; |
5124 | ||
5125 | case PT_WORD: | case PT_WORD: |
5126 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); |
5127 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5128 | /* Fall through. */ | /* Fall through. */ |
5129 | ||
5130 | case PT_ALNUM: | case PT_ALNUM: |
5131 | SET_TYPE_OFFSET(ucp_Ll); | SET_TYPE_OFFSET(ucp_Ll); |
5132 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); |
5133 | OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL); |
5134 | SET_TYPE_OFFSET(ucp_Nd); | SET_TYPE_OFFSET(ucp_Nd); |
5135 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); |
5136 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
5137 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5138 | break; | break; |
5139 | ||
5140 | case PT_CLIST: | case PT_CLIST: |
# | Line 5101 while (*cc != XCL_END) | Line 5156 while (*cc != XCL_END) |
5156 | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); |
5157 | } | } |
5158 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); |
5159 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5160 | other_cases += 2; | other_cases += 2; |
5161 | } | } |
5162 | else if (is_powerof2(other_cases[2] ^ other_cases[1])) | else if (is_powerof2(other_cases[2] ^ other_cases[1])) |
# | Line 5114 while (*cc != XCL_END) | Line 5169 while (*cc != XCL_END) |
5169 | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); | OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); |
5170 | } | } |
5171 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); |
5172 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5173 | ||
5174 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset)); |
5175 | OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5176 | ||
5177 | other_cases += 3; | other_cases += 3; |
5178 | } | } |
5179 | else | else |
5180 | { | { |
5181 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); |
5182 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5183 | } | } |
5184 | ||
5185 | while (*other_cases != NOTACHAR) | while (*other_cases != NOTACHAR) |
5186 | { | { |
5187 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset)); |
5188 | OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5189 | } | } |
5190 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5191 | break; | break; |
5192 | ||
5193 | case PT_UCNC: | case PT_UCNC: |
5194 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset)); |
5195 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5196 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset)); |
5197 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5198 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset)); |
5199 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5200 | ||
5201 | SET_CHAR_OFFSET(0xa0); | SET_CHAR_OFFSET(0xa0); |
5202 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset)); |
5203 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
5204 | SET_CHAR_OFFSET(0); | SET_CHAR_OFFSET(0); |
5205 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0); |
5206 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL); |
5207 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5208 | break; | break; |
5209 | ||
5210 | case PT_PXGRAPH: | case PT_PXGRAPH: |
5211 | /* C and Z groups are the farthest two groups. */ | /* C and Z groups are the farthest two groups. */ |
5212 | SET_TYPE_OFFSET(ucp_Ll); | SET_TYPE_OFFSET(ucp_Ll); |
5213 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); |
5214 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER); |
5215 | ||
5216 | jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); | jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); |
5217 | ||
5218 | /* In case of ucp_Cf, we overwrite the result. */ | /* In case of ucp_Cf, we overwrite the result. */ |
5219 | SET_CHAR_OFFSET(0x2066); | SET_CHAR_OFFSET(0x2066); |
5220 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); |
5221 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
5222 | ||
5223 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); |
5224 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5225 | ||
5226 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); |
5227 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5228 | ||
5229 | JUMPHERE(jump); | JUMPHERE(jump); |
5230 | jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); | jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); |
5231 | break; | break; |
5232 | ||
5233 | case PT_PXPRINT: | case PT_PXPRINT: |
5234 | /* C and Z groups are the farthest two groups. */ | /* C and Z groups are the farthest two groups. */ |
5235 | SET_TYPE_OFFSET(ucp_Ll); | SET_TYPE_OFFSET(ucp_Ll); |
5236 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); |
5237 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER); |
5238 | ||
5239 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); |
5240 | OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL); | OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); |
5241 | ||
5242 | jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); | jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); |
5243 | ||
5244 | /* In case of ucp_Cf, we overwrite the result. */ | /* In case of ucp_Cf, we overwrite the result. */ |
5245 | SET_CHAR_OFFSET(0x2066); | SET_CHAR_OFFSET(0x2066); |
5246 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); |
5247 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
5248 | ||
5249 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); |
5250 | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL); |
5251 | ||
5252 | JUMPHERE(jump); | JUMPHERE(jump); |
5253 | jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); | jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); |
5254 | break; | break; |
5255 | ||
5256 | case PT_PXPUNCT: | case PT_PXPUNCT: |
5257 | SET_TYPE_OFFSET(ucp_Sc); | SET_TYPE_OFFSET(ucp_Sc); |
5258 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); |
5259 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); |
5260 | ||
5261 | SET_CHAR_OFFSET(0); | SET_CHAR_OFFSET(0); |
5262 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f); |
5263 | OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
5264 | ||
5265 | SET_TYPE_OFFSET(ucp_Pc); | SET_TYPE_OFFSET(ucp_Pc); |
5266 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); |
5267 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); |
5268 | jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); | jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); |
5269 | break; | break; |
5270 | } | } |
5271 | cc += 2; | cc += 2; |
# | Line 5230 if (found != NULL) | Line 5285 if (found != NULL) |
5285 | ||
5286 | #endif | #endif |
5287 | ||
5288 | static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) | static pcre_uchar *compile_simple_assertion_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) |
5289 | { | { |
5290 | DEFINE_COMPILER; | DEFINE_COMPILER; |
5291 | int length; | int length; |
unsigned int c, oc, bit; | ||
compare_context context; | ||
5292 | struct sljit_jump *jump[4]; | struct sljit_jump *jump[4]; |
jump_list *end_list; | ||
5293 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
5294 | struct sljit_label *label; | struct sljit_label *label; |
#ifdef SUPPORT_UCP | ||
pcre_uchar propdata[5]; | ||
#endif | ||
5295 | #endif /* SUPPORT_UTF */ | #endif /* SUPPORT_UTF */ |
5296 | ||
5297 | switch(type) | switch(type) |
# | Line 5250 switch(type) | Line 5299 switch(type) |
5299 | case OP_SOD: | case OP_SOD: |
5300 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
5301 | 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)); |
5302 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); |
5303 | return cc; | return cc; |
5304 | ||
5305 | case OP_SOM: | case OP_SOM: |
5306 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
5307 | 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)); |
5308 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); |
5309 | return cc; | return cc; |
5310 | ||
5311 | case OP_NOT_WORD_BOUNDARY: | case OP_NOT_WORD_BOUNDARY: |
5312 | case OP_WORD_BOUNDARY: | case OP_WORD_BOUNDARY: |
5313 | add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); |
5314 | add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); | add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); |
5315 | return cc; | |
5316 | ||
5317 | case OP_EODN: | |
5318 | /* Requires rather complex checks. */ | |
5319 | jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | |
5320 | if (common->nltype == NLTYPE_FIXED && common->newline > 255) | |
5321 | { | |
5322 | OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | |
5323 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | |
5324 | if (common->mode == JIT_COMPILE) | |
5325 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); | |
5326 | else | |
5327 | { | |
5328 | jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); | |
5329 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); | |
5330 | OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS); | |
5331 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); | |
5332 | OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); | |
5333 | add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); | |
5334 | check_partial(common, TRUE); | |
5335 | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | |
5336 | JUMPHERE(jump[1]); | |
5337 | } | |
5338 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | |
5339 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | |
5340 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); | |
5341 | } | |
5342 | else if (common->nltype == NLTYPE_FIXED) | |
5343 | { | |
5344 | OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); | |
5345 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | |
5346 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); | |
5347 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); | |
5348 | } | |
5349 | else | |
5350 | { | |
5351 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | |
5352 | jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); | |
5353 | OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | |
5354 | OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); | |
5355 | jump[2] = JUMP(SLJIT_GREATER); | |
5356 | add_jump(compiler, backtracks, JUMP(SLJIT_LESS)); | |
5357 | /* Equal. */ | |
5358 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | |
5359 | jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); | |
5360 | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | |
5361 | ||
5362 | JUMPHERE(jump[1]); | |
5363 | if (common->nltype == NLTYPE_ANYCRLF) | |
5364 | { | |
5365 | OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); | |
5366 | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); | |
5367 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); | |
5368 | } | |
5369 | else | |
5370 | { | |
5371 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); | |
5372 | read_char_range(common, common->nlmin, common->nlmax, TRUE); | |
5373 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); | |
5374 | add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); | |
5375 | add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); | |
5376 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); | |
5377 | } | |
5378 | JUMPHERE(jump[2]); | |
5379 | JUMPHERE(jump[3]); | |
5380 | } | |
5381 | JUMPHERE(jump[0]); | |
5382 | check_partial(common, FALSE); | |
5383 | return cc; | |
5384 | ||
5385 | case OP_EOD: | |
5386 | add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); | |
5387 | check_partial(common, FALSE); | |
5388 | return cc; | |
5389 | ||
5390 | case OP_DOLL: | |
5391 | OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | |
5392 | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); | |
5393 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | |
5394 | ||
5395 | if (!common->endonly) | |
5396 | compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); | |
5397 | else | |
5398 | { | |
5399 | add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); | |
5400 | check_partial(common, FALSE); | |
5401 | } | |
5402 | return cc; | return cc; |
5403 | ||
5404 | case OP_DOLLM: | |
5405 | jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); | |
5406 | OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | |
5407 | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); | |
5408 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | |
5409 | check_partial(common, FALSE); | |
5410 | jump[0] = JUMP(SLJIT_JUMP); | |
5411 | JUMPHERE(jump[1]); | |
5412 | ||
5413 | if (common->nltype == NLTYPE_FIXED && common->newline > 255) | |
5414 | { | |
5415 | OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | |
5416 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | |
5417 | if (common->mode == JIT_COMPILE) | |
5418 | add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); | |
5419 | else | |
5420 | { | |
5421 | jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); | |
5422 | /* STR_PTR = STR_END - IN_UCHARS(1) */ | |
5423 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | |
5424 | check_partial(common, TRUE); | |
5425 | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | |
5426 | JUMPHERE(jump[1]); | |
5427 | } | |
5428 | ||
5429 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | |
5430 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | |
5431 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); | |
5432 | } | |
5433 | else | |
5434 | { | |
5435 | peek_char(common, common->nlmax); | |
5436 | check_newlinechar(common, common->nltype, backtracks, FALSE); | |
5437 | } | |
5438 | JUMPHERE(jump[0]); | |
5439 | return cc; | |
5440 | ||
5441 | case OP_CIRC: | |
5442 | OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | |
5443 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); | |
5444 | add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); | |
5445 | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); | |
5446 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | |
5447 | return cc; | |
5448 | ||
5449 | case OP_CIRCM: | |
5450 | OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | |
5451 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); | |
5452 | jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); | |
5453 | OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); | |
5454 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | |
5455 | jump[0] = JUMP(SLJIT_JUMP); | |
5456 | JUMPHERE(jump[1]); | |
5457 | ||
5458 | add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); | |
5459 | if (common->nltype == NLTYPE_FIXED && common->newline > 255) | |
5460 | { | |
5461 | OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | |
5462 | add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); | |
5463 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); | |
5464 | OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); | |
5465 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | |
5466 | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); | |
5467 | } | |
5468 | else | |
5469 | { | |
5470 | skip_char_back(common); | |
5471 | read_char_range(common, common->nlmin, common->nlmax, TRUE); | |
5472 | check_newlinechar(common, common->nltype, backtracks, FALSE); | |
5473 | } | |
5474 | JUMPHERE(jump[0]); | |
5475 | return cc; | |
5476 | ||
5477 | case OP_REVERSE: | |
5478 | length = GET(cc, 0); | |
5479 | if (length == 0) | |
5480 | return cc + LINK_SIZE; | |
5481 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | |
5482 | #ifdef SUPPORT_UTF | |
5483 | if (common->utf) | |
5484 | { | |
5485 | OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); | |
5486 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); | |
5487 | label = LABEL(); | |
5488 | add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); | |
5489 | skip_char_back(common); | |
5490 | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); | |
5491 | JUMPTO(SLJIT_NOT_ZERO, label); | |
5492 | } | |
5493 | else | |
5494 | #endif | |
5495 | { | |
5496 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); | |
5497 | OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); | |
5498 | add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0)); | |
5499 | } | |
5500 | check_start_used_ptr(common); | |
5501 | return cc + LINK_SIZE; | |
5502 | } | |
5503 | SLJIT_ASSERT_STOP(); | |
5504 | return cc; | |
5505 | } | |
5506 | ||
5507 | static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks, BOOL check_str_ptr) | |
5508 | { | |
5509 | DEFINE_COMPILER; | |
5510 | int length; | |
5511 | unsigned int c, oc, bit; | |
5512 | compare_context context; | |
5513 | struct sljit_jump *jump[3]; | |
5514 | jump_list *end_list; | |
5515 | #ifdef SUPPORT_UTF | |
5516 | struct sljit_label *label; | |
5517 | #ifdef SUPPORT_UCP | |
5518 | pcre_uchar propdata[5]; | |
5519 | #endif | |
5520 | #endif /* SUPPORT_UTF */ | |
5521 | ||
5522 | switch(type) | |
5523 | { | |
5524 | case OP_NOT_DIGIT: | case OP_NOT_DIGIT: |
5525 | case OP_DIGIT: | case OP_DIGIT: |
5526 | /* Digits are usually 0-9, so it is worth to optimize them. */ | /* Digits are usually 0-9, so it is worth to optimize them. */ |
5527 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5528 | detect_partial_match(common, backtracks); | |
5529 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 |
5530 | if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE)) | if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE)) |
5531 | read_char7_type(common, type == OP_NOT_DIGIT); | read_char7_type(common, type == OP_NOT_DIGIT); |
# | Line 5277 switch(type) | Line 5534 switch(type) |
5534 | read_char8_type(common, type == OP_NOT_DIGIT); | read_char8_type(common, type == OP_NOT_DIGIT); |
5535 | /* Flip the starting bit in the negative case. */ | /* Flip the starting bit in the negative case. */ |
5536 | 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); |
5537 | add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); | add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); |
5538 | return cc; | return cc; |
5539 | ||
5540 | case OP_NOT_WHITESPACE: | case OP_NOT_WHITESPACE: |
5541 | case OP_WHITESPACE: | case OP_WHITESPACE: |
5542 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5543 | detect_partial_match(common, backtracks); | |
5544 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 |
5545 | if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE)) | if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE)) |
5546 | read_char7_type(common, type == OP_NOT_WHITESPACE); | read_char7_type(common, type == OP_NOT_WHITESPACE); |
# | Line 5290 switch(type) | Line 5548 switch(type) |
5548 | #endif | #endif |
5549 | read_char8_type(common, type == OP_NOT_WHITESPACE); | read_char8_type(common, type == OP_NOT_WHITESPACE); |
5550 | 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); |
5551 | add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); | add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); |
5552 | return cc; | return cc; |
5553 | ||
5554 | case OP_NOT_WORDCHAR: | case OP_NOT_WORDCHAR: |
5555 | case OP_WORDCHAR: | case OP_WORDCHAR: |
5556 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5557 | detect_partial_match(common, backtracks); | |
5558 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 |
5559 | if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE)) | if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE)) |
5560 | read_char7_type(common, type == OP_NOT_WORDCHAR); | read_char7_type(common, type == OP_NOT_WORDCHAR); |
# | Line 5303 switch(type) | Line 5562 switch(type) |
5562 | #endif | #endif |
5563 | read_char8_type(common, type == OP_NOT_WORDCHAR); | read_char8_type(common, type == OP_NOT_WORDCHAR); |
5564 | 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); |
5565 | add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); | add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); |
5566 | return cc; | return cc; |
5567 | ||
5568 | case OP_ANY: | case OP_ANY: |
5569 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5570 | detect_partial_match(common, backtracks); | |
5571 | read_char_range(common, common->nlmin, common->nlmax, TRUE); | read_char_range(common, common->nlmin, common->nlmax, TRUE); |
5572 | if (common->nltype == NLTYPE_FIXED && common->newline > 255) | if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
5573 | { | { |
5574 | jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); | jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
5575 | end_list = NULL; | end_list = NULL; |
5576 | if (common->mode != JIT_PARTIAL_HARD_COMPILE) | if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
5577 | add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); | add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
5578 | else | else |
5579 | check_str_end(common, &end_list); | check_str_end(common, &end_list); |
5580 | ||
5581 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
5582 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); |
5583 | set_jumps(end_list, LABEL()); | set_jumps(end_list, LABEL()); |
5584 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
5585 | } | } |
# | Line 5328 switch(type) | Line 5588 switch(type) |
5588 | return cc; | return cc; |
5589 | ||
5590 | case OP_ALLANY: | case OP_ALLANY: |
5591 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5592 | detect_partial_match(common, backtracks); | |
5593 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
5594 | if (common->utf) | if (common->utf) |
5595 | { | { |
# | Line 5336 switch(type) | Line 5597 switch(type) |
5597 | 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)); |
5598 | #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 | #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 |
5599 | #if defined COMPILE_PCRE8 | #if defined COMPILE_PCRE8 |
5600 | jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); | jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); |
5601 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
5602 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
5603 | #elif defined COMPILE_PCRE16 | #elif defined COMPILE_PCRE16 |
5604 | jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); | jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); |
5605 | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); | OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); |
5606 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); |
5607 | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); | OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); |
5608 | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
5609 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
5610 | #endif | #endif |
# | Line 5356 switch(type) | Line 5617 switch(type) |
5617 | return cc; | return cc; |
5618 | ||
5619 | case OP_ANYBYTE: | case OP_ANYBYTE: |
5620 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5621 | detect_partial_match(common, backtracks); | |
5622 | 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)); |
5623 | return cc; | return cc; |
5624 | ||
# | Line 5369 switch(type) | Line 5631 switch(type) |
5631 | propdata[2] = cc[0]; | propdata[2] = cc[0]; |
5632 | propdata[3] = cc[1]; | propdata[3] = cc[1]; |
5633 | propdata[4] = XCL_END; | propdata[4] = XCL_END; |
5634 | if (check_str_ptr) | |
5635 | detect_partial_match(common, backtracks); | |
5636 | compile_xclass_matchingpath(common, propdata, backtracks); | compile_xclass_matchingpath(common, propdata, backtracks); |
5637 | return cc + 2; | return cc + 2; |
5638 | #endif | #endif |
5639 | #endif | #endif |
5640 | ||
5641 | case OP_ANYNL: | case OP_ANYNL: |
5642 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5643 | detect_partial_match(common, backtracks); | |
5644 | read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); | read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); |
5645 | jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); | jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
5646 | /* We don't need to handle soft partial matching case. */ | /* We don't need to handle soft partial matching case. */ |
5647 | end_list = NULL; | end_list = NULL; |
5648 | if (common->mode != JIT_PARTIAL_HARD_COMPILE) | if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
5649 | add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); | add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
5650 | else | else |
5651 | check_str_end(common, &end_list); | check_str_end(common, &end_list); |
5652 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
5653 | jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); | jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); |
5654 | 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)); |
5655 | jump[2] = JUMP(SLJIT_JUMP); | jump[2] = JUMP(SLJIT_JUMP); |
5656 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
# | Line 5397 switch(type) | Line 5662 switch(type) |
5662 | ||
5663 | case OP_NOT_HSPACE: | case OP_NOT_HSPACE: |
5664 | case OP_HSPACE: | case OP_HSPACE: |
5665 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5666 | detect_partial_match(common, backtracks); | |
5667 | read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); | read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); |
5668 | add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
5669 | add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); | add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); |
5670 | return cc; | return cc; |
5671 | ||
5672 | case OP_NOT_VSPACE: | case OP_NOT_VSPACE: |
5673 | case OP_VSPACE: | case OP_VSPACE: |
5674 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5675 | detect_partial_match(common, backtracks); | |
5676 | read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); | read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); |
5677 | add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
5678 | add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); | add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); |
5679 | return cc; | return cc; |
5680 | ||
5681 | #ifdef SUPPORT_UCP | #ifdef SUPPORT_UCP |
5682 | case OP_EXTUNI: | case OP_EXTUNI: |
5683 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5684 | detect_partial_match(common, backtracks); | |
5685 | read_char(common); | read_char(common); |
5686 | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
5687 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); |
# | Line 5422 switch(type) | Line 5690 switch(type) |
5690 | OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); | OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); |
5691 | ||
5692 | label = LABEL(); | label = LABEL(); |
5693 | jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
5694 | OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); | OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); |
5695 | read_char(common); | read_char(common); |
5696 | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); | add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
# | Line 5434 switch(type) | Line 5702 switch(type) |
5702 | OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); | OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); |
5703 | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
5704 | 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); |
5705 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
5706 | ||
5707 | OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); | OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
5708 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
# | Line 5442 switch(type) | Line 5710 switch(type) |
5710 | ||
5711 | if (common->mode == JIT_PARTIAL_HARD_COMPILE) | if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
5712 | { | { |
5713 | jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); | jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); |
5714 | /* Since we successfully read a char above, partial matching must occure. */ | /* Since we successfully read a char above, partial matching must occure. */ |
5715 | check_partial(common, TRUE); | check_partial(common, TRUE); |
5716 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
# | Line 5450 switch(type) | Line 5718 switch(type) |
5718 | return cc; | return cc; |
5719 | #endif | #endif |
5720 | ||
case OP_EODN: | ||
/* Requires rather complex checks. */ | ||
jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); | ||
if (common->nltype == NLTYPE_FIXED && common->newline > 255) | ||
{ | ||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | ||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | ||
if (common->mode == JIT_COMPILE) | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); | ||
else | ||
{ | ||
jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); | ||
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); | ||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS); | ||
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); | ||
OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL); | ||
add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); | ||
check_partial(common, TRUE); | ||
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | ||
JUMPHERE(jump[1]); | ||
} | ||
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); | ||
} | ||
else if (common->nltype == NLTYPE_FIXED) | ||
{ | ||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); | ||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); | ||
} | ||
else | ||
{ | ||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | ||
jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); | ||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | ||
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); | ||
jump[2] = JUMP(SLJIT_C_GREATER); | ||
add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS)); | ||
/* Equal. */ | ||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | ||
jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); | ||
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | ||
JUMPHERE(jump[1]); | ||
if (common->nltype == NLTYPE_ANYCRLF) | ||
{ | ||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); | ||
} | ||
else | ||
{ | ||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); | ||
read_char_range(common, common->nlmin, common->nlmax, TRUE); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); | ||
add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); | ||
add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); | ||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); | ||
} | ||
JUMPHERE(jump[2]); | ||
JUMPHERE(jump[3]); | ||
} | ||
JUMPHERE(jump[0]); | ||
check_partial(common, FALSE); | ||
return cc; | ||
case OP_EOD: | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); | ||
check_partial(common, FALSE); | ||
return cc; | ||
case OP_CIRC: | ||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | ||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0)); | ||
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | ||
return cc; | ||
case OP_CIRCM: | ||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | ||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); | ||
jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0); | ||
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | ||
jump[0] = JUMP(SLJIT_JUMP); | ||
JUMPHERE(jump[1]); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); | ||
if (common->nltype == NLTYPE_FIXED && common->newline > 255) | ||
{ | ||
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0)); | ||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); | ||
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); | ||
} | ||
else | ||
{ | ||
skip_char_back(common); | ||
read_char_range(common, common->nlmin, common->nlmax, TRUE); | ||
check_newlinechar(common, common->nltype, backtracks, FALSE); | ||
} | ||
JUMPHERE(jump[0]); | ||
return cc; | ||
case OP_DOLL: | ||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | ||
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | ||
if (!common->endonly) | ||
compile_char1_matchingpath(common, OP_EODN, cc, backtracks); | ||
else | ||
{ | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); | ||
check_partial(common, FALSE); | ||
} | ||
return cc; | ||
case OP_DOLLM: | ||
jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); | ||
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); | ||
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | ||
check_partial(common, FALSE); | ||
jump[0] = JUMP(SLJIT_JUMP); | ||
JUMPHERE(jump[1]); | ||
if (common->nltype == NLTYPE_FIXED && common->newline > 255) | ||
{ | ||
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); | ||
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); | ||
if (common->mode == JIT_COMPILE) | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); | ||
else | ||
{ | ||
jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); | ||
/* STR_PTR = STR_END - IN_UCHARS(1) */ | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | ||
check_partial(common, TRUE); | ||
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | ||
JUMPHERE(jump[1]); | ||
} | ||
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); | ||
} | ||
else | ||
{ | ||
peek_char(common, common->nlmax); | ||
check_newlinechar(common, common->nltype, backtracks, FALSE); | ||
} | ||
JUMPHERE(jump[0]); | ||
return cc; | ||
5721 | case OP_CHAR: | case OP_CHAR: |
5722 | case OP_CHARI: | case OP_CHARI: |
5723 | length = 1; | length = 1; |
# | Line 5619 switch(type) | Line 5727 switch(type) |
5727 | 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)) |
5728 | { | { |
5729 | 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)); |
5730 | add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); |
5731 | ||
5732 | context.length = IN_UCHARS(length); | context.length = IN_UCHARS(length); |
5733 | context.sourcereg = -1; | context.sourcereg = -1; |
# | Line 5629 switch(type) | Line 5737 switch(type) |
5737 | return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); | return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); |
5738 | } | } |
5739 | ||
5740 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5741 | detect_partial_match(common, backtracks); | |
5742 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
5743 | if (common->utf) | if (common->utf) |
5744 | { | { |
# | Line 5642 switch(type) | Line 5751 switch(type) |
5751 | if (type == OP_CHAR || !char_has_othercase(common, cc)) | if (type == OP_CHAR || !char_has_othercase(common, cc)) |
5752 | { | { |
5753 | read_char_range(common, c, c, FALSE); | read_char_range(common, c, c, FALSE); |
5754 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
5755 | return cc + length; | return cc + length; |
5756 | } | } |
5757 | oc = char_othercase(common, c); | oc = char_othercase(common, c); |
# | Line 5651 switch(type) | Line 5760 switch(type) |
5760 | if (is_powerof2(bit)) | if (is_powerof2(bit)) |
5761 | { | { |
5762 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
5763 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
5764 | return cc + length; | return cc + length; |
5765 | } | } |
5766 | jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c); | jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); |
5767 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); |
5768 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
5769 | return cc + length; | return cc + length; |
5770 | ||
5771 | case OP_NOT: | case OP_NOT: |
5772 | case OP_NOTI: | case OP_NOTI: |
5773 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5774 | detect_partial_match(common, backtracks); | |
5775 | length = 1; | length = 1; |
5776 | #ifdef SUPPORT_UTF | #ifdef SUPPORT_UTF |
5777 | if (common->utf) | if (common->utf) |
# | Line 5672 switch(type) | Line 5782 switch(type) |
5782 | { | { |
5783 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
5784 | if (type == OP_NOT || !char_has_othercase(common, cc)) | if (type == OP_NOT || !char_has_othercase(common, cc)) |
5785 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
5786 | else | else |
5787 | { | { |
5788 | /* 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. */ |
5789 | OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); | OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20); |
5790 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20)); |
5791 | } | } |
5792 | /* Skip the variable-length character. */ | /* Skip the variable-length character. */ |
5793 | 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)); |
5794 | jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); | jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); |
5795 | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); | OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); |
5796 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); |
5797 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
# | Line 5700 switch(type) | Line 5810 switch(type) |
5810 | if (type == OP_NOT || !char_has_othercase(common, cc)) | if (type == OP_NOT || !char_has_othercase(common, cc)) |
5811 | { | { |
5812 | read_char_range(common, c, c, TRUE); | read_char_range(common, c, c, TRUE); |
5813 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
5814 | } | } |
5815 | else | else |
5816 | { | { |
# | Line 5710 switch(type) | Line 5820 switch(type) |
5820 | if (is_powerof2(bit)) | if (is_powerof2(bit)) |
5821 | { | { |
5822 | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); | OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
5823 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
5824 | } | } |
5825 | else | else |
5826 | { | { |
5827 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
5828 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); |
5829 | } | } |
5830 | } | } |
5831 | return cc + length; | return cc + length; |
5832 | ||
5833 | case OP_CLASS: | case OP_CLASS: |
5834 | case OP_NCLASS: | case OP_NCLASS: |
5835 | detect_partial_match(common, backtracks); | if (check_str_ptr) |
5836 | detect_partial_match(common, backtracks); | |
5837 | ||
5838 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 |
5839 | bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255; | bit = (common->utf && is_char7_bitset((const sljit_ub *)cc, type == OP_NCLASS)) ? 127 : 255; |
5840 | read_char_range(common, 0, bit, type == OP_NCLASS); | read_char_range(common, 0, bit, type == OP_NCLASS); |
5841 | #else | #else |
5842 | read_char_range(common, 0, 255, type == OP_NCLASS); | read_char_range(common, 0, 255, type == OP_NCLASS); |
5843 | #endif | #endif |
5844 | ||
5845 | if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks)) | if (check_class_ranges(common, (const sljit_ub *)cc, type == OP_NCLASS, FALSE, backtracks)) |
5846 | return cc + 32 / sizeof(pcre_uchar); | return cc + 32 / sizeof(pcre_uchar); |
5847 | ||
5848 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 | #if defined SUPPORT_UTF && defined COMPILE_PCRE8 |
5849 | jump[0] = NULL; | jump[0] = NULL; |
5850 | if (common->utf) | if (common->utf) |
5851 | { | { |
5852 | jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit); | jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit); |
5853 | if (type == OP_CLASS) | if (type == OP_CLASS) |
5854 | { | { |
5855 | add_jump(compiler, backtracks, jump[0]); | add_jump(compiler, backtracks, jump[0]); |
# | Line 5746 switch(type) | Line 5857 switch(type) |
5857 | } | } |
5858 | } | } |
5859 | #elif !defined COMPILE_PCRE8 | #elif !defined COMPILE_PCRE8 |
5860 | jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); | jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); |
5861 | if (type == OP_CLASS) | if (type == OP_CLASS) |
5862 | { | { |
5863 | add_jump(compiler, backtracks, jump[0]); | add_jump(compiler, backtracks, jump[0]); |
# | Line 5759 switch(type) | Line 5870 switch(type) |
5870 | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); | OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); |
5871 | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); | OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); |
5872 | 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); |
5873 | add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); | add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); |
5874 | ||
5875 | #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 | #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
5876 | if (jump[0] != NULL) | if (jump[0] != NULL) |
5877 | JUMPHERE(jump[0]); | JUMPHERE(jump[0]); |
5878 | #endif | #endif |
5879 | return cc + 32 / sizeof(pcre_uchar); | return cc + 32 / sizeof(pcre_uchar); |
5880 | ||
5881 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
5882 | case OP_XCLASS: | case OP_XCLASS: |
5883 | if (check_str_ptr) | |
5884 | detect_partial_match(common, backtracks); | |
5885 | compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); | compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); |
5886 | return cc + GET(cc, 0) - 1; | return cc + GET(cc, 0) - 1; |
5887 | #endif | #endif |
case OP_REVERSE: | ||
length = GET(cc, 0); | ||
if (length == 0) | ||
return cc + LINK_SIZE; | ||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | ||
#ifdef SUPPORT_UTF | ||
if (common->utf) | ||
{ | ||
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); | ||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); | ||
label = LABEL(); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); | ||
skip_char_back(common); | ||
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); | ||
JUMPTO(SLJIT_C_NOT_ZERO, label); | ||
} | ||
else | ||
#endif | ||
{ | ||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); | ||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); | ||
add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); | ||
} | ||
check_start_used_ptr(common); | ||
return cc + LINK_SIZE; | ||
5888 | } | } |
5889 | SLJIT_ASSERT_STOP(); | SLJIT_ASSERT_STOP(); |
5890 | return cc; | return cc; |
# | Line 5856 if (context.length > 0) | Line 5942 if (context.length > 0) |
5942 | { | { |
5943 | /* We have a fixed-length byte sequence. */ | /* We have a fixed-length byte sequence. */ |
5944 | 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); |
5945 | add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); |
5946 | ||
5947 | context.sourcereg = -1; | context.sourcereg = -1; |
5948 | #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED | #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED |
# | Line 5867 if (context.length > 0) | Line 5953 if (context.length > 0) |
5953 | } | } |
5954 | ||
5955 | /* A non-fixed length character will be checked if length == 0. */ | /* A non-fixed length character will be checked if length == 0. */ |
5956 | return compile_char1_matchingpath(common, *cc, cc + 1, backtracks); | return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); |
5957 | } | } |
5958 | ||
5959 | /* Forward definitions. */ | /* Forward definitions. */ |
# | Line 5920 while (count-- > 0) | Line 6006 while (count-- > 0) |
6006 | { | { |
6007 | offset = GET2(slot, 0) << 1; | offset = GET2(slot, 0) << 1; |
6008 | GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); | GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); |
6009 | add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); | add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); |
6010 | slot += common->name_entry_size; | slot += common->name_entry_size; |
6011 | } | } |
6012 | ||
6013 | offset = GET2(slot, 0) << 1; | offset = GET2(slot, 0) << 1; |
6014 | GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); | GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset)); |
6015 | if (backtracks != NULL && !common->jscript_compat) | if (backtracks != NULL && !common->jscript_compat) |
6016 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0)); |
6017 | ||
6018 | set_jumps(found, LABEL()); | set_jumps(found, LABEL()); |
6019 | } | } |
# | Line 5947 if (ref) | Line 6033 if (ref) |
6033 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); |
6034 | /* OVECTOR(1) contains the "string begin - 1" constant. */ | /* OVECTOR(1) contains the "string begin - 1" constant. */ |
6035 | if (withchecks && !common->jscript_compat) | if (withchecks && !common->jscript_compat) |
6036 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); |
6037 | } | } |
6038 | else | else |
6039 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); |
# | Line 5962 if (common->utf && *cc == OP_REFI) | Line 6048 if (common->utf && *cc == OP_REFI) |
6048 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); |
6049 | ||
6050 | if (withchecks) | if (withchecks) |
6051 | jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); | jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0); |
6052 | ||
6053 | /* Needed to save important temporary registers. */ | /* Needed to save important temporary registers. */ |
6054 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); |
# | Line 5971 if (common->utf && *cc == OP_REFI) | Line 6057 if (common->utf && *cc == OP_REFI) |
6057 | 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)); |
6058 | OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); | OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); |
6059 | if (common->mode == JIT_COMPILE) | if (common->mode == JIT_COMPILE) |
6060 | add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); | add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); |
6061 | else | else |
6062 | { | { |
6063 | add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
6064 | nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); | nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
6065 | check_partial(common, FALSE); | check_partial(common, FALSE); |
6066 | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
6067 | JUMPHERE(nopartial); | JUMPHERE(nopartial); |
# | Line 5991 else | Line 6077 else |
6077 | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); | OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0); |
6078 | ||
6079 | if (withchecks) | if (withchecks) |
6080 | jump = JUMP(SLJIT_C_ZERO); | jump = JUMP(SLJIT_ZERO); |
6081 | ||
6082 | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); | OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
6083 | partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); | partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0); |
6084 | if (common->mode == JIT_COMPILE) | if (common->mode == JIT_COMPILE) |
6085 | add_jump(compiler, backtracks, partial); | add_jump(compiler, backtracks, partial); |
6086 | ||
6087 | 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)); |
6088 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
6089 | ||
6090 | if (common->mode != JIT_COMPILE) | if (common->mode != JIT_COMPILE) |
6091 | { | { |
# | Line 6008 else | Line 6094 else |
6094 | /* TMP2 -= STR_END - STR_PTR */ | /* TMP2 -= STR_END - STR_PTR */ |
6095 | OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); | OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); |
6096 | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); | OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); |
6097 | partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); | partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0); |
6098 | OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); | OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); |
6099 | 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)); |
6100 | add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
6101 | JUMPHERE(partial); | JUMPHERE(partial); |
6102 | check_partial(common, FALSE); | check_partial(common, FALSE); |
6103 | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); | add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); |
# | Line 6097 if (!minimize) | Line 6183 if (!minimize) |
6183 | /* Handles both invalid and empty cases. Since the minimum repeat, | /* Handles both invalid and empty cases. Since the minimum repeat, |
6184 | is zero the invalid case is basically the same as an empty case. */ | is zero the invalid case is basically the same as an empty case. */ |
6185 | if (ref) | if (ref) |
6186 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); |
6187 | else | else |
6188 | { | { |
6189 | compile_dnref_search(common, ccbegin, NULL); | compile_dnref_search(common, ccbegin, NULL); |
6190 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); |
6191 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); |
6192 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); |
6193 | } | } |
6194 | /* Restore if not zero length. */ | /* Restore if not zero length. */ |
6195 | OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); | OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); |
# | Line 6116 if (!minimize) | Line 6202 if (!minimize) |
6202 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
6203 | if (ref) | if (ref) |
6204 | { | { |
6205 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); |
6206 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); |
6207 | } | } |
6208 | else | else |
6209 | { | { |
6210 | compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); | compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); |
6211 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); |
6212 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); |
6213 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); |
6214 | } | } |
6215 | } | } |
6216 | ||
# | Line 6142 if (!minimize) | Line 6228 if (!minimize) |
6228 | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
6229 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); |
6230 | if (min > 1) | if (min > 1) |
6231 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); |
6232 | if (max > 1) | if (max > 1) |
6233 | { | { |
6234 | jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); | jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); |
6235 | allocate_stack(common, 1); | allocate_stack(common, 1); |
6236 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
6237 | JUMPTO(SLJIT_JUMP, label); | JUMPTO(SLJIT_JUMP, label); |
# | Line 6180 if (min == 0) | Line 6266 if (min == 0) |
6266 | /* Handles both invalid and empty cases. Since the minimum repeat, | /* Handles both invalid and empty cases. Since the minimum repeat, |
6267 | is zero the invalid case is basically the same as an empty case. */ | is zero the invalid case is basically the same as an empty case. */ |
6268 | if (ref) | if (ref) |
6269 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); |
6270 | else | else |
6271 | { | { |
6272 | compile_dnref_search(common, ccbegin, NULL); | compile_dnref_search(common, ccbegin, NULL); |
6273 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); |
6274 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); |
6275 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); |
6276 | } | } |
6277 | /* Length is non-zero, we can match real repeats. */ | /* Length is non-zero, we can match real repeats. */ |
6278 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
# | Line 6196 else | Line 6282 else |
6282 | { | { |
6283 | if (ref) | if (ref) |
6284 | { | { |
6285 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); |
6286 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); |
6287 | } | } |
6288 | else | else |
6289 | { | { |
6290 | compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); | compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); |
6291 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); |
6292 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); |
6293 | zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); | zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); |
6294 | } | } |
6295 | } | } |
6296 | ||
6297 | BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); | BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); |
6298 | if (max > 0) | if (max > 0) |
6299 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); |
6300 | ||
6301 | if (!ref) | if (!ref) |
6302 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
# | Line 6222 if (min > 1) | Line 6308 if (min > 1) |
6308 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
6309 | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
6310 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
6311 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath); |
6312 | } | } |
6313 | else if (max > 0) | else if (max > 0) |
6314 | 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); |
# | Line 6300 if (entry->entry == NULL) | Line 6386 if (entry->entry == NULL) |
6386 | else | else |
6387 | JUMPTO(SLJIT_FAST_CALL, entry->entry); | JUMPTO(SLJIT_FAST_CALL, entry->entry); |
6388 | /* Leave if the match is failed. */ | /* Leave if the match is failed. */ |
6389 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); |
6390 | return cc + 1 + LINK_SIZE; | return cc + 1 + LINK_SIZE; |
6391 | } | } |
6392 | ||
6393 | static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector) | static int SLJIT_CALL do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector) |
6394 | { | { |
6395 | const pcre_uchar *begin = arguments->begin; | const pcre_uchar *begin = arguments->begin; |
6396 | int *offset_vector = arguments->offsets; | int *offset_vector = arguments->offsets; |
# | Line 6364 PUSH_BACKTRACK(sizeof(backtrack_common), | Line 6450 PUSH_BACKTRACK(sizeof(backtrack_common), |
6450 | ||
6451 | allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); | allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); |
6452 | ||
6453 | SLJIT_ASSERT(common->capture_last_ptr != 0); | |
6454 | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); | OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); |
6455 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
SLJIT_ASSERT(common->capture_last_ptr != 0); | ||
6456 | OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]); | OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]); |
6457 | OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); | OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); |
6458 | ||
# | Line 6392 free_stack(common, CALLOUT_ARG_SIZE / si | Line 6478 free_stack(common, CALLOUT_ARG_SIZE / si |
6478 | ||
6479 | /* Check return value. */ | /* Check return value. */ |
6480 | OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); | OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); |
6481 | add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER)); | add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER)); |
6482 | if (common->forced_quit_label == NULL) | if (common->forced_quit_label == NULL) |
6483 | add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS)); | add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS)); |
6484 | else | else |
6485 | JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label); | JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label); |
6486 | return cc + 2 + 2 * LINK_SIZE; | return cc + 2 + 2 * LINK_SIZE; |
6487 | } | } |
6488 | ||
6489 | #undef CALLOUT_ARG_SIZE | #undef CALLOUT_ARG_SIZE |
6490 | #undef CALLOUT_ARG_OFFSET | #undef CALLOUT_ARG_OFFSET |
6491 | ||
6492 | static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(pcre_uchar *cc) | |
6493 | { | |
6494 | while (TRUE) | |
6495 | { | |
6496 | switch (*cc) | |
6497 | { | |
6498 | case OP_NOT_WORD_BOUNDARY: | |
6499 | case OP_WORD_BOUNDARY: | |
6500 | case OP_CIRC: | |
6501 | case OP_CIRCM: | |
6502 | case OP_DOLL: | |
6503 | case OP_DOLLM: | |
6504 | case OP_CALLOUT: | |
6505 | case OP_ALT: | |
6506 | cc += PRIV(OP_lengths)[*cc]; | |
6507 | break; | |
6508 | ||
6509 | case OP_KET: | |
6510 | return FALSE; | |
6511 | ||
6512 | default: | |
6513 | return TRUE; | |
6514 | } | |
6515 | } | |
6516 | } | |
6517 | ||
6518 | static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) | static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) |
6519 | { | { |
6520 | DEFINE_COMPILER; | DEFINE_COMPILER; |
# | Line 6454 if (bra == OP_BRAMINZERO) | Line 6566 if (bra == OP_BRAMINZERO) |
6566 | /* This is a braminzero backtrack path. */ | /* This is a braminzero backtrack path. */ |
6567 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6568 | free_stack(common, 1); | free_stack(common, 1); |
6569 | brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); | brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
6570 | } | } |
6571 | ||
6572 | if (framesize < 0) | if (framesize < 0) |
6573 | { | { |
6574 | extrasize = needs_control_head ? 2 : 1; | extrasize = 1; |
6575 | if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE)) | |
6576 | extrasize = 0; | |
6577 | ||
6578 | if (needs_control_head) | |
6579 | extrasize++; | |
6580 | ||
6581 | if (framesize == no_frame) | if (framesize == no_frame) |
6582 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); |
6583 | allocate_stack(common, extrasize); | |
6584 | if (extrasize > 0) | |
6585 | allocate_stack(common, extrasize); | |
6586 | ||
6587 | if (needs_control_head) | if (needs_control_head) |
6588 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); |
6589 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); | |
6590 | if (extrasize > 0) | |
6591 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); | |
6592 | ||
6593 | if (needs_control_head) | if (needs_control_head) |
6594 | { | { |
6595 | SLJIT_ASSERT(extrasize == 2); | |
6596 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); |
6597 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
6598 | } | } |
# | Line 6476 else | Line 6601 else |
6601 | { | { |
6602 | extrasize = needs_control_head ? 3 : 2; | extrasize = needs_control_head ? 3 : 2; |
6603 | allocate_stack(common, framesize + extrasize); | allocate_stack(common, framesize + extrasize); |
6604 | ||
6605 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); |
6606 | OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); | OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); |
6607 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); |
# | Line 6490 else | Line 6616 else |
6616 | } | } |
6617 | else | else |
6618 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
6619 | ||
6620 | init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); | init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); |
6621 | } | } |
6622 | ||
# | Line 6513 while (1) | Line 6640 while (1) |
6640 | altbacktrack.top = NULL; | altbacktrack.top = NULL; |
6641 | altbacktrack.topbacktracks = NULL; | altbacktrack.topbacktracks = NULL; |
6642 | ||
6643 | if (*ccbegin == OP_ALT) | if (*ccbegin == OP_ALT && extrasize > 0) |
6644 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6645 | ||
6646 | altbacktrack.cc = ccbegin; | altbacktrack.cc = ccbegin; |
# | Line 6542 while (1) | Line 6669 while (1) |
6669 | { | { |
6670 | if (framesize == no_frame) | if (framesize == no_frame) |
6671 | OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); | OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); |
6672 | else | else if (extrasize > 0) |
6673 | free_stack(common, extrasize); | free_stack(common, extrasize); |
6674 | ||
6675 | if (needs_control_head) | if (needs_control_head) |
6676 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); |
6677 | } | } |
# | Line 6569 while (1) | Line 6697 while (1) |
6697 | { | { |
6698 | /* We know that STR_PTR was stored on the top of the stack. */ | /* We know that STR_PTR was stored on the top of the stack. */ |
6699 | if (conditional) | if (conditional) |
6700 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); | { |
6701 | if (extrasize > 0) | |
6702 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); | |
6703 | } | |
6704 | else if (bra == OP_BRAZERO) | else if (bra == OP_BRAZERO) |
6705 | { | { |
6706 | if (framesize < 0) | if (framesize < 0) |
# | Line 6646 if (needs_control_head) | Line 6777 if (needs_control_head) |
6777 | if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) | if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
6778 | { | { |
6779 | /* Assert is failed. */ | /* Assert is failed. */ |
6780 | if (conditional || bra == OP_BRAZERO) | if ((conditional && extrasize > 0) || bra == OP_BRAZERO) |
6781 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6782 | ||
6783 | if (framesize < 0) | if (framesize < 0) |
# | Line 6658 if (opcode == OP_ASSERT || opcode == OP_ | Line 6789 if (opcode == OP_ASSERT || opcode == OP_ |
6789 | free_stack(common, 1); | free_stack(common, 1); |
6790 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
6791 | } | } |
6792 | else | else if (extrasize > 0) |
6793 | free_stack(common, extrasize); | free_stack(common, extrasize); |
6794 | } | } |
6795 | else | else |
# | Line 6683 if (opcode == OP_ASSERT || opcode == OP_ | Line 6814 if (opcode == OP_ASSERT || opcode == OP_ |
6814 | if (framesize < 0) | if (framesize < 0) |
6815 | { | { |
6816 | /* We know that STR_PTR was stored on the top of the stack. */ | /* We know that STR_PTR was stored on the top of the stack. */ |
6817 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); | if (extrasize > 0) |
6818 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); | |
6819 | ||
6820 | /* Keep the STR_PTR on the top of the stack. */ | /* Keep the STR_PTR on the top of the stack. */ |
6821 | if (bra == OP_BRAZERO) | if (bra == OP_BRAZERO) |
6822 | { | { |
# | Line 6746 else | Line 6879 else |
6879 | /* AssertNot is successful. */ | /* AssertNot is successful. */ |
6880 | if (framesize < 0) | if (framesize < 0) |
6881 | { | { |
6882 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | if (extrasize > 0) |
6883 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | |
6884 | ||
6885 | if (bra != OP_BRA) | if (bra != OP_BRA) |
6886 | { | { |
6887 | if (extrasize == 2) | if (extrasize == 2) |
6888 | free_stack(common, 1); | free_stack(common, 1); |
6889 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
6890 | } | } |
6891 | else | else if (extrasize > 0) |
6892 | free_stack(common, extrasize); | free_stack(common, extrasize); |
6893 | } | } |
6894 | else | else |
# | Line 6815 if (framesize < 0) | Line 6950 if (framesize < 0) |
6950 | stacksize = needs_control_head ? 1 : 0; | stacksize = needs_control_head ? 1 : 0; |
6951 | if (ket != OP_KET || has_alternatives) | if (ket != OP_KET || has_alternatives) |
6952 | stacksize++; | stacksize++; |
6953 | free_stack(common, stacksize); | |
6954 | if (stacksize > 0) | |
6955 | free_stack(common, stacksize); | |
6956 | } | } |
6957 | ||
6958 | if (needs_control_head) | if (needs_control_head) |
# | Line 6989 cc += GET(cc, 1); | Line 7126 cc += GET(cc, 1); |
7126 | ||
7127 | has_alternatives = *cc == OP_ALT; | has_alternatives = *cc == OP_ALT; |
7128 | if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) | if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) |
7129 | has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE; | has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL) ? FALSE : TRUE; |
7130 | ||
7131 | if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) | if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) |
7132 | opcode = OP_SCOND; | opcode = OP_SCOND; |
# | Line 7050 if (bra == OP_BRAMINZERO) | Line 7187 if (bra == OP_BRAMINZERO) |
7187 | if (ket != OP_KETRMIN) | if (ket != OP_KETRMIN) |
7188 | { | { |
7189 | free_stack(common, 1); | free_stack(common, 1); |
7190 | braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); | braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
7191 | } | } |
7192 | else | else |
7193 | { | { |
7194 | if (opcode == OP_ONCE || opcode >= OP_SBRA) | if (opcode == OP_ONCE || opcode >= OP_SBRA) |
7195 | { | { |
7196 | jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); | jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
7197 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
7198 | /* Nothing stored during the first run. */ | /* Nothing stored during the first run. */ |
7199 | skip = JUMP(SLJIT_JUMP); | skip = JUMP(SLJIT_JUMP); |
# | Line 7065 if (bra == OP_BRAMINZERO) | Line 7202 if (bra == OP_BRAMINZERO) |
7202 | if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) | if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
7203 | { | { |
7204 | /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ | /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ |
7205 | braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); | braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); |
7206 | } | } |
7207 | else | else |
7208 | { | { |
7209 | /* Except when the whole stack frame must be saved. */ | /* Except when the whole stack frame must be saved. */ |
7210 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); |
7211 | braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); | braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); |
7212 | } | } |
7213 | JUMPHERE(skip); | JUMPHERE(skip); |
7214 | } | } |
7215 | else | else |
7216 | { | { |
7217 | jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); | jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
7218 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
7219 | JUMPHERE(jump); | JUMPHERE(jump); |
7220 | } | } |
# | Line 7223 if (opcode == OP_COND || opcode == OP_SC | Line 7360 if (opcode == OP_COND || opcode == OP_SC |
7360 | { | { |
7361 | SLJIT_ASSERT(has_alternatives); | SLJIT_ASSERT(has_alternatives); |
7362 | add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), | add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), |
7363 | CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); | CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); |
7364 | matchingpath += 1 + IMM2_SIZE; | matchingpath += 1 + IMM2_SIZE; |
7365 | } | } |
7366 | else if (*matchingpath == OP_DNCREF) | else if (*matchingpath == OP_DNCREF) |
# | Line 7244 if (opcode == OP_COND || opcode == OP_SC | Line 7381 if (opcode == OP_COND || opcode == OP_SC |
7381 | slot += common->name_entry_size; | slot += common->name_entry_size; |
7382 | } | } |
7383 | OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); | OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
7384 | add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO)); | add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO)); |
7385 | matchingpath += 1 + 2 * IMM2_SIZE; | matchingpath += 1 + 2 * IMM2_SIZE; |
7386 | } | } |
7387 | else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) | else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL) |
7388 | { | { |
7389 | /* Never has other case. */ | /* Never has other case. */ |
7390 | BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; | BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; |
7391 | SLJIT_ASSERT(!has_alternatives); | SLJIT_ASSERT(!has_alternatives); |
7392 | ||
7393 | if (*matchingpath == OP_FAIL) | |
7394 | stacksize = 0; | |
7395 | if (*matchingpath == OP_RREF) | if (*matchingpath == OP_RREF) |
7396 | { | { |
7397 | stacksize = GET2(matchingpath, 1); | stacksize = GET2(matchingpath, 1); |
# | Line 7387 if (ket == OP_KETRMAX) | Line 7526 if (ket == OP_KETRMAX) |
7526 | if (has_alternatives) | if (has_alternatives) |
7527 | BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); | BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); |
7528 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); |
7529 | JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); | JUMPTO(SLJIT_NOT_ZERO, rmax_label); |
7530 | /* Drop STR_PTR for greedy plus quantifier. */ | /* Drop STR_PTR for greedy plus quantifier. */ |
7531 | if (opcode != OP_ONCE) | if (opcode != OP_ONCE) |
7532 | free_stack(common, 1); | free_stack(common, 1); |
# | Line 7399 if (ket == OP_KETRMAX) | Line 7538 if (ket == OP_KETRMAX) |
7538 | /* Checking zero-length iteration. */ | /* Checking zero-length iteration. */ |
7539 | if (opcode != OP_ONCE) | if (opcode != OP_ONCE) |
7540 | { | { |
7541 | CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label); | CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label); |
7542 | /* Drop STR_PTR for greedy plus quantifier. */ | /* Drop STR_PTR for greedy plus quantifier. */ |
7543 | if (bra != OP_BRAZERO) | if (bra != OP_BRAZERO) |
7544 | free_stack(common, 1); | free_stack(common, 1); |
7545 | } | } |
7546 | else | else |
7547 | /* TMP2 must contain the starting STR_PTR. */ | /* TMP2 must contain the starting STR_PTR. */ |
7548 | CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); | CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); |
7549 | } | } |
7550 | else | else |
7551 | JUMPTO(SLJIT_JUMP, rmax_label); | JUMPTO(SLJIT_JUMP, rmax_label); |
# | Line 7417 if (repeat_type == OP_EXACT) | Line 7556 if (repeat_type == OP_EXACT) |
7556 | { | { |
7557 | count_match(common); | count_match(common); |
7558 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1); |
7559 | JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); | JUMPTO(SLJIT_NOT_ZERO, rmax_label); |
7560 | } | } |
7561 | else if (repeat_type == OP_UPTO) | else if (repeat_type == OP_UPTO) |
7562 | { | { |
# | Line 7648 while (*cc != OP_KETRPOS) | Line 7787 while (*cc != OP_KETRPOS) |
7787 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
7788 | } | } |
7789 | ||
7790 | /* Even if the match is empty, we need to reset the control head. */ | |
7791 | if (needs_control_head) | |
7792 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); | |
7793 | ||
7794 | if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) | if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) |
7795 | add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); | add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); |
7796 | ||
7797 | if (!zero) | if (!zero) |
7798 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0); |
# | Line 7675 while (*cc != OP_KETRPOS) | Line 7818 while (*cc != OP_KETRPOS) |
7818 | OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); |
7819 | } | } |
7820 | ||
7821 | /* Even if the match is empty, we need to reset the control head. */ | |
7822 | if (needs_control_head) | |
7823 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); | |
7824 | ||
7825 | if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) | if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) |
7826 | add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0)); | add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0)); |
7827 | ||
7828 | if (!zero) | if (!zero) |
7829 | { | { |
# | Line 7687 while (*cc != OP_KETRPOS) | Line 7834 while (*cc != OP_KETRPOS) |
7834 | } | } |
7835 | } | } |
7836 | ||
if (needs_control_head) | ||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); | ||
7837 | JUMPTO(SLJIT_JUMP, loop); | JUMPTO(SLJIT_JUMP, loop); |
7838 | flush_stubs(common); | flush_stubs(common); |
7839 | ||
# | Line 7732 backtrack->topbacktracks = NULL; | Line 7876 backtrack->topbacktracks = NULL; |
7876 | if (!zero) | if (!zero) |
7877 | { | { |
7878 | if (framesize < 0) | if (framesize < 0) |
7879 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); |
7880 | else /* TMP2 is set to [private_data_ptr] above. */ | else /* TMP2 is set to [private_data_ptr] above. */ |
7881 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0)); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0)); |
7882 | } | } |
7883 | ||
7884 | /* None of them matched. */ | /* None of them matched. */ |
# | Line 7848 backtrack_common *backtrack; | Line 7992 backtrack_common *backtrack; |
7992 | pcre_uchar opcode; | pcre_uchar opcode; |
7993 | pcre_uchar type; | pcre_uchar type; |
7994 | int max = -1, min = -1; | int max = -1, min = -1; |
7995 | pcre_uchar* end; | pcre_uchar *end; |
7996 | jump_list *nomatch = NULL; | jump_list *nomatch = NULL; |
7997 | struct sljit_jump *jump = NULL; | struct sljit_jump *jump = NULL; |
7998 | struct sljit_label *label; | struct sljit_label *label; |
# | Line 7926 switch(opcode) | Line 8070 switch(opcode) |
8070 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); |
8071 | ||
8072 | label = LABEL(); | label = LABEL(); |
8073 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8074 | if (opcode == OP_UPTO || opcode == OP_CRRANGE) | if (opcode == OP_UPTO || opcode == OP_CRRANGE) |
8075 | { | { |
8076 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); |
8077 | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
8078 | if (opcode == OP_CRRANGE && min > 0) | if (opcode == OP_CRRANGE && min > 0) |
8079 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); |
8080 | if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0)) | if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0)) |
8081 | jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); | jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); |
8082 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); |
8083 | } | } |
8084 | ||
# | Line 7948 switch(opcode) | Line 8092 switch(opcode) |
8092 | else | else |
8093 | { | { |
8094 | if (opcode == OP_PLUS) | if (opcode == OP_PLUS) |
8095 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8096 | if (private_data_ptr == 0) | if (private_data_ptr == 0) |
8097 | allocate_stack(common, 2); | allocate_stack(common, 2); |
8098 | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); |
# | Line 7957 switch(opcode) | Line 8101 switch(opcode) |
8101 | else | else |
8102 | OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); | OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); |
8103 | label = LABEL(); | label = LABEL(); |
8104 | compile_char1_matchingpath(common, type, cc, &nomatch); | compile_char1_matchingpath(common, type, cc, &nomatch, TRUE); |
8105 | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); |
8106 | if (opcode <= OP_PLUS) | if (opcode <= OP_PLUS) |
8107 | JUMPTO(SLJIT_JUMP, label); | JUMPTO(SLJIT_JUMP, label); |
# | Line 7971 switch(opcode) | Line 8115 switch(opcode) |
8115 | OP1(SLJIT_MOV, TMP1, 0, base, offset1); | OP1(SLJIT_MOV, TMP1, 0, base, offset1); |
8116 | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); |
8117 | OP1(SLJIT_MOV, base, offset1, TMP1, 0); | OP1(SLJIT_MOV, base, offset1, TMP1, 0); |
8118 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, max + 1, label); |
8119 | } | } |
8120 | set_jumps(nomatch, LABEL()); | set_jumps(nomatch, LABEL()); |
8121 | if (opcode == OP_CRRANGE) | if (opcode == OP_CRRANGE) |
8122 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, min + 1)); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS, base, offset1, SLJIT_IMM, min + 1)); |
8123 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8124 | } | } |
8125 | BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); | BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); |
# | Line 7984 switch(opcode) | Line 8128 switch(opcode) |
8128 | case OP_MINSTAR: | case OP_MINSTAR: |
8129 | case OP_MINPLUS: | case OP_MINPLUS: |
8130 | if (opcode == OP_MINPLUS) | if (opcode == OP_MINPLUS) |
8131 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8132 | if (private_data_ptr == 0) | if (private_data_ptr == 0) |
8133 | allocate_stack(common, 1); | allocate_stack(common, 1); |
8134 | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); |
# | Line 8008 switch(opcode) | Line 8152 switch(opcode) |
8152 | allocate_stack(common, 1); | allocate_stack(common, 1); |
8153 | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); |
8154 | if (opcode == OP_QUERY) | if (opcode == OP_QUERY) |
8155 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8156 | BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); | BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); |
8157 | break; | break; |
8158 | ||
8159 | case OP_EXACT: | case OP_EXACT: |
8160 | OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); | OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); |
8161 | label = LABEL(); | label = LABEL(); |
8162 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8163 | OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); |
8164 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
8165 | break; | break; |
8166 | ||
8167 | case OP_POSSTAR: | case OP_POSSTAR: |
8168 | case OP_POSPLUS: | case OP_POSPLUS: |
8169 | case OP_POSUPTO: | case OP_POSUPTO: |
8170 | if (opcode == OP_POSPLUS) | if (opcode == OP_POSPLUS) |
8171 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8172 | if (opcode == OP_POSUPTO) | if (opcode == OP_POSUPTO) |
8173 | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max); | OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max); |
8174 | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); |
8175 | label = LABEL(); | label = LABEL(); |
8176 | compile_char1_matchingpath(common, type, cc, &nomatch); | compile_char1_matchingpath(common, type, cc, &nomatch, TRUE); |
8177 | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); |
8178 | if (opcode != OP_POSUPTO) | if (opcode != OP_POSUPTO) |
8179 | JUMPTO(SLJIT_JUMP, label); | JUMPTO(SLJIT_JUMP, label); |
8180 | else | else |
8181 | { | { |
8182 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); |
8183 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
8184 | } | } |
8185 | set_jumps(nomatch, LABEL()); | set_jumps(nomatch, LABEL()); |
8186 | OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); | OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); |
# | Line 8044 switch(opcode) | Line 8188 switch(opcode) |
8188 | ||
8189 | case OP_POSQUERY: | case OP_POSQUERY: |
8190 | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); |
8191 | compile_char1_matchingpath(common, type, cc, &nomatch); | compile_char1_matchingpath(common, type, cc, &nomatch, TRUE); |
8192 | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); |
8193 | set_jumps(nomatch, LABEL()); | set_jumps(nomatch, LABEL()); |
8194 | OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); | OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); |
# | Line 8054 switch(opcode) | Line 8198 switch(opcode) |
8198 | /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */ | /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */ |
8199 | OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min); | OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min); |
8200 | label = LABEL(); | label = LABEL(); |
8201 | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); | compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); |
8202 | OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); |
8203 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
8204 | ||
8205 | if (max != 0) | if (max != 0) |
8206 | { | { |
# | Line 8065 switch(opcode) | Line 8209 switch(opcode) |
8209 | } | } |
8210 | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); |
8211 | label = LABEL(); | label = LABEL(); |
8212 | compile_char1_matchingpath(common, type, cc, &nomatch); | compile_char1_matchingpath(common, type, cc, &nomatch, TRUE); |
8213 | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); | OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); |
8214 | if (max == 0) | if (max == 0) |
8215 | JUMPTO(SLJIT_JUMP, label); | JUMPTO(SLJIT_JUMP, label); |
8216 | else | else |
8217 | { | { |
8218 | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); | OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); |
8219 | JUMPTO(SLJIT_C_NOT_ZERO, label); | JUMPTO(SLJIT_NOT_ZERO, label); |
8220 | } | } |
8221 | set_jumps(nomatch, LABEL()); | set_jumps(nomatch, LABEL()); |
8222 | OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); | OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); |
# | Line 8111 if (*cc == OP_ASSERT_ACCEPT || common->c | Line 8255 if (*cc == OP_ASSERT_ACCEPT || common->c |
8255 | } | } |
8256 | ||
8257 | if (common->accept_label == NULL) | if (common->accept_label == NULL) |
8258 | add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0))); | add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0))); |
8259 | else | else |
8260 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); |
8261 | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); | OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
8262 | 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)); |
8263 | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
8264 | 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)); |
8265 | if (common->accept_label == NULL) | if (common->accept_label == NULL) |
8266 | add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0)); | add_jump(compiler, &common->accept, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
8267 | else | else |
8268 | CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label); | CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label); |
8269 | 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)); |
8270 | if (common->accept_label == NULL) | if (common->accept_label == NULL) |
8271 | add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); | add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); |
8272 | else | else |
8273 | CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); | CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); |
8274 | add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); | add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); |
8275 | return cc + 1; | return cc + 1; |
8276 | } | } |
# | Line 8239 while (cc < ccend) | Line 8383 while (cc < ccend) |
8383 | case OP_SOM: | case OP_SOM: |
8384 | case OP_NOT_WORD_BOUNDARY: | case OP_NOT_WORD_BOUNDARY: |
8385 | case OP_WORD_BOUNDARY: | case OP_WORD_BOUNDARY: |
8386 | case OP_EODN: | |
8387 | case OP_EOD: | |
8388 | case OP_DOLL: | |
8389 | case OP_DOLLM: | |
8390 | case OP_CIRC: | |
8391 | case OP_CIRCM: | |
8392 | case OP_REVERSE: | |
8393 | cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); | |
8394 | break; | |
8395 | ||
8396 | case OP_NOT_DIGIT: | case OP_NOT_DIGIT: |
8397 | case OP_DIGIT: | case OP_DIGIT: |
8398 | case OP_NOT_WHITESPACE: | case OP_NOT_WHITESPACE: |
# | Line 8256 while (cc < ccend) | Line 8410 while (cc < ccend) |
8410 | case OP_NOT_VSPACE: | case OP_NOT_VSPACE: |
8411 | case OP_VSPACE: | case OP_VSPACE: |
8412 | case OP_EXTUNI: | case OP_EXTUNI: |
case OP_EODN: | ||
case OP_EOD: | ||
case OP_CIRC: | ||
case OP_CIRCM: | ||
case OP_DOLL: | ||
case OP_DOLLM: | ||
8413 | case OP_NOT: | case OP_NOT: |
8414 | case OP_NOTI: | case OP_NOTI: |
8415 | case OP_REVERSE: | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); |
cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); | ||
8416 | break; | break; |
8417 | ||
8418 | case OP_SET_SOM: | case OP_SET_SOM: |
# | Line 8282 while (cc < ccend) | Line 8429 while (cc < ccend) |
8429 | if (common->mode == JIT_COMPILE) | if (common->mode == JIT_COMPILE) |
8430 | cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); | cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); |
8431 | else | else |
8432 | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); |
8433 | break; | break; |
8434 | ||
8435 | case OP_STAR: | case OP_STAR: |
# | Line 8358 while (cc < ccend) | Line 8505 while (cc < ccend) |
8505 | if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE) | if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE) |
8506 | cc = compile_iterator_matchingpath(common, cc, parent); | cc = compile_iterator_matchingpath(common, cc, parent); |
8507 | else | else |
8508 | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); |
8509 | break; | break; |
8510 | ||
8511 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 | #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
# | Line 8366 while (cc < ccend) | Line 8513 while (cc < ccend) |
8513 | if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) | if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) |
8514 | cc = compile_iterator_matchingpath(common, cc, parent); | cc = compile_iterator_matchingpath(common, cc, parent); |
8515 | else | else |
8516 | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); | cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); |
8517 | break; | break; |
8518 | #endif | #endif |
8519 | ||
# | Line 8424 while (cc < ccend) | Line 8571 while (cc < ccend) |
8571 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); |
8572 | } | } |
8573 | BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); | BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); |
8574 | if (cc[1] > OP_ASSERTBACK_NOT) | count_match(common); |
count_match(common); | ||
8575 | break; | break; |
8576 | ||
8577 | case OP_ONCE: | case OP_ONCE: |
# | Line 8566 switch(opcode) | Line 8712 switch(opcode) |
8712 | set_jumps(current->topbacktracks, LABEL()); | set_jumps(current->topbacktracks, LABEL()); |
8713 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8714 | free_stack(common, 1); | free_stack(common, 1); |
8715 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); |
8716 | } | } |
8717 | else | else |
8718 | { | { |
# | Line 8575 switch(opcode) | Line 8721 switch(opcode) |
8721 | if (opcode <= OP_PLUS) | if (opcode <= OP_PLUS) |
8722 | { | { |
8723 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8724 | jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1); | jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); |
8725 | } | } |
8726 | else | else |
8727 | { | { |
8728 | OP1(SLJIT_MOV, TMP1, 0, base, offset1); | OP1(SLJIT_MOV, TMP1, 0, base, offset1); |
8729 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8730 | jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1); | jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1); |
8731 | OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); | OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); |
8732 | } | } |
8733 | skip_char_back(common); | skip_char_back(common); |
# | Line 8600 switch(opcode) | Line 8746 switch(opcode) |
8746 | case OP_MINSTAR: | case OP_MINSTAR: |
8747 | case OP_MINPLUS: | case OP_MINPLUS: |
8748 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8749 | compile_char1_matchingpath(common, type, cc, &jumplist); | compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); |
8750 | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); |
8751 | JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); | JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); |
8752 | set_jumps(jumplist, LABEL()); | set_jumps(jumplist, LABEL()); |
# | Line 8618 switch(opcode) | Line 8764 switch(opcode) |
8764 | set_jumps(current->topbacktracks, label); | set_jumps(current->topbacktracks, label); |
8765 | } | } |
8766 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8767 | compile_char1_matchingpath(common, type, cc, &jumplist); | compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); |
8768 | ||
8769 | OP1(SLJIT_MOV, TMP1, 0, base, offset1); | OP1(SLJIT_MOV, TMP1, 0, base, offset1); |
8770 | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); | OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); |
# | Line 8626 switch(opcode) | Line 8772 switch(opcode) |
8772 | OP1(SLJIT_MOV, base, offset1, TMP1, 0); | OP1(SLJIT_MOV, base, offset1, TMP1, 0); |
8773 | ||
8774 | if (opcode == OP_CRMINRANGE) | if (opcode == OP_CRMINRANGE) |
8775 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min + 1, label); |
8776 | ||
8777 | if (opcode == OP_CRMINRANGE && max == 0) | if (opcode == OP_CRMINRANGE && max == 0) |
8778 | JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); | JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); |
8779 | else | else |
8780 | CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath); | CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath); |
8781 | ||
8782 | set_jumps(jumplist, LABEL()); | set_jumps(jumplist, LABEL()); |
8783 | if (private_data_ptr == 0) | if (private_data_ptr == 0) |
# | Line 8641 switch(opcode) | Line 8787 switch(opcode) |
8787 | case OP_QUERY: | case OP_QUERY: |
8788 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8789 | OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); |
8790 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); |
8791 | jump = JUMP(SLJIT_JUMP); | jump = JUMP(SLJIT_JUMP); |
8792 | set_jumps(current->topbacktracks, LABEL()); | set_jumps(current->topbacktracks, LABEL()); |
8793 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
# | Line 8655 switch(opcode) | Line 8801 switch(opcode) |
8801 | case OP_MINQUERY: | case OP_MINQUERY: |
8802 | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); | OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); |
8803 | OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); | OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); |
8804 | jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); | jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
8805 | compile_char1_matchingpath(common, type, cc, &jumplist); | compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); |
8806 | JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); | JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); |
8807 | set_jumps(jumplist, LABEL()); | set_jumps(jumplist, LABEL()); |
8808 | JUMPHERE(jump); | JUMPHERE(jump); |
# | Line 8696 if ((type & 0x1) == 0) | Line 8842 if ((type & 0x1) == 0) |
8842 | set_jumps(current->topbacktracks, LABEL()); | set_jumps(current->topbacktracks, LABEL()); |
8843 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8844 | free_stack(common, 1); | free_stack(common, 1); |
8845 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); |
8846 | return; | return; |
8847 | } | } |
8848 | ||
8849 | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8850 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); |
8851 | set_jumps(current->topbacktracks, LABEL()); | set_jumps(current->topbacktracks, LABEL()); |
8852 | free_stack(common, ref ? 2 : 3); | free_stack(common, ref ? 2 : 3); |
8853 | } | } |
# | Line 8759 if (CURRENT_AS(assert_backtrack)->frames | Line 8905 if (CURRENT_AS(assert_backtrack)->frames |
8905 | if (bra == OP_BRAZERO) | if (bra == OP_BRAZERO) |
8906 | { | { |
8907 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
8908 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); |
8909 | free_stack(common, 1); | free_stack(common, 1); |
8910 | } | } |
8911 | return; | return; |
# | Line 8770 if (bra == OP_BRAZERO) | Line 8916 if (bra == OP_BRAZERO) |
8916 | if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) | if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) |
8917 | { | { |
8918 | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); | OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
8919 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); |
8920 | free_stack(common, 1); | free_stack(common, 1); |
8921 | return; | return; |
8922 | } | } |
8923 | free_stack(common, 1); | free_stack(common, 1); |
8924 | brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); | brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
8925 | } | } |
8926 | ||
8927 | if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) | if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) |
# | Line 8881 if (ket == OP_KETRMAX) | Line 9027 if (ket == OP_KETRMAX) |
9027 | { | { |
9028 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
9029 | free_stack(common, 1); | free_stack(common, 1); |
9030 | brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0); | brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0); |
9031 | } | } |
9032 | } | } |
9033 | else if (ket == OP_KETRMIN) | else if (ket == OP_KETRMIN) |
# | Line 8892 else if (ket == OP_KETRMIN) | Line 9038 else if (ket == OP_KETRMIN) |
9038 | if (repeat_type != 0) | if (repeat_type != 0) |
9039 | { | { |
9040 | /* TMP1 was set a few lines above. */ | /* TMP1 was set a few lines above. */ |
9041 | CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); | CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
9042 | /* Drop STR_PTR for non-greedy plus quantifier. */ | /* Drop STR_PTR for non-greedy plus quantifier. */ |
9043 | if (opcode != OP_ONCE) | if (opcode != OP_ONCE) |
9044 | free_stack(common, 1); | free_stack(common, 1); |
# | Line 8901 else if (ket == OP_KETRMIN) | Line 9047 else if (ket == OP_KETRMIN) |
9047 | { | { |
9048 | /* Checking zero-length iteration. */ | /* Checking zero-length iteration. */ |
9049 | if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) | if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) |
9050 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
9051 | else | else |
9052 | { | { |
9053 | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); | OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); |
9054 | CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); | CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
9055 | } | } |