152 |
const pcre_uchar *begin; |
const pcre_uchar *begin; |
153 |
const pcre_uchar *end; |
const pcre_uchar *end; |
154 |
int *offsets; |
int *offsets; |
155 |
pcre_uchar *ptr; |
pcre_uchar *uchar_ptr; |
156 |
|
pcre_uchar *mark_ptr; |
157 |
/* Everything else after. */ |
/* Everything else after. */ |
158 |
int offsetcount; |
int offsetcount; |
159 |
int calllimit; |
int calllimit; |
163 |
pcre_uint8 notempty_atstart; |
pcre_uint8 notempty_atstart; |
164 |
} jit_arguments; |
} jit_arguments; |
165 |
|
|
166 |
typedef struct executable_function { |
typedef struct executable_functions { |
167 |
void *executable_func; |
void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; |
168 |
PUBL(jit_callback) callback; |
PUBL(jit_callback) callback; |
169 |
void *userdata; |
void *userdata; |
170 |
sljit_uw executable_size; |
sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; |
171 |
} executable_function; |
} executable_functions; |
172 |
|
|
173 |
typedef struct jump_list { |
typedef struct jump_list { |
174 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
271 |
typedef struct compiler_common { |
typedef struct compiler_common { |
272 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
273 |
pcre_uchar *start; |
pcre_uchar *start; |
274 |
int localsize; |
|
275 |
|
/* Opcode local area direct map. */ |
276 |
int *localptrs; |
int *localptrs; |
277 |
|
int cbraptr; |
278 |
|
/* OVector starting point. Must be divisible by 2. */ |
279 |
|
int ovector_start; |
280 |
|
/* Last known position of the requested byte. */ |
281 |
|
int req_char_ptr; |
282 |
|
/* Head of the last recursion. */ |
283 |
|
int recursive_head; |
284 |
|
/* First inspected character for partial matching. */ |
285 |
|
int start_used_ptr; |
286 |
|
/* Starting pointer for partial soft matches. */ |
287 |
|
int hit_start; |
288 |
|
/* End pointer of the first line. */ |
289 |
|
int first_line_end; |
290 |
|
/* Points to the marked string. */ |
291 |
|
int mark_ptr; |
292 |
|
|
293 |
|
/* Other */ |
294 |
const pcre_uint8 *fcc; |
const pcre_uint8 *fcc; |
295 |
sljit_w lcc; |
sljit_w lcc; |
296 |
int cbraptr; |
int mode; |
297 |
int nltype; |
int nltype; |
298 |
int newline; |
int newline; |
299 |
int bsr_nltype; |
int bsr_nltype; |
300 |
int endonly; |
int endonly; |
301 |
|
BOOL has_set_som; |
302 |
sljit_w ctypes; |
sljit_w ctypes; |
303 |
sljit_uw name_table; |
sljit_uw name_table; |
304 |
sljit_w name_count; |
sljit_w name_count; |
305 |
sljit_w name_entry_size; |
sljit_w name_entry_size; |
306 |
|
|
307 |
|
/* Labels and jump lists. */ |
308 |
|
struct sljit_label *partialmatchlabel; |
309 |
|
struct sljit_label *leavelabel; |
310 |
struct sljit_label *acceptlabel; |
struct sljit_label *acceptlabel; |
311 |
stub_list *stubs; |
stub_list *stubs; |
312 |
recurse_entry *entries; |
recurse_entry *entries; |
313 |
recurse_entry *currententry; |
recurse_entry *currententry; |
314 |
|
jump_list *partialmatch; |
315 |
|
jump_list *leave; |
316 |
jump_list *accept; |
jump_list *accept; |
317 |
jump_list *calllimit; |
jump_list *calllimit; |
318 |
jump_list *stackalloc; |
jump_list *stackalloc; |
375 |
|
|
376 |
enum { |
enum { |
377 |
frame_end = 0, |
frame_end = 0, |
378 |
frame_setstrbegin = -1 |
frame_setstrbegin = -1, |
379 |
|
frame_setmark = -2 |
380 |
}; |
}; |
381 |
|
|
382 |
|
/* Undefine sljit macros. */ |
383 |
|
#undef CMP |
384 |
|
|
385 |
/* Used for accessing the elements of the stack. */ |
/* Used for accessing the elements of the stack. */ |
386 |
#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) |
#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) |
387 |
|
|
388 |
#define TMP1 SLJIT_TEMPORARY_REG1 |
#define TMP1 SLJIT_TEMPORARY_REG1 |
389 |
#define TMP2 SLJIT_TEMPORARY_REG3 |
#define TMP2 SLJIT_TEMPORARY_REG3 |
390 |
#define TMP3 SLJIT_TEMPORARY_EREG2 |
#define TMP3 SLJIT_TEMPORARY_EREG2 |
391 |
#define STR_PTR SLJIT_GENERAL_REG1 |
#define STR_PTR SLJIT_SAVED_REG1 |
392 |
#define STR_END SLJIT_GENERAL_REG2 |
#define STR_END SLJIT_SAVED_REG2 |
393 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
394 |
#define STACK_LIMIT SLJIT_GENERAL_REG3 |
#define STACK_LIMIT SLJIT_SAVED_REG3 |
395 |
#define ARGUMENTS SLJIT_GENERAL_EREG1 |
#define ARGUMENTS SLJIT_SAVED_EREG1 |
396 |
#define CALL_COUNT SLJIT_GENERAL_EREG2 |
#define CALL_COUNT SLJIT_SAVED_EREG2 |
397 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
398 |
|
|
399 |
/* Locals layout. */ |
/* Locals layout. */ |
403 |
/* Two local variables for possessive quantifiers (char1 cannot use them). */ |
/* Two local variables for possessive quantifiers (char1 cannot use them). */ |
404 |
#define POSSESSIVE0 (2 * sizeof(sljit_w)) |
#define POSSESSIVE0 (2 * sizeof(sljit_w)) |
405 |
#define POSSESSIVE1 (3 * sizeof(sljit_w)) |
#define POSSESSIVE1 (3 * sizeof(sljit_w)) |
|
/* Head of the last recursion. */ |
|
|
#define RECURSIVE_HEAD (4 * sizeof(sljit_w)) |
|
406 |
/* Max limit of recursions. */ |
/* Max limit of recursions. */ |
407 |
#define CALL_LIMIT (5 * sizeof(sljit_w)) |
#define CALL_LIMIT (4 * sizeof(sljit_w)) |
|
/* Last known position of the requested byte. */ |
|
|
#define REQ_CHAR_PTR (6 * sizeof(sljit_w)) |
|
|
/* End pointer of the first line. */ |
|
|
#define FIRSTLINE_END (7 * sizeof(sljit_w)) |
|
408 |
/* The output vector is stored on the stack, and contains pointers |
/* The output vector is stored on the stack, and contains pointers |
409 |
to characters. The vector data is divided into two groups: the first |
to characters. The vector data is divided into two groups: the first |
410 |
group contains the start / end character pointers, and the second is |
group contains the start / end character pointers, and the second is |
411 |
the start pointers when the end of the capturing group has not yet reached. */ |
the start pointers when the end of the capturing group has not yet reached. */ |
412 |
#define OVECTOR_START (8 * sizeof(sljit_w)) |
#define OVECTOR_START (common->ovector_start) |
413 |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
414 |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
415 |
#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) |
#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) |
447 |
sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) |
sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) |
448 |
#define COND_VALUE(op, dst, dstw, type) \ |
#define COND_VALUE(op, dst, dstw, type) \ |
449 |
sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) |
sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) |
450 |
|
#define GET_LOCAL_BASE(dst, dstw, offset) \ |
451 |
|
sljit_get_local_base(compiler, (dst), (dstw), (offset)) |
452 |
|
|
453 |
static pcre_uchar* bracketend(pcre_uchar* cc) |
static pcre_uchar* bracketend(pcre_uchar* cc) |
454 |
{ |
{ |
520 |
case OP_BRAZERO: |
case OP_BRAZERO: |
521 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
522 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
523 |
|
case OP_COMMIT: |
524 |
case OP_FAIL: |
case OP_FAIL: |
525 |
case OP_ACCEPT: |
case OP_ACCEPT: |
526 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
659 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
660 |
return cc + 1 + LINK_SIZE + IMM2_SIZE; |
return cc + 1 + LINK_SIZE + IMM2_SIZE; |
661 |
|
|
662 |
|
case OP_MARK: |
663 |
|
return cc + 1 + 2 + cc[1]; |
664 |
|
|
665 |
default: |
default: |
666 |
return NULL; |
return NULL; |
667 |
} |
} |
676 |
{ |
{ |
677 |
switch(*cc) |
switch(*cc) |
678 |
{ |
{ |
679 |
|
case OP_SET_SOM: |
680 |
|
common->has_set_som = TRUE; |
681 |
|
cc += 1; |
682 |
|
break; |
683 |
|
|
684 |
case OP_ASSERT: |
case OP_ASSERT: |
685 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
686 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
709 |
cc += 1 + LINK_SIZE; |
cc += 1 + LINK_SIZE; |
710 |
break; |
break; |
711 |
|
|
712 |
|
case OP_RECURSE: |
713 |
|
/* Set its value only once. */ |
714 |
|
if (common->recursive_head == 0) |
715 |
|
{ |
716 |
|
common->recursive_head = common->ovector_start; |
717 |
|
common->ovector_start += sizeof(sljit_w); |
718 |
|
} |
719 |
|
cc += 1 + LINK_SIZE; |
720 |
|
break; |
721 |
|
|
722 |
|
case OP_MARK: |
723 |
|
if (common->mark_ptr == 0) |
724 |
|
{ |
725 |
|
common->mark_ptr = common->ovector_start; |
726 |
|
common->ovector_start += sizeof(sljit_w); |
727 |
|
} |
728 |
|
cc += 1 + 2 + cc[1]; |
729 |
|
break; |
730 |
|
|
731 |
default: |
default: |
732 |
cc = next_opcode(common, cc); |
cc = next_opcode(common, cc); |
733 |
if (cc == NULL) |
if (cc == NULL) |
793 |
pcre_uchar *ccend = bracketend(cc); |
pcre_uchar *ccend = bracketend(cc); |
794 |
int length = 0; |
int length = 0; |
795 |
BOOL possessive = FALSE; |
BOOL possessive = FALSE; |
796 |
BOOL setsom_found = FALSE; |
BOOL setsom_found = recursive; |
797 |
|
BOOL setmark_found = recursive; |
798 |
|
|
799 |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
800 |
{ |
{ |
808 |
switch(*cc) |
switch(*cc) |
809 |
{ |
{ |
810 |
case OP_SET_SOM: |
case OP_SET_SOM: |
811 |
case OP_RECURSE: |
SLJIT_ASSERT(common->has_set_som); |
812 |
if (!setsom_found) |
if (!setsom_found) |
813 |
{ |
{ |
814 |
length += 2; |
length += 2; |
815 |
setsom_found = TRUE; |
setsom_found = TRUE; |
816 |
} |
} |
817 |
cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE; |
cc += 1; |
818 |
|
break; |
819 |
|
|
820 |
|
case OP_MARK: |
821 |
|
SLJIT_ASSERT(common->mark_ptr != 0); |
822 |
|
if (!setmark_found) |
823 |
|
{ |
824 |
|
length += 2; |
825 |
|
setmark_found = TRUE; |
826 |
|
} |
827 |
|
cc += 1 + 2 + cc[1]; |
828 |
|
break; |
829 |
|
|
830 |
|
case OP_RECURSE: |
831 |
|
if (common->has_set_som && !setsom_found) |
832 |
|
{ |
833 |
|
length += 2; |
834 |
|
setsom_found = TRUE; |
835 |
|
} |
836 |
|
if (common->mark_ptr != 0 && !setmark_found) |
837 |
|
{ |
838 |
|
length += 2; |
839 |
|
setmark_found = TRUE; |
840 |
|
} |
841 |
|
cc += 1 + LINK_SIZE; |
842 |
break; |
break; |
843 |
|
|
844 |
case OP_CBRA: |
case OP_CBRA: |
868 |
{ |
{ |
869 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
870 |
pcre_uchar *ccend = bracketend(cc); |
pcre_uchar *ccend = bracketend(cc); |
871 |
BOOL setsom_found = FALSE; |
BOOL setsom_found = recursive; |
872 |
|
BOOL setmark_found = recursive; |
873 |
int offset; |
int offset; |
874 |
|
|
875 |
/* >= 1 + shortest item size (2) */ |
/* >= 1 + shortest item size (2) */ |
876 |
|
SLJIT_UNUSED_ARG(stacktop); |
877 |
SLJIT_ASSERT(stackpos >= stacktop + 2); |
SLJIT_ASSERT(stackpos >= stacktop + 2); |
878 |
|
|
879 |
stackpos = STACK(stackpos); |
stackpos = STACK(stackpos); |
884 |
switch(*cc) |
switch(*cc) |
885 |
{ |
{ |
886 |
case OP_SET_SOM: |
case OP_SET_SOM: |
887 |
case OP_RECURSE: |
SLJIT_ASSERT(common->has_set_som); |
888 |
if (!setsom_found) |
if (!setsom_found) |
889 |
{ |
{ |
890 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
894 |
stackpos += (int)sizeof(sljit_w); |
stackpos += (int)sizeof(sljit_w); |
895 |
setsom_found = TRUE; |
setsom_found = TRUE; |
896 |
} |
} |
897 |
cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE; |
cc += 1; |
898 |
|
break; |
899 |
|
|
900 |
|
case OP_MARK: |
901 |
|
SLJIT_ASSERT(common->mark_ptr != 0); |
902 |
|
if (!setmark_found) |
903 |
|
{ |
904 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
905 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); |
906 |
|
stackpos += (int)sizeof(sljit_w); |
907 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
908 |
|
stackpos += (int)sizeof(sljit_w); |
909 |
|
setmark_found = TRUE; |
910 |
|
} |
911 |
|
cc += 1 + 2 + cc[1]; |
912 |
|
break; |
913 |
|
|
914 |
|
case OP_RECURSE: |
915 |
|
if (common->has_set_som && !setsom_found) |
916 |
|
{ |
917 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
918 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); |
919 |
|
stackpos += (int)sizeof(sljit_w); |
920 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
921 |
|
stackpos += (int)sizeof(sljit_w); |
922 |
|
setsom_found = TRUE; |
923 |
|
} |
924 |
|
if (common->mark_ptr != 0 && !setmark_found) |
925 |
|
{ |
926 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
927 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); |
928 |
|
stackpos += (int)sizeof(sljit_w); |
929 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
930 |
|
stackpos += (int)sizeof(sljit_w); |
931 |
|
setmark_found = TRUE; |
932 |
|
} |
933 |
|
cc += 1 + LINK_SIZE; |
934 |
break; |
break; |
935 |
|
|
936 |
case OP_CBRA: |
case OP_CBRA: |
1057 |
switch(status) |
switch(status) |
1058 |
{ |
{ |
1059 |
case start: |
case start: |
1060 |
SLJIT_ASSERT(save); |
SLJIT_ASSERT(save && common->recursive_head != 0); |
1061 |
count = 1; |
count = 1; |
1062 |
srcw[0] = RECURSIVE_HEAD; |
srcw[0] = common->recursive_head; |
1063 |
status = loop; |
status = loop; |
1064 |
break; |
break; |
1065 |
|
|
1318 |
int i; |
int i; |
1319 |
/* At this point we can freely use all temporary registers. */ |
/* At this point we can freely use all temporary registers. */ |
1320 |
/* TMP1 returns with begin - 1. */ |
/* TMP1 returns with begin - 1. */ |
1321 |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); |
1322 |
if (length < 8) |
if (length < 8) |
1323 |
{ |
{ |
1324 |
for (i = 0; i < length; i++) |
for (i = 0; i < length; i++) |
1326 |
} |
} |
1327 |
else |
else |
1328 |
{ |
{ |
1329 |
OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w)); |
GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w)); |
1330 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); |
1331 |
loop = LABEL(); |
loop = LABEL(); |
1332 |
OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); |
OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); |
1342 |
struct sljit_jump *earlyexit; |
struct sljit_jump *earlyexit; |
1343 |
|
|
1344 |
/* At this point we can freely use all registers. */ |
/* At this point we can freely use all registers. */ |
1345 |
OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
1346 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); |
1347 |
|
|
1348 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
1349 |
|
if (common->mark_ptr != 0) |
1350 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
1351 |
OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); |
OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); |
1352 |
|
if (common->mark_ptr != 0) |
1353 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); |
1354 |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); |
1355 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); |
1356 |
OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START); |
GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); |
1357 |
/* Unlikely, but possible */ |
/* Unlikely, but possible */ |
1358 |
earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); |
earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); |
1359 |
loop = LABEL(); |
loop = LABEL(); |
1360 |
OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0); |
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0); |
1361 |
OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); |
OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); |
1362 |
/* Copy the integer value to the output buffer */ |
/* Copy the integer value to the output buffer */ |
1363 |
#ifdef COMPILE_PCRE16 |
#ifdef COMPILE_PCRE16 |
1364 |
OP2(SLJIT_ASHR, SLJIT_GENERAL_REG2, 0, SLJIT_GENERAL_REG2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); |
1365 |
#endif |
#endif |
1366 |
OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0); |
OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); |
1367 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); |
1368 |
JUMPTO(SLJIT_C_NOT_ZERO, loop); |
JUMPTO(SLJIT_C_NOT_ZERO, loop); |
1369 |
JUMPHERE(earlyexit); |
JUMPHERE(earlyexit); |
1371 |
/* Calculate the return value, which is the maximum ovector value. */ |
/* Calculate the return value, which is the maximum ovector value. */ |
1372 |
if (topbracket > 1) |
if (topbracket > 1) |
1373 |
{ |
{ |
1374 |
OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); |
GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); |
1375 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); |
1376 |
|
|
1377 |
/* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */ |
/* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ |
1378 |
loop = LABEL(); |
loop = LABEL(); |
1379 |
OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); |
OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); |
1380 |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); |
1381 |
CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop); |
CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop); |
1382 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); |
1383 |
} |
} |
1384 |
else |
else |
1385 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
1386 |
} |
} |
1387 |
|
|
1388 |
|
static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave) |
1389 |
|
{ |
1390 |
|
DEFINE_COMPILER; |
1391 |
|
|
1392 |
|
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); |
1393 |
|
SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); |
1394 |
|
|
1395 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
1396 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); |
1397 |
|
OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); |
1398 |
|
CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave); |
1399 |
|
|
1400 |
|
/* Store match begin and end. */ |
1401 |
|
OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); |
1402 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); |
1403 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); |
1404 |
|
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); |
1405 |
|
#ifdef COMPILE_PCRE16 |
1406 |
|
OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); |
1407 |
|
#endif |
1408 |
|
OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); |
1409 |
|
|
1410 |
|
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); |
1411 |
|
#ifdef COMPILE_PCRE16 |
1412 |
|
OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); |
1413 |
|
#endif |
1414 |
|
OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); |
1415 |
|
|
1416 |
|
JUMPTO(SLJIT_JUMP, leave); |
1417 |
|
} |
1418 |
|
|
1419 |
|
static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) |
1420 |
|
{ |
1421 |
|
/* May destroy TMP1. */ |
1422 |
|
DEFINE_COMPILER; |
1423 |
|
struct sljit_jump *jump; |
1424 |
|
|
1425 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1426 |
|
{ |
1427 |
|
/* The value of -1 must be kept for start_used_ptr! */ |
1428 |
|
OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1); |
1429 |
|
/* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting |
1430 |
|
is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ |
1431 |
|
jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); |
1432 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1433 |
|
JUMPHERE(jump); |
1434 |
|
} |
1435 |
|
else if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
1436 |
|
{ |
1437 |
|
jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1438 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1439 |
|
JUMPHERE(jump); |
1440 |
|
} |
1441 |
|
} |
1442 |
|
|
1443 |
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) |
1444 |
{ |
{ |
1445 |
/* Detects if the character has an othercase. */ |
/* Detects if the character has an othercase. */ |
1561 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
1562 |
} |
} |
1563 |
|
|
1564 |
static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks) |
static void check_partial(compiler_common *common, BOOL force) |
1565 |
|
{ |
1566 |
|
/* Checks whether a partial matching is occured. Does not modify registers. */ |
1567 |
|
DEFINE_COMPILER; |
1568 |
|
struct sljit_jump *jump = NULL; |
1569 |
|
|
1570 |
|
SLJIT_ASSERT(!force || common->mode != JIT_COMPILE); |
1571 |
|
|
1572 |
|
if (common->mode == JIT_COMPILE) |
1573 |
|
return; |
1574 |
|
|
1575 |
|
if (!force) |
1576 |
|
jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1577 |
|
else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1578 |
|
jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); |
1579 |
|
|
1580 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1581 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
1582 |
|
else |
1583 |
|
{ |
1584 |
|
if (common->partialmatchlabel != NULL) |
1585 |
|
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
1586 |
|
else |
1587 |
|
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
1588 |
|
} |
1589 |
|
|
1590 |
|
if (jump != NULL) |
1591 |
|
JUMPHERE(jump); |
1592 |
|
} |
1593 |
|
|
1594 |
|
static struct sljit_jump *check_str_end(compiler_common *common) |
1595 |
{ |
{ |
1596 |
|
/* Does not affect registers. Usually used in a tight spot. */ |
1597 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
1598 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
struct sljit_jump *jump; |
1599 |
|
struct sljit_jump *nohit; |
1600 |
|
struct sljit_jump *return_value; |
1601 |
|
|
1602 |
|
if (common->mode == JIT_COMPILE) |
1603 |
|
return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
1604 |
|
|
1605 |
|
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
1606 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1607 |
|
{ |
1608 |
|
nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1609 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
1610 |
|
JUMPHERE(nohit); |
1611 |
|
return_value = JUMP(SLJIT_JUMP); |
1612 |
|
} |
1613 |
|
else |
1614 |
|
{ |
1615 |
|
return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1616 |
|
if (common->partialmatchlabel != NULL) |
1617 |
|
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
1618 |
|
else |
1619 |
|
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
1620 |
|
} |
1621 |
|
JUMPHERE(jump); |
1622 |
|
return return_value; |
1623 |
|
} |
1624 |
|
|
1625 |
|
static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks) |
1626 |
|
{ |
1627 |
|
DEFINE_COMPILER; |
1628 |
|
struct sljit_jump *jump; |
1629 |
|
|
1630 |
|
if (common->mode == JIT_COMPILE) |
1631 |
|
{ |
1632 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
1633 |
|
return; |
1634 |
|
} |
1635 |
|
|
1636 |
|
/* Partial matching mode. */ |
1637 |
|
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
1638 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); |
1639 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1640 |
|
{ |
1641 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
1642 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
1643 |
|
} |
1644 |
|
else |
1645 |
|
{ |
1646 |
|
if (common->partialmatchlabel != NULL) |
1647 |
|
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
1648 |
|
else |
1649 |
|
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
1650 |
|
} |
1651 |
|
JUMPHERE(jump); |
1652 |
} |
} |
1653 |
|
|
1654 |
static void read_char(compiler_common *common) |
static void read_char(compiler_common *common) |
1824 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
1825 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
1826 |
|
|
1827 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
1828 |
/* Searching for the first zero. */ |
/* Searching for the first zero. */ |
1829 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); |
1830 |
jump = JUMP(SLJIT_C_NOT_ZERO); |
jump = JUMP(SLJIT_C_NOT_ZERO); |
1883 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
1884 |
struct sljit_jump *compare; |
struct sljit_jump *compare; |
1885 |
|
|
1886 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
1887 |
|
|
1888 |
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); |
1889 |
jump = JUMP(SLJIT_C_NOT_ZERO); |
jump = JUMP(SLJIT_C_NOT_ZERO); |
1920 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
1921 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
1922 |
|
|
1923 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
1924 |
jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00); |
jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00); |
1925 |
/* Do nothing, only return. */ |
/* Do nothing, only return. */ |
1926 |
sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
1957 |
|
|
1958 |
SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); |
SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); |
1959 |
|
|
1960 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
1961 |
OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); |
OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); |
1962 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1)); |
1963 |
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); |
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); |
1993 |
if (firstline) |
if (firstline) |
1994 |
{ |
{ |
1995 |
/* Search for the end of the first line. */ |
/* Search for the end of the first line. */ |
1996 |
|
SLJIT_ASSERT(common->first_line_end != 0); |
1997 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); |
1998 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0); |
1999 |
|
|
2000 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
2001 |
{ |
{ |
2006 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
2007 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); |
2008 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); |
2009 |
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
2010 |
} |
} |
2011 |
else |
else |
2012 |
{ |
{ |
2013 |
end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
2014 |
mainloop = LABEL(); |
mainloop = LABEL(); |
2015 |
/* Continual stores does not cause data dependency. */ |
/* Continual stores does not cause data dependency. */ |
2016 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); |
2017 |
read_char(common); |
read_char(common); |
2018 |
check_newlinechar(common, common->nltype, &newline, TRUE); |
check_newlinechar(common, common->nltype, &newline, TRUE); |
2019 |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
2020 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); |
2021 |
set_jumps(newline, LABEL()); |
set_jumps(newline, LABEL()); |
2022 |
} |
} |
2023 |
|
|
2100 |
if (firstline) |
if (firstline) |
2101 |
{ |
{ |
2102 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
2103 |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); |
2104 |
} |
} |
2105 |
|
|
2106 |
start = LABEL(); |
start = LABEL(); |
2178 |
if (firstline) |
if (firstline) |
2179 |
{ |
{ |
2180 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
2181 |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); |
2182 |
} |
} |
2183 |
|
|
2184 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
2262 |
if (firstline) |
if (firstline) |
2263 |
{ |
{ |
2264 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
2265 |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); |
2266 |
} |
} |
2267 |
|
|
2268 |
start = LABEL(); |
start = LABEL(); |
2327 |
struct sljit_jump *notfound; |
struct sljit_jump *notfound; |
2328 |
pcre_uchar oc, bit; |
pcre_uchar oc, bit; |
2329 |
|
|
2330 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR); |
SLJIT_ASSERT(common->req_char_ptr != 0); |
2331 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); |
2332 |
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); |
2333 |
toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); |
toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); |
2334 |
alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); |
alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); |
2373 |
JUMPHERE(found); |
JUMPHERE(found); |
2374 |
if (foundoc) |
if (foundoc) |
2375 |
JUMPHERE(foundoc); |
JUMPHERE(foundoc); |
2376 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0); |
2377 |
JUMPHERE(alreadyfound); |
JUMPHERE(alreadyfound); |
2378 |
JUMPHERE(toolong); |
JUMPHERE(toolong); |
2379 |
return notfound; |
return notfound; |
2385 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
2386 |
struct sljit_label *mainloop; |
struct sljit_label *mainloop; |
2387 |
|
|
2388 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
2389 |
OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); |
OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0); |
2390 |
|
GET_LOCAL_BASE(TMP3, 0, 0); |
2391 |
|
|
2392 |
/* Drop frames until we reach STACK_TOP. */ |
/* Drop frames until we reach STACK_TOP. */ |
2393 |
mainloop = LABEL(); |
mainloop = LABEL(); |
2394 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); |
2395 |
jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); |
jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); |
2396 |
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0); |
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); |
2397 |
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
2398 |
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); |
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); |
2399 |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); |
2413 |
JUMPTO(SLJIT_JUMP, mainloop); |
JUMPTO(SLJIT_JUMP, mainloop); |
2414 |
|
|
2415 |
JUMPHERE(jump); |
JUMPHERE(jump); |
2416 |
|
if (common->mark_ptr != 0) |
2417 |
|
{ |
2418 |
|
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark); |
2419 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
2420 |
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); |
2421 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
2422 |
|
JUMPTO(SLJIT_JUMP, mainloop); |
2423 |
|
|
2424 |
|
JUMPHERE(jump); |
2425 |
|
} |
2426 |
|
|
2427 |
/* Unknown command. */ |
/* Unknown command. */ |
2428 |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); |
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); |
2429 |
JUMPTO(SLJIT_JUMP, mainloop); |
JUMPTO(SLJIT_JUMP, mainloop); |
2432 |
static void check_wordboundary(compiler_common *common) |
static void check_wordboundary(compiler_common *common) |
2433 |
{ |
{ |
2434 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
2435 |
struct sljit_jump *beginend; |
struct sljit_jump *skipread; |
2436 |
#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF |
#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF |
2437 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
2438 |
#endif |
#endif |
2439 |
|
|
2440 |
SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); |
SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); |
2441 |
|
|
2442 |
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
2443 |
/* Get type of the previous char, and put it to LOCALS1. */ |
/* Get type of the previous char, and put it to LOCALS1. */ |
2444 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
2445 |
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)); |
2446 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); |
2447 |
beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); |
skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); |
2448 |
skip_char_back(common); |
skip_char_back(common); |
2449 |
|
check_start_used_ptr(common); |
2450 |
read_char(common); |
read_char(common); |
2451 |
|
|
2452 |
/* Testing char type. */ |
/* Testing char type. */ |
2487 |
JUMPHERE(jump); |
JUMPHERE(jump); |
2488 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
2489 |
} |
} |
2490 |
JUMPHERE(beginend); |
JUMPHERE(skipread); |
2491 |
|
|
2492 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
2493 |
beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
skipread = check_str_end(common); |
2494 |
peek_char(common); |
peek_char(common); |
2495 |
|
|
2496 |
/* Testing char type. This is a code duplication. */ |
/* Testing char type. This is a code duplication. */ |
2531 |
JUMPHERE(jump); |
JUMPHERE(jump); |
2532 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
2533 |
} |
} |
2534 |
JUMPHERE(beginend); |
JUMPHERE(skipread); |
2535 |
|
|
2536 |
OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); |
OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); |
2537 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
2542 |
/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ |
/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ |
2543 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
2544 |
|
|
2545 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
2546 |
|
|
2547 |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); |
2548 |
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); |
2569 |
/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ |
/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ |
2570 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
2571 |
|
|
2572 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
2573 |
|
|
2574 |
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); |
2575 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
2608 |
/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ |
/* Check whether TMP1 contains a newline character. TMP2 destroyed. */ |
2609 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
2610 |
|
|
2611 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
2612 |
|
|
2613 |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); |
2614 |
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); |
2640 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
2641 |
struct sljit_label *label; |
struct sljit_label *label; |
2642 |
|
|
2643 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
2644 |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
2645 |
OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); |
OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0); |
2646 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0); |
2669 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
2670 |
struct sljit_label *label; |
struct sljit_label *label; |
2671 |
|
|
2672 |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); |
2673 |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
2674 |
|
|
2675 |
OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); |
OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); |
2716 |
{ |
{ |
2717 |
/* This function would be ineffective to do in JIT level. */ |
/* This function would be ineffective to do in JIT level. */ |
2718 |
int c1, c2; |
int c1, c2; |
2719 |
const pcre_uchar *src2 = args->ptr; |
const pcre_uchar *src2 = args->uchar_ptr; |
2720 |
const pcre_uchar *end2 = args->end; |
const pcre_uchar *end2 = args->end; |
2721 |
|
|
2722 |
while (src1 < end1) |
while (src1 < end1) |
2723 |
{ |
{ |
2724 |
if (src2 >= end2) |
if (src2 >= end2) |
2725 |
return 0; |
return (pcre_uchar*)1; |
2726 |
GETCHARINC(c1, src1); |
GETCHARINC(c1, src1); |
2727 |
GETCHARINC(c2, src2); |
GETCHARINC(c2, src2); |
2728 |
if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0; |
if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL; |
2729 |
} |
} |
2730 |
return src2; |
return src2; |
2731 |
} |
} |
2931 |
unsigned int charoffset; |
unsigned int charoffset; |
2932 |
|
|
2933 |
/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ |
/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ |
2934 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
2935 |
read_char(common); |
read_char(common); |
2936 |
|
|
2937 |
if ((*cc++ & XCL_MAP) != 0) |
if ((*cc++ & XCL_MAP) != 0) |
3285 |
|
|
3286 |
case OP_NOT_DIGIT: |
case OP_NOT_DIGIT: |
3287 |
case OP_DIGIT: |
case OP_DIGIT: |
3288 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3289 |
read_char8_type(common); |
read_char8_type(common); |
3290 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); |
3291 |
add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
3293 |
|
|
3294 |
case OP_NOT_WHITESPACE: |
case OP_NOT_WHITESPACE: |
3295 |
case OP_WHITESPACE: |
case OP_WHITESPACE: |
3296 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3297 |
read_char8_type(common); |
read_char8_type(common); |
3298 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); |
3299 |
add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
3301 |
|
|
3302 |
case OP_NOT_WORDCHAR: |
case OP_NOT_WORDCHAR: |
3303 |
case OP_WORDCHAR: |
case OP_WORDCHAR: |
3304 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3305 |
read_char8_type(common); |
read_char8_type(common); |
3306 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); |
3307 |
add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
3308 |
return cc; |
return cc; |
3309 |
|
|
3310 |
case OP_ANY: |
case OP_ANY: |
3311 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3312 |
read_char(common); |
read_char(common); |
3313 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3314 |
{ |
{ |
3315 |
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
3316 |
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
3317 |
|
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3318 |
|
else |
3319 |
|
jump[1] = check_str_end(common); |
3320 |
|
|
3321 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3322 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff)); |
3323 |
JUMPHERE(jump[1]); |
if (jump[1] != NULL) |
3324 |
|
JUMPHERE(jump[1]); |
3325 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
3326 |
} |
} |
3327 |
else |
else |
3329 |
return cc; |
return cc; |
3330 |
|
|
3331 |
case OP_ALLANY: |
case OP_ALLANY: |
3332 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3333 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
3334 |
if (common->utf) |
if (common->utf) |
3335 |
{ |
{ |
3357 |
return cc; |
return cc; |
3358 |
|
|
3359 |
case OP_ANYBYTE: |
case OP_ANYBYTE: |
3360 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3361 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
3362 |
return cc; |
return cc; |
3363 |
|
|
3376 |
#endif |
#endif |
3377 |
|
|
3378 |
case OP_ANYNL: |
case OP_ANYNL: |
3379 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3380 |
read_char(common); |
read_char(common); |
3381 |
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); |
3382 |
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
/* We don't need to handle soft partial matching case. */ |
3383 |
|
if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
3384 |
|
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3385 |
|
else |
3386 |
|
jump[1] = check_str_end(common); |
3387 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3388 |
jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); |
jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); |
3389 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); |
3397 |
|
|
3398 |
case OP_NOT_HSPACE: |
case OP_NOT_HSPACE: |
3399 |
case OP_HSPACE: |
case OP_HSPACE: |
3400 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3401 |
read_char(common); |
read_char(common); |
3402 |
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
3403 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
3405 |
|
|
3406 |
case OP_NOT_VSPACE: |
case OP_NOT_VSPACE: |
3407 |
case OP_VSPACE: |
case OP_VSPACE: |
3408 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3409 |
read_char(common); |
read_char(common); |
3410 |
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
3411 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
3413 |
|
|
3414 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
3415 |
case OP_EXTUNI: |
case OP_EXTUNI: |
3416 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3417 |
read_char(common); |
read_char(common); |
3418 |
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
3419 |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); |
3429 |
|
|
3430 |
OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
3431 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
3432 |
|
if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
3433 |
|
{ |
3434 |
|
jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
3435 |
|
/* Since we successfully read a char above, partial matching must occure. */ |
3436 |
|
check_partial(common, TRUE); |
3437 |
|
JUMPHERE(jump[0]); |
3438 |
|
} |
3439 |
return cc; |
return cc; |
3440 |
#endif |
#endif |
3441 |
|
|
3442 |
case OP_EODN: |
case OP_EODN: |
3443 |
|
/* Requires rather complex checks. */ |
3444 |
jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3445 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3446 |
{ |
{ |
3447 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
3448 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
3449 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
if (common->mode == JIT_COMPILE) |
3450 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
3451 |
|
else |
3452 |
|
{ |
3453 |
|
jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); |
3454 |
|
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); |
3455 |
|
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); |
3456 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
3457 |
|
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); |
3458 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL)); |
3459 |
|
check_partial(common, TRUE); |
3460 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3461 |
|
JUMPHERE(jump[1]); |
3462 |
|
} |
3463 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
3464 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
3465 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
3504 |
JUMPHERE(jump[3]); |
JUMPHERE(jump[3]); |
3505 |
} |
} |
3506 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
3507 |
|
check_partial(common, FALSE); |
3508 |
return cc; |
return cc; |
3509 |
|
|
3510 |
case OP_EOD: |
case OP_EOD: |
3511 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
3512 |
|
check_partial(common, FALSE); |
3513 |
return cc; |
return cc; |
3514 |
|
|
3515 |
case OP_CIRC: |
case OP_CIRC: |
3529 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
3530 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
3531 |
|
|
3532 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
3533 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3534 |
{ |
{ |
3535 |
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
3556 |
if (!common->endonly) |
if (!common->endonly) |
3557 |
compile_char1_hotpath(common, OP_EODN, cc, fallbacks); |
compile_char1_hotpath(common, OP_EODN, cc, fallbacks); |
3558 |
else |
else |
3559 |
|
{ |
3560 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); |
3561 |
|
check_partial(common, FALSE); |
3562 |
|
} |
3563 |
return cc; |
return cc; |
3564 |
|
|
3565 |
case OP_DOLLM: |
case OP_DOLLM: |
3567 |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
3568 |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); |
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); |
3569 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
3570 |
|
check_partial(common, FALSE); |
3571 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
3572 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
3573 |
|
|
3574 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3575 |
{ |
{ |
3576 |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); |
|
3577 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
3578 |
|
if (common->mode == JIT_COMPILE) |
3579 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); |
3580 |
|
else |
3581 |
|
{ |
3582 |
|
jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); |
3583 |
|
/* STR_PTR = STR_END - IN_UCHARS(1) */ |
3584 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
3585 |
|
check_partial(common, TRUE); |
3586 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3587 |
|
JUMPHERE(jump[1]); |
3588 |
|
} |
3589 |
|
|
3590 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
3591 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
3592 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); |
3605 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
3606 |
if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); |
if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); |
3607 |
#endif |
#endif |
3608 |
if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) |
if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) |
3609 |
{ |
{ |
3610 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
3611 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
3617 |
#endif |
#endif |
3618 |
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks); |
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks); |
3619 |
} |
} |
3620 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3621 |
read_char(common); |
read_char(common); |
3622 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
3623 |
if (common->utf) |
if (common->utf) |
3627 |
else |
else |
3628 |
#endif |
#endif |
3629 |
c = *cc; |
c = *cc; |
3630 |
|
if (type == OP_CHAR || !char_has_othercase(common, cc)) |
3631 |
|
{ |
3632 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
3633 |
|
return cc + length; |
3634 |
|
} |
3635 |
|
oc = char_othercase(common, c); |
3636 |
|
bit = c ^ oc; |
3637 |
|
if (ispowerof2(bit)) |
3638 |
|
{ |
3639 |
|
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
3640 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
3641 |
|
return cc + length; |
3642 |
|
} |
3643 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); |
3644 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
3645 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); |
3649 |
|
|
3650 |
case OP_NOT: |
case OP_NOT: |
3651 |
case OP_NOTI: |
case OP_NOTI: |
3652 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3653 |
length = 1; |
length = 1; |
3654 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
3655 |
if (common->utf) |
if (common->utf) |
3706 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc)); |
3707 |
} |
} |
3708 |
} |
} |
3709 |
return cc + 1; |
return cc + length; |
3710 |
|
|
3711 |
case OP_CLASS: |
case OP_CLASS: |
3712 |
case OP_NCLASS: |
case OP_NCLASS: |
3713 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3714 |
read_char(common); |
read_char(common); |
3715 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
3716 |
jump[0] = NULL; |
jump[0] = NULL; |
3748 |
|
|
3749 |
case OP_REVERSE: |
case OP_REVERSE: |
3750 |
length = GET(cc, 0); |
length = GET(cc, 0); |
3751 |
SLJIT_ASSERT(length > 0); |
if (length == 0) |
3752 |
|
return cc + LINK_SIZE; |
3753 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
3754 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
3755 |
if (common->utf) |
if (common->utf) |
3761 |
skip_char_back(common); |
skip_char_back(common); |
3762 |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); |
3763 |
JUMPTO(SLJIT_C_NOT_ZERO, label); |
JUMPTO(SLJIT_C_NOT_ZERO, label); |
|
return cc + LINK_SIZE; |
|
3764 |
} |
} |
3765 |
|
else |
3766 |
#endif |
#endif |
3767 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
{ |
3768 |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
3769 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
3770 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); |
3771 |
|
} |
3772 |
|
check_start_used_ptr(common); |
3773 |
return cc + LINK_SIZE; |
return cc + LINK_SIZE; |
3774 |
} |
} |
3775 |
SLJIT_ASSERT_STOP(); |
SLJIT_ASSERT_STOP(); |
3852 |
{ |
{ |
3853 |
if (fallbacks == NULL) |
if (fallbacks == NULL) |
3854 |
{ |
{ |
3855 |
|
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
3856 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
3857 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
3858 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
3894 |
} \ |
} \ |
3895 |
while (0) |
while (0) |
3896 |
|
|
3897 |
#define FALLBACK_AS(type) ((type*)fallback) |
#define FALLBACK_AS(type) ((type *)fallback) |
3898 |
|
|
3899 |
static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail) |
static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail) |
3900 |
{ |
{ |
3901 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
3902 |
int offset = GET2(cc, 1) << 1; |
int offset = GET2(cc, 1) << 1; |
3903 |
struct sljit_jump *jump = NULL; |
struct sljit_jump *jump = NULL; |
3904 |
|
struct sljit_jump *partial; |
3905 |
|
struct sljit_jump *nopartial; |
3906 |
|
|
3907 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
3908 |
|
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
3909 |
if (withchecks && !common->jscript_compat) |
if (withchecks && !common->jscript_compat) |
3910 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
3911 |
|
|
3920 |
/* Needed to save important temporary registers. */ |
/* Needed to save important temporary registers. */ |
3921 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
3922 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
3923 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); |
3924 |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); |
3925 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
3926 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
if (common->mode == JIT_COMPILE) |
3927 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); |
3928 |
|
else |
3929 |
|
{ |
3930 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
3931 |
|
nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
3932 |
|
check_partial(common, FALSE); |
3933 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3934 |
|
JUMPHERE(nopartial); |
3935 |
|
} |
3936 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); |
3937 |
} |
} |
3938 |
else |
else |
3941 |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); |
3942 |
if (withchecks) |
if (withchecks) |
3943 |
jump = JUMP(SLJIT_C_ZERO); |
jump = JUMP(SLJIT_C_ZERO); |
3944 |
|
|
3945 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
3946 |
|
partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); |
3947 |
|
if (common->mode == JIT_COMPILE) |
3948 |
|
add_jump(compiler, fallbacks, partial); |
3949 |
|
|
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
|
3950 |
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
3951 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
3952 |
|
|
3953 |
|
if (common->mode != JIT_COMPILE) |
3954 |
|
{ |
3955 |
|
nopartial = JUMP(SLJIT_JUMP); |
3956 |
|
JUMPHERE(partial); |
3957 |
|
/* TMP2 -= STR_END - STR_PTR */ |
3958 |
|
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); |
3959 |
|
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); |
3960 |
|
partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); |
3961 |
|
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); |
3962 |
|
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
3963 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
3964 |
|
JUMPHERE(partial); |
3965 |
|
check_partial(common, FALSE); |
3966 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3967 |
|
JUMPHERE(nopartial); |
3968 |
|
} |
3969 |
} |
} |
3970 |
|
|
3971 |
if (jump != NULL) |
if (jump != NULL) |
4155 |
common->entries = entry; |
common->entries = entry; |
4156 |
} |
} |
4157 |
|
|
4158 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
if (common->has_set_som && common->mark_ptr != 0) |
4159 |
allocate_stack(common, 1); |
{ |
4160 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
4161 |
|
allocate_stack(common, 2); |
4162 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
4163 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
4164 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
4165 |
|
} |
4166 |
|
else if (common->has_set_som || common->mark_ptr != 0) |
4167 |
|
{ |
4168 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); |
4169 |
|
allocate_stack(common, 1); |
4170 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
4171 |
|
} |
4172 |
|
|
4173 |
if (entry->entry == NULL) |
if (entry->entry == NULL) |
4174 |
add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); |
4192 |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
4193 |
jump_list **found; |
jump_list **found; |
4194 |
/* Saving previous accept variables. */ |
/* Saving previous accept variables. */ |
4195 |
|
struct sljit_label *save_leavelabel = common->leavelabel; |
4196 |
struct sljit_label *save_acceptlabel = common->acceptlabel; |
struct sljit_label *save_acceptlabel = common->acceptlabel; |
4197 |
|
jump_list *save_leave = common->leave; |
4198 |
|
jump_list *save_accept = common->accept; |
4199 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
4200 |
struct sljit_jump *brajump = NULL; |
struct sljit_jump *brajump = NULL; |
|
jump_list *save_accept = common->accept; |
|
4201 |
|
|
4202 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
4203 |
{ |
{ |
4242 |
} |
} |
4243 |
|
|
4244 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altfallback, 0, sizeof(fallback_common)); |
4245 |
|
common->leavelabel = NULL; |
4246 |
|
common->leave = NULL; |
4247 |
while (1) |
while (1) |
4248 |
{ |
{ |
4249 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
4258 |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
4259 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
4260 |
{ |
{ |
4261 |
|
common->leavelabel = save_leavelabel; |
4262 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
4263 |
|
common->leave = save_leave; |
4264 |
common->accept = save_accept; |
common->accept = save_accept; |
4265 |
return NULL; |
return NULL; |
4266 |
} |
} |
4313 |
compile_fallbackpath(common, altfallback.top); |
compile_fallbackpath(common, altfallback.top); |
4314 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
4315 |
{ |
{ |
4316 |
|
common->leavelabel = save_leavelabel; |
4317 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
4318 |
|
common->leave = save_leave; |
4319 |
common->accept = save_accept; |
common->accept = save_accept; |
4320 |
return NULL; |
return NULL; |
4321 |
} |
} |
4328 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
4329 |
} |
} |
4330 |
/* None of them matched. */ |
/* None of them matched. */ |
4331 |
|
if (common->leave != NULL) |
4332 |
|
set_jumps(common->leave, LABEL()); |
4333 |
|
|
4334 |
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
4335 |
{ |
{ |
4454 |
} |
} |
4455 |
} |
} |
4456 |
|
|
4457 |
|
common->leavelabel = save_leavelabel; |
4458 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
4459 |
|
common->leave = save_leave; |
4460 |
common->accept = save_accept; |
common->accept = save_accept; |
4461 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
4462 |
} |
} |
4471 |
sljit_w no_capture; |
sljit_w no_capture; |
4472 |
int i; |
int i; |
4473 |
|
|
4474 |
locals += OVECTOR_START / sizeof(sljit_w); |
locals += refno & 0xff; |
4475 |
|
refno >>= 8; |
4476 |
no_capture = locals[1]; |
no_capture = locals[1]; |
4477 |
|
|
4478 |
for (i = 0; i < name_count; i++) |
for (i = 0; i < name_count; i++) |
4872 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
4873 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); |
4874 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
4875 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w))); |
4876 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); |
GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); |
4877 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
4878 |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); |
4879 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
4923 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
4924 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); |
4925 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); |
4926 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); |
GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); |
4927 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
4928 |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); |
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); |
4929 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
5036 |
if (bra == OP_BRAMINZERO) |
if (bra == OP_BRAMINZERO) |
5037 |
{ |
{ |
5038 |
/* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */ |
/* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */ |
5039 |
JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath); |
JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath); |
5040 |
if (braminzerojump != NULL) |
if (braminzerojump != NULL) |
5041 |
{ |
{ |
5042 |
JUMPHERE(braminzerojump); |
JUMPHERE(braminzerojump); |
5321 |
SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); |
SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS); |
5322 |
*type = *opcode; |
*type = *opcode; |
5323 |
cc++; |
cc++; |
5324 |
class_len = (*type < OP_XCLASS) ? (1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); |
class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); |
5325 |
*opcode = cc[class_len - 1]; |
*opcode = cc[class_len - 1]; |
5326 |
if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) |
if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) |
5327 |
{ |
{ |
5647 |
|
|
5648 |
case OP_SET_SOM: |
case OP_SET_SOM: |
5649 |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
5650 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
5651 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
|
5652 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); |
5653 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
5654 |
cc++; |
cc++; |
5655 |
break; |
break; |
5656 |
|
|
5657 |
case OP_CHAR: |
case OP_CHAR: |
5658 |
case OP_CHARI: |
case OP_CHARI: |
5659 |
cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
if (common->mode == JIT_COMPILE) |
5660 |
|
cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
5661 |
|
else |
5662 |
|
cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
5663 |
break; |
break; |
5664 |
|
|
5665 |
case OP_STAR: |
case OP_STAR: |
5815 |
cc = compile_bracketpos_hotpath(common, cc, parent); |
cc = compile_bracketpos_hotpath(common, cc, parent); |
5816 |
break; |
break; |
5817 |
|
|
5818 |
|
case OP_MARK: |
5819 |
|
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
5820 |
|
SLJIT_ASSERT(common->mark_ptr != 0); |
5821 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
5822 |
|
allocate_stack(common, 1); |
5823 |
|
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
5824 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
5825 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2)); |
5826 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
5827 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
5828 |
|
cc += 1 + 2 + cc[1]; |
5829 |
|
break; |
5830 |
|
|
5831 |
|
case OP_COMMIT: |
5832 |
|
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
5833 |
|
cc += 1; |
5834 |
|
break; |
5835 |
|
|
5836 |
case OP_FAIL: |
case OP_FAIL: |
5837 |
case OP_ACCEPT: |
case OP_ACCEPT: |
5838 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
5870 |
} \ |
} \ |
5871 |
while (0) |
while (0) |
5872 |
|
|
5873 |
#define CURRENT_AS(type) ((type*)current) |
#define CURRENT_AS(type) ((type *)current) |
5874 |
|
|
5875 |
static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) |
5876 |
{ |
{ |
6026 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
6027 |
|
|
6028 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topfallbacks, LABEL()); |
6029 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
|
6030 |
free_stack(common, 1); |
if (common->has_set_som && common->mark_ptr != 0) |
6031 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); |
{ |
6032 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6033 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
6034 |
|
free_stack(common, 2); |
6035 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); |
6036 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); |
6037 |
|
} |
6038 |
|
else if (common->has_set_som || common->mark_ptr != 0) |
6039 |
|
{ |
6040 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6041 |
|
free_stack(common, 1); |
6042 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); |
6043 |
|
} |
6044 |
} |
} |
6045 |
|
|
6046 |
static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current) |
6676 |
compile_braminzero_fallbackpath(common, current); |
compile_braminzero_fallbackpath(common, current); |
6677 |
break; |
break; |
6678 |
|
|
6679 |
|
case OP_MARK: |
6680 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6681 |
|
free_stack(common, 1); |
6682 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); |
6683 |
|
break; |
6684 |
|
|
6685 |
|
case OP_COMMIT: |
6686 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
6687 |
|
if (common->leavelabel == NULL) |
6688 |
|
add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); |
6689 |
|
else |
6690 |
|
JUMPTO(SLJIT_JUMP, common->leavelabel); |
6691 |
|
break; |
6692 |
|
|
6693 |
case OP_FAIL: |
case OP_FAIL: |
6694 |
case OP_ACCEPT: |
case OP_ACCEPT: |
6695 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
6715 |
int alternativesize; |
int alternativesize; |
6716 |
BOOL needsframe; |
BOOL needsframe; |
6717 |
fallback_common altfallback; |
fallback_common altfallback; |
6718 |
|
struct sljit_label *save_leavelabel = common->leavelabel; |
6719 |
|
jump_list *save_leave = common->leave; |
6720 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
6721 |
|
|
6722 |
SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); |
SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); |
6725 |
framesize = 0; |
framesize = 0; |
6726 |
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; |
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; |
6727 |
|
|
6728 |
SLJIT_ASSERT(common->currententry->entry == NULL); |
SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); |
6729 |
common->currententry->entry = LABEL(); |
common->currententry->entry = LABEL(); |
6730 |
set_jumps(common->currententry->calls, common->currententry->entry); |
set_jumps(common->currententry->calls, common->currententry->entry); |
6731 |
|
|
6732 |
sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, TMP2, 0); |
6733 |
allocate_stack(common, localsize + framesize + alternativesize); |
allocate_stack(common, localsize + framesize + alternativesize); |
6734 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); |
6735 |
copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); |
copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); |
6736 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0); |
6737 |
if (needsframe) |
if (needsframe) |
6738 |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE); |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); |
6739 |
|
|
6740 |
if (alternativesize > 0) |
if (alternativesize > 0) |
6741 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
6742 |
|
|
6743 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altfallback, 0, sizeof(fallback_common)); |
6744 |
|
common->leavelabel = NULL; |
6745 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
6746 |
|
common->leave = NULL; |
6747 |
common->accept = NULL; |
common->accept = NULL; |
6748 |
altfallback.cc = ccbegin; |
altfallback.cc = ccbegin; |
6749 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
6757 |
|
|
6758 |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
6759 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
6760 |
|
{ |
6761 |
|
common->leavelabel = save_leavelabel; |
6762 |
|
common->leave = save_leave; |
6763 |
return; |
return; |
6764 |
|
} |
6765 |
|
|
6766 |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
6767 |
|
|
6768 |
compile_fallbackpath(common, altfallback.top); |
compile_fallbackpath(common, altfallback.top); |
6769 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
6770 |
|
{ |
6771 |
|
common->leavelabel = save_leavelabel; |
6772 |
|
common->leave = save_leave; |
6773 |
return; |
return; |
6774 |
|
} |
6775 |
set_jumps(altfallback.topfallbacks, LABEL()); |
set_jumps(altfallback.topfallbacks, LABEL()); |
6776 |
|
|
6777 |
if (*cc != OP_ALT) |
if (*cc != OP_ALT) |
6781 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
6782 |
} |
} |
6783 |
/* None of them matched. */ |
/* None of them matched. */ |
6784 |
|
if (common->leave != NULL) |
6785 |
|
set_jumps(common->leave, LABEL()); |
6786 |
|
|
6787 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); |
6788 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
6789 |
|
|
6790 |
set_jumps(common->accept, LABEL()); |
set_jumps(common->accept, LABEL()); |
6791 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head); |
6792 |
if (needsframe) |
if (needsframe) |
6793 |
{ |
{ |
|
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
|
6794 |
OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); |
OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); |
6795 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
6796 |
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); |
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0); |
|
6797 |
} |
} |
6798 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); |
6799 |
|
|
6802 |
free_stack(common, localsize + framesize + alternativesize); |
free_stack(common, localsize + framesize + alternativesize); |
6803 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); |
6804 |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
6805 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); |
6806 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
6807 |
|
|
6808 |
|
common->leavelabel = save_leavelabel; |
6809 |
|
common->leave = save_leave; |
6810 |
} |
} |
6811 |
|
|
6812 |
#undef COMPILE_FALLBACKPATH |
#undef COMPILE_FALLBACKPATH |
6813 |
#undef CURRENT_AS |
#undef CURRENT_AS |
6814 |
|
|
6815 |
void |
void |
6816 |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra) |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) |
6817 |
{ |
{ |
6818 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
6819 |
fallback_common rootfallback; |
fallback_common rootfallback; |
6821 |
compiler_common *common = &common_data; |
compiler_common *common = &common_data; |
6822 |
const pcre_uint8 *tables = re->tables; |
const pcre_uint8 *tables = re->tables; |
6823 |
pcre_study_data *study; |
pcre_study_data *study; |
6824 |
|
int localsize; |
6825 |
pcre_uchar *ccend; |
pcre_uchar *ccend; |
6826 |
executable_function *function; |
executable_functions *functions; |
6827 |
void *executable_func; |
void *executable_func; |
6828 |
sljit_uw executable_size; |
sljit_uw executable_size; |
|
struct sljit_label *leave; |
|
6829 |
struct sljit_label *mainloop = NULL; |
struct sljit_label *mainloop = NULL; |
6830 |
struct sljit_label *empty_match_found; |
struct sljit_label *empty_match_found; |
6831 |
struct sljit_label *empty_match_fallback; |
struct sljit_label *empty_match_fallback; |
6832 |
struct sljit_jump *alloc_error; |
struct sljit_jump *jump; |
6833 |
struct sljit_jump *reqbyte_notfound = NULL; |
struct sljit_jump *reqbyte_notfound = NULL; |
6834 |
struct sljit_jump *empty_match; |
struct sljit_jump *empty_match; |
6835 |
|
|
6840 |
tables = PRIV(default_tables); |
tables = PRIV(default_tables); |
6841 |
|
|
6842 |
memset(&rootfallback, 0, sizeof(fallback_common)); |
memset(&rootfallback, 0, sizeof(fallback_common)); |
6843 |
|
memset(common, 0, sizeof(compiler_common)); |
6844 |
rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; |
rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size; |
6845 |
|
|
|
common->compiler = NULL; |
|
6846 |
common->start = rootfallback.cc; |
common->start = rootfallback.cc; |
|
common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); |
|
6847 |
common->fcc = tables + fcc_offset; |
common->fcc = tables + fcc_offset; |
6848 |
common->lcc = (sljit_w)(tables + lcc_offset); |
common->lcc = (sljit_w)(tables + lcc_offset); |
6849 |
|
common->mode = mode; |
6850 |
common->nltype = NLTYPE_FIXED; |
common->nltype = NLTYPE_FIXED; |
6851 |
switch(re->options & PCRE_NEWLINE_BITS) |
switch(re->options & PCRE_NEWLINE_BITS) |
6852 |
{ |
{ |
6884 |
common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); |
common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); |
6885 |
common->name_count = re->name_count; |
common->name_count = re->name_count; |
6886 |
common->name_entry_size = re->name_entry_size; |
common->name_entry_size = re->name_entry_size; |
|
common->acceptlabel = NULL; |
|
|
common->stubs = NULL; |
|
|
common->entries = NULL; |
|
|
common->currententry = NULL; |
|
|
common->accept = NULL; |
|
|
common->calllimit = NULL; |
|
|
common->stackalloc = NULL; |
|
|
common->revertframes = NULL; |
|
|
common->wordboundary = NULL; |
|
|
common->anynewline = NULL; |
|
|
common->hspace = NULL; |
|
|
common->vspace = NULL; |
|
|
common->casefulcmp = NULL; |
|
|
common->caselesscmp = NULL; |
|
6887 |
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; |
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; |
6888 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
6889 |
/* PCRE_UTF16 has the same value as PCRE_UTF8. */ |
/* PCRE_UTF16 has the same value as PCRE_UTF8. */ |
6891 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
6892 |
common->use_ucp = (re->options & PCRE_UCP) != 0; |
common->use_ucp = (re->options & PCRE_UCP) != 0; |
6893 |
#endif |
#endif |
|
common->utfreadchar = NULL; |
|
|
#ifdef COMPILE_PCRE8 |
|
|
common->utfreadtype8 = NULL; |
|
|
#endif |
|
6894 |
#endif /* SUPPORT_UTF */ |
#endif /* SUPPORT_UTF */ |
|
#ifdef SUPPORT_UCP |
|
|
common->getucd = NULL; |
|
|
#endif |
|
6895 |
ccend = bracketend(rootfallback.cc); |
ccend = bracketend(rootfallback.cc); |
6896 |
|
|
6897 |
|
/* Calculate the local space size on the stack. */ |
6898 |
|
common->ovector_start = CALL_LIMIT + sizeof(sljit_w); |
6899 |
|
|
6900 |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
6901 |
common->localsize = get_localspace(common, rootfallback.cc, ccend); |
localsize = get_localspace(common, rootfallback.cc, ccend); |
6902 |
if (common->localsize < 0) |
if (localsize < 0) |
6903 |
return; |
return; |
6904 |
common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
|
6905 |
if (common->localsize > SLJIT_MAX_LOCAL_SIZE) |
/* Checking flags and updating ovector_start. */ |
6906 |
|
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) |
6907 |
|
{ |
6908 |
|
common->req_char_ptr = common->ovector_start; |
6909 |
|
common->ovector_start += sizeof(sljit_w); |
6910 |
|
} |
6911 |
|
if (mode != JIT_COMPILE) |
6912 |
|
{ |
6913 |
|
common->start_used_ptr = common->ovector_start; |
6914 |
|
common->ovector_start += sizeof(sljit_w); |
6915 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
6916 |
|
{ |
6917 |
|
common->hit_start = common->ovector_start; |
6918 |
|
common->ovector_start += sizeof(sljit_w); |
6919 |
|
} |
6920 |
|
} |
6921 |
|
if ((re->options & PCRE_FIRSTLINE) != 0) |
6922 |
|
{ |
6923 |
|
common->first_line_end = common->ovector_start; |
6924 |
|
common->ovector_start += sizeof(sljit_w); |
6925 |
|
} |
6926 |
|
|
6927 |
|
/* Aligning ovector to even number of sljit words. */ |
6928 |
|
if ((common->ovector_start & sizeof(sljit_w)) != 0) |
6929 |
|
common->ovector_start += sizeof(sljit_w); |
6930 |
|
|
6931 |
|
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); |
6932 |
|
common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); |
6933 |
|
localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
6934 |
|
if (localsize > SLJIT_MAX_LOCAL_SIZE) |
6935 |
return; |
return; |
6936 |
common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int)); |
common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int)); |
6937 |
if (!common->localptrs) |
if (!common->localptrs) |
6938 |
return; |
return; |
6939 |
memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int)); |
memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int)); |
6948 |
common->compiler = compiler; |
common->compiler = compiler; |
6949 |
|
|
6950 |
/* Main pcre_jit_exec entry. */ |
/* Main pcre_jit_exec entry. */ |
6951 |
sljit_emit_enter(compiler, 1, 5, 5, common->localsize); |
sljit_emit_enter(compiler, 1, 5, 5, localsize); |
6952 |
|
|
6953 |
/* Register init. */ |
/* Register init. */ |
6954 |
reset_ovector(common, (re->top_bracket + 1) * 2); |
reset_ovector(common, (re->top_bracket + 1) * 2); |
6955 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if (common->req_char_ptr != 0) |
6956 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0); |
6957 |
|
|
6958 |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0); |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); |
6959 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); |
6960 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
6961 |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); |
6962 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
6965 |
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); |
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); |
6966 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
6967 |
|
|
6968 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
6969 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); |
6970 |
|
|
6971 |
/* Main part of the matching */ |
/* Main part of the matching */ |
6972 |
if ((re->options & PCRE_ANCHORED) == 0) |
if ((re->options & PCRE_ANCHORED) == 0) |
6973 |
{ |
{ |
6974 |
mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
6975 |
/* Forward search if possible. */ |
/* Forward search if possible. */ |
6976 |
if ((re->flags & PCRE_FIRSTSET) != 0) |
if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) |
6977 |
fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
{ |
6978 |
else if ((re->flags & PCRE_STARTLINE) != 0) |
if ((re->flags & PCRE_FIRSTSET) != 0) |
6979 |
fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); |
fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
6980 |
else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) |
else if ((re->flags & PCRE_STARTLINE) != 0) |
6981 |
fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); |
fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); |
6982 |
|
else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) |
6983 |
|
fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); |
6984 |
|
} |
6985 |
} |
} |
6986 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if (common->req_char_ptr != 0) |
6987 |
reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); |
reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); |
6988 |
|
|
6989 |
/* Store the current STR_PTR in OVECTOR(0). */ |
/* Store the current STR_PTR in OVECTOR(0). */ |
6990 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); |
6991 |
/* Copy the limit of allowed recursions. */ |
/* Copy the limit of allowed recursions. */ |
6992 |
OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); |
OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); |
6993 |
|
if (common->mark_ptr != 0) |
6994 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); |
6995 |
|
/* Copy the beginning of the string. */ |
6996 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
6997 |
|
{ |
6998 |
|
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); |
6999 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
7000 |
|
JUMPHERE(jump); |
7001 |
|
} |
7002 |
|
else if (mode == JIT_PARTIAL_HARD_COMPILE) |
7003 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
7004 |
|
|
7005 |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
7006 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
7019 |
|
|
7020 |
/* This means we have a match. Update the ovector. */ |
/* This means we have a match. Update the ovector. */ |
7021 |
copy_ovector(common, re->top_bracket + 1); |
copy_ovector(common, re->top_bracket + 1); |
7022 |
leave = LABEL(); |
common->leavelabel = LABEL(); |
7023 |
|
if (common->leave != NULL) |
7024 |
|
set_jumps(common->leave, common->leavelabel); |
7025 |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
7026 |
|
|
7027 |
|
if (mode != JIT_COMPILE) |
7028 |
|
{ |
7029 |
|
common->partialmatchlabel = LABEL(); |
7030 |
|
set_jumps(common->partialmatch, common->partialmatchlabel); |
7031 |
|
return_with_partial_match(common, common->leavelabel); |
7032 |
|
} |
7033 |
|
|
7034 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
7035 |
compile_fallbackpath(common, rootfallback.top); |
compile_fallbackpath(common, rootfallback.top); |
7036 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
7042 |
|
|
7043 |
SLJIT_ASSERT(rootfallback.prev == NULL); |
SLJIT_ASSERT(rootfallback.prev == NULL); |
7044 |
|
|
7045 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
7046 |
|
{ |
7047 |
|
/* Update hit_start only in the first time. */ |
7048 |
|
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
7049 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr); |
7050 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); |
7051 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0); |
7052 |
|
JUMPHERE(jump); |
7053 |
|
} |
7054 |
|
|
7055 |
/* Check we have remaining characters. */ |
/* Check we have remaining characters. */ |
7056 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
7057 |
|
|
7059 |
{ |
{ |
7060 |
if ((re->options & PCRE_FIRSTLINE) == 0) |
if ((re->options & PCRE_FIRSTLINE) == 0) |
7061 |
{ |
{ |
7062 |
if (study != NULL && study->minlength > 1) |
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) |
7063 |
{ |
{ |
7064 |
OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength)); |
OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); |
7065 |
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); |
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); |
7066 |
} |
} |
7067 |
else |
else |
7069 |
} |
} |
7070 |
else |
else |
7071 |
{ |
{ |
7072 |
if (study != NULL && study->minlength > 1) |
SLJIT_ASSERT(common->first_line_end != 0); |
7073 |
|
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) |
7074 |
{ |
{ |
7075 |
OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength)); |
OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); |
7076 |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); |
7077 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); |
7078 |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END); |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); |
7079 |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); |
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); |
7080 |
JUMPTO(SLJIT_C_ZERO, mainloop); |
JUMPTO(SLJIT_C_ZERO, mainloop); |
7081 |
} |
} |
7082 |
else |
else |
7083 |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop); |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop); |
7084 |
} |
} |
7085 |
} |
} |
7086 |
|
|
7087 |
|
/* No more remaining characters. */ |
7088 |
if (reqbyte_notfound != NULL) |
if (reqbyte_notfound != NULL) |
7089 |
JUMPHERE(reqbyte_notfound); |
JUMPHERE(reqbyte_notfound); |
7090 |
/* Copy OVECTOR(1) to OVECTOR(0) */ |
|
7091 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
7092 |
|
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); |
7093 |
|
|
7094 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
7095 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
7096 |
|
|
7097 |
flush_stubs(common); |
flush_stubs(common); |
7098 |
|
|
7125 |
/* This is a (really) rare case. */ |
/* This is a (really) rare case. */ |
7126 |
set_jumps(common->stackalloc, LABEL()); |
set_jumps(common->stackalloc, LABEL()); |
7127 |
/* RETURN_ADDR is not a saved register. */ |
/* RETURN_ADDR is not a saved register. */ |
7128 |
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize); |
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
7129 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); |
7130 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
7131 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
7133 |
OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); |
OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); |
7134 |
|
|
7135 |
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); |
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); |
7136 |
alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); |
7137 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
7138 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
7139 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); |
7142 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
7143 |
|
|
7144 |
/* Allocation failed. */ |
/* Allocation failed. */ |
7145 |
JUMPHERE(alloc_error); |
JUMPHERE(jump); |
7146 |
/* We break the return address cache here, but this is a really rare case. */ |
/* We break the return address cache here, but this is a really rare case. */ |
7147 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); |
7148 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
7149 |
|
|
7150 |
/* Call limit reached. */ |
/* Call limit reached. */ |
7151 |
set_jumps(common->calllimit, LABEL()); |
set_jumps(common->calllimit, LABEL()); |
7152 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
7153 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
7154 |
|
|
7155 |
if (common->revertframes != NULL) |
if (common->revertframes != NULL) |
7156 |
{ |
{ |
7216 |
if (executable_func == NULL) |
if (executable_func == NULL) |
7217 |
return; |
return; |
7218 |
|
|
7219 |
function = SLJIT_MALLOC(sizeof(executable_function)); |
/* Reuse the function descriptor if possible. */ |
7220 |
if (function == NULL) |
if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) |
7221 |
|
functions = (executable_functions *)extra->executable_jit; |
7222 |
|
else |
7223 |
{ |
{ |
7224 |
/* This case is highly unlikely since we just recently |
functions = SLJIT_MALLOC(sizeof(executable_functions)); |
7225 |
freed a lot of memory. Although not impossible. */ |
if (functions == NULL) |
7226 |
sljit_free_code(executable_func); |
{ |
7227 |
return; |
/* This case is highly unlikely since we just recently |
7228 |
|
freed a lot of memory. Although not impossible. */ |
7229 |
|
sljit_free_code(executable_func); |
7230 |
|
return; |
7231 |
|
} |
7232 |
|
memset(functions, 0, sizeof(executable_functions)); |
7233 |
|
extra->executable_jit = functions; |
7234 |
|
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; |
7235 |
} |
} |
7236 |
|
|
7237 |
function->executable_func = executable_func; |
functions->executable_funcs[mode] = executable_func; |
7238 |
function->executable_size = executable_size; |
functions->executable_sizes[mode] = executable_size; |
|
function->callback = NULL; |
|
|
function->userdata = NULL; |
|
|
extra->executable_jit = function; |
|
|
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; |
|
7239 |
} |
} |
7240 |
|
|
7241 |
static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function) |
static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func) |
7242 |
{ |
{ |
7243 |
union { |
union { |
7244 |
void* executable_func; |
void* executable_func; |
7252 |
local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; |
local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; |
7253 |
local_stack.max_limit = local_stack.limit; |
local_stack.max_limit = local_stack.limit; |
7254 |
arguments->stack = &local_stack; |
arguments->stack = &local_stack; |
7255 |
convert_executable_func.executable_func = function->executable_func; |
convert_executable_func.executable_func = executable_func; |
7256 |
return convert_executable_func.call_executable_func(arguments); |
return convert_executable_func.call_executable_func(arguments); |
7257 |
} |
} |
7258 |
|
|
7259 |
int |
int |
7260 |
PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func, |
PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, |
7261 |
const pcre_uchar *subject, int length, int start_offset, int options, |
int length, int start_offset, int options, int *offsets, int offsetcount) |
|
int match_limit, int *offsets, int offsetcount) |
|
7262 |
{ |
{ |
7263 |
executable_function *function = (executable_function*)executable_func; |
executable_functions *functions = (executable_functions *)extra_data->executable_jit; |
7264 |
union { |
union { |
7265 |
void* executable_func; |
void* executable_func; |
7266 |
jit_function call_executable_func; |
jit_function call_executable_func; |
7268 |
jit_arguments arguments; |
jit_arguments arguments; |
7269 |
int maxoffsetcount; |
int maxoffsetcount; |
7270 |
int retval; |
int retval; |
7271 |
|
int mode = JIT_COMPILE; |
7272 |
|
|
7273 |
|
if ((options & PCRE_PARTIAL_HARD) != 0) |
7274 |
|
mode = JIT_PARTIAL_HARD_COMPILE; |
7275 |
|
else if ((options & PCRE_PARTIAL_SOFT) != 0) |
7276 |
|
mode = JIT_PARTIAL_SOFT_COMPILE; |
7277 |
|
|
7278 |
|
if (functions->executable_funcs[mode] == NULL) |
7279 |
|
return PCRE_ERROR_NULL; |
7280 |
|
|
7281 |
/* Sanity checks should be handled by pcre_exec. */ |
/* Sanity checks should be handled by pcre_exec. */ |
7282 |
arguments.stack = NULL; |
arguments.stack = NULL; |
7283 |
arguments.str = subject + start_offset; |
arguments.str = subject + start_offset; |
7284 |
arguments.begin = subject; |
arguments.begin = subject; |
7285 |
arguments.end = subject + length; |
arguments.end = subject + length; |
7286 |
arguments.calllimit = match_limit; /* JIT decreases this value less times. */ |
arguments.mark_ptr = NULL; |
7287 |
|
/* JIT decreases this value less frequently than the interpreter. */ |
7288 |
|
arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; |
7289 |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
7290 |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
7291 |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
7305 |
offsetcount = maxoffsetcount; |
offsetcount = maxoffsetcount; |
7306 |
arguments.offsetcount = offsetcount; |
arguments.offsetcount = offsetcount; |
7307 |
|
|
7308 |
if (function->callback) |
if (functions->callback) |
7309 |
arguments.stack = (struct sljit_stack*)function->callback(function->userdata); |
arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); |
7310 |
else |
else |
7311 |
arguments.stack = (struct sljit_stack*)function->userdata; |
arguments.stack = (struct sljit_stack *)functions->userdata; |
7312 |
|
|
7313 |
if (arguments.stack == NULL) |
if (arguments.stack == NULL) |
7314 |
retval = jit_machine_stack_exec(&arguments, function); |
retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]); |
7315 |
else |
else |
7316 |
{ |
{ |
7317 |
convert_executable_func.executable_func = function->executable_func; |
convert_executable_func.executable_func = functions->executable_funcs[mode]; |
7318 |
retval = convert_executable_func.call_executable_func(&arguments); |
retval = convert_executable_func.call_executable_func(&arguments); |
7319 |
} |
} |
7320 |
|
|
7321 |
if (retval * 2 > offsetcount) |
if (retval * 2 > offsetcount) |
7322 |
retval = 0; |
retval = 0; |
7323 |
|
if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) |
7324 |
|
*(extra_data->mark) = arguments.mark_ptr; |
7325 |
|
|
7326 |
return retval; |
return retval; |
7327 |
} |
} |
7328 |
|
|
7329 |
void |
void |
7330 |
PRIV(jit_free)(void *executable_func) |
PRIV(jit_free)(void *executable_funcs) |
7331 |
{ |
{ |
7332 |
executable_function *function = (executable_function*)executable_func; |
int i; |
7333 |
sljit_free_code(function->executable_func); |
executable_functions *functions = (executable_functions *)executable_funcs; |
7334 |
SLJIT_FREE(function); |
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) |
7335 |
|
{ |
7336 |
|
if (functions->executable_funcs[i] != NULL) |
7337 |
|
sljit_free_code(functions->executable_funcs[i]); |
7338 |
|
} |
7339 |
|
SLJIT_FREE(functions); |
7340 |
} |
} |
7341 |
|
|
7342 |
int |
int |
7343 |
PRIV(jit_get_size)(void *executable_func) |
PRIV(jit_get_size)(void *executable_funcs) |
7344 |
|
{ |
7345 |
|
int i; |
7346 |
|
sljit_uw size = 0; |
7347 |
|
sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes; |
7348 |
|
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) |
7349 |
|
size += executable_sizes[i]; |
7350 |
|
return (int)size; |
7351 |
|
} |
7352 |
|
|
7353 |
|
const char* |
7354 |
|
PRIV(jit_get_target)(void) |
7355 |
{ |
{ |
7356 |
return ((executable_function*)executable_func)->executable_size; |
return sljit_get_platform_name(); |
7357 |
} |
} |
7358 |
|
|
7359 |
#ifdef COMPILE_PCRE8 |
#ifdef COMPILE_PCRE8 |
7381 |
pcre16_jit_stack_free(pcre16_jit_stack *stack) |
pcre16_jit_stack_free(pcre16_jit_stack *stack) |
7382 |
#endif |
#endif |
7383 |
{ |
{ |
7384 |
sljit_free_stack((struct sljit_stack*)stack); |
sljit_free_stack((struct sljit_stack *)stack); |
7385 |
} |
} |
7386 |
|
|
7387 |
#ifdef COMPILE_PCRE8 |
#ifdef COMPILE_PCRE8 |
7392 |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) |
7393 |
#endif |
#endif |
7394 |
{ |
{ |
7395 |
executable_function *function; |
executable_functions *functions; |
7396 |
if (extra != NULL && |
if (extra != NULL && |
7397 |
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
7398 |
extra->executable_jit != NULL) |
extra->executable_jit != NULL) |
7399 |
{ |
{ |
7400 |
function = (executable_function*)extra->executable_jit; |
functions = (executable_functions *)extra->executable_jit; |
7401 |
function->callback = callback; |
functions->callback = callback; |
7402 |
function->userdata = userdata; |
functions->userdata = userdata; |
7403 |
} |
} |
7404 |
} |
} |
7405 |
|
|