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; |
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 |
|
|
275 |
|
/* Local stack area size and variable pointers. */ |
276 |
int localsize; |
int localsize; |
277 |
int *localptrs; |
int *localptrs; |
278 |
|
int cbraptr; |
279 |
|
/* OVector starting point. Must be divisible by 2. */ |
280 |
|
int ovector_start; |
281 |
|
/* Last known position of the requested byte. */ |
282 |
|
int req_char_ptr; |
283 |
|
/* Head of the last recursion. */ |
284 |
|
int recursive_head; |
285 |
|
/* First inspected character for partial matching. */ |
286 |
|
int start_used_ptr; |
287 |
|
/* Starting pointer for partial soft matches. */ |
288 |
|
int hit_start; |
289 |
|
/* End pointer of the first line. */ |
290 |
|
int first_line_end; |
291 |
|
/* Points to the marked string. */ |
292 |
|
int mark_ptr; |
293 |
|
|
294 |
|
/* Other */ |
295 |
const pcre_uint8 *fcc; |
const pcre_uint8 *fcc; |
296 |
sljit_w lcc; |
sljit_w lcc; |
|
int cbraptr; |
|
297 |
int mode; |
int mode; |
298 |
int nltype; |
int nltype; |
299 |
int newline; |
int newline; |
300 |
int bsr_nltype; |
int bsr_nltype; |
301 |
int endonly; |
int endonly; |
302 |
|
BOOL has_set_som; |
303 |
sljit_w ctypes; |
sljit_w ctypes; |
304 |
sljit_uw name_table; |
sljit_uw name_table; |
305 |
sljit_w name_count; |
sljit_w name_count; |
306 |
sljit_w name_entry_size; |
sljit_w name_entry_size; |
307 |
|
|
308 |
|
/* Labels and jump lists. */ |
309 |
struct sljit_label *partialmatchlabel; |
struct sljit_label *partialmatchlabel; |
310 |
|
struct sljit_label *leavelabel; |
311 |
struct sljit_label *acceptlabel; |
struct sljit_label *acceptlabel; |
312 |
stub_list *stubs; |
stub_list *stubs; |
313 |
recurse_entry *entries; |
recurse_entry *entries; |
314 |
recurse_entry *currententry; |
recurse_entry *currententry; |
315 |
jump_list *partialmatch; |
jump_list *partialmatch; |
316 |
|
jump_list *leave; |
317 |
jump_list *accept; |
jump_list *accept; |
318 |
jump_list *calllimit; |
jump_list *calllimit; |
319 |
jump_list *stackalloc; |
jump_list *stackalloc; |
376 |
|
|
377 |
enum { |
enum { |
378 |
frame_end = 0, |
frame_end = 0, |
379 |
frame_setstrbegin = -1 |
frame_setstrbegin = -1, |
380 |
|
frame_setmark = -2 |
381 |
}; |
}; |
382 |
|
|
383 |
/* Undefine sljit macros. */ |
/* Undefine sljit macros. */ |
404 |
/* Two local variables for possessive quantifiers (char1 cannot use them). */ |
/* Two local variables for possessive quantifiers (char1 cannot use them). */ |
405 |
#define POSSESSIVE0 (2 * sizeof(sljit_w)) |
#define POSSESSIVE0 (2 * sizeof(sljit_w)) |
406 |
#define POSSESSIVE1 (3 * sizeof(sljit_w)) |
#define POSSESSIVE1 (3 * sizeof(sljit_w)) |
|
/* Head of the last recursion. */ |
|
|
#define RECURSIVE_HEAD (4 * sizeof(sljit_w)) |
|
407 |
/* Max limit of recursions. */ |
/* Max limit of recursions. */ |
408 |
#define CALL_LIMIT (5 * sizeof(sljit_w)) |
#define CALL_LIMIT (4 * sizeof(sljit_w)) |
|
/* Last known position of the requested byte. |
|
|
Same as START_USED_PTR. (Partial matching and req_char are exclusive) */ |
|
|
#define REQ_CHAR_PTR (6 * sizeof(sljit_w)) |
|
|
/* First inspected character for partial matching. |
|
|
Same as REQ_CHAR_PTR. (Partial matching and req_char are exclusive) */ |
|
|
#define START_USED_PTR (6 * sizeof(sljit_w)) |
|
|
/* Starting pointer for partial soft matches. */ |
|
|
#define HIT_START (8 * sizeof(sljit_w)) |
|
|
/* End pointer of the first line. */ |
|
|
#define FIRSTLINE_END (9 * sizeof(sljit_w)) |
|
409 |
/* The output vector is stored on the stack, and contains pointers |
/* The output vector is stored on the stack, and contains pointers |
410 |
to characters. The vector data is divided into two groups: the first |
to characters. The vector data is divided into two groups: the first |
411 |
group contains the start / end character pointers, and the second is |
group contains the start / end character pointers, and the second is |
412 |
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. */ |
413 |
#define OVECTOR_START (10 * sizeof(sljit_w)) |
#define OVECTOR_START (common->ovector_start) |
414 |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
415 |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
416 |
#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) |
#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) |
519 |
case OP_BRAZERO: |
case OP_BRAZERO: |
520 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
521 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
522 |
|
case OP_COMMIT: |
523 |
case OP_FAIL: |
case OP_FAIL: |
524 |
case OP_ACCEPT: |
case OP_ACCEPT: |
525 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
658 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
659 |
return cc + 1 + LINK_SIZE + IMM2_SIZE; |
return cc + 1 + LINK_SIZE + IMM2_SIZE; |
660 |
|
|
661 |
|
case OP_MARK: |
662 |
|
return cc + 1 + 2 + cc[1]; |
663 |
|
|
664 |
default: |
default: |
665 |
return NULL; |
return NULL; |
666 |
} |
} |
675 |
{ |
{ |
676 |
switch(*cc) |
switch(*cc) |
677 |
{ |
{ |
678 |
|
case OP_SET_SOM: |
679 |
|
common->has_set_som = TRUE; |
680 |
|
cc += 1; |
681 |
|
break; |
682 |
|
|
683 |
case OP_ASSERT: |
case OP_ASSERT: |
684 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
685 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
708 |
cc += 1 + LINK_SIZE; |
cc += 1 + LINK_SIZE; |
709 |
break; |
break; |
710 |
|
|
711 |
|
case OP_RECURSE: |
712 |
|
/* Set its value only once. */ |
713 |
|
if (common->recursive_head == 0) |
714 |
|
{ |
715 |
|
common->recursive_head = common->ovector_start; |
716 |
|
common->ovector_start += sizeof(sljit_w); |
717 |
|
} |
718 |
|
cc += 1 + LINK_SIZE; |
719 |
|
break; |
720 |
|
|
721 |
|
case OP_MARK: |
722 |
|
if (common->mark_ptr == 0) |
723 |
|
{ |
724 |
|
common->mark_ptr = common->ovector_start; |
725 |
|
common->ovector_start += sizeof(sljit_w); |
726 |
|
} |
727 |
|
cc += 1 + 2 + cc[1]; |
728 |
|
break; |
729 |
|
|
730 |
default: |
default: |
731 |
cc = next_opcode(common, cc); |
cc = next_opcode(common, cc); |
732 |
if (cc == NULL) |
if (cc == NULL) |
792 |
pcre_uchar *ccend = bracketend(cc); |
pcre_uchar *ccend = bracketend(cc); |
793 |
int length = 0; |
int length = 0; |
794 |
BOOL possessive = FALSE; |
BOOL possessive = FALSE; |
795 |
BOOL setsom_found = FALSE; |
BOOL setsom_found = recursive; |
796 |
|
BOOL setmark_found = recursive; |
797 |
|
|
798 |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
799 |
{ |
{ |
807 |
switch(*cc) |
switch(*cc) |
808 |
{ |
{ |
809 |
case OP_SET_SOM: |
case OP_SET_SOM: |
810 |
case OP_RECURSE: |
SLJIT_ASSERT(common->has_set_som); |
811 |
if (!setsom_found) |
if (!setsom_found) |
812 |
{ |
{ |
813 |
length += 2; |
length += 2; |
814 |
setsom_found = TRUE; |
setsom_found = TRUE; |
815 |
} |
} |
816 |
cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE; |
cc += 1; |
817 |
|
break; |
818 |
|
|
819 |
|
case OP_MARK: |
820 |
|
SLJIT_ASSERT(common->mark_ptr != 0); |
821 |
|
if (!setmark_found) |
822 |
|
{ |
823 |
|
length += 2; |
824 |
|
setmark_found = TRUE; |
825 |
|
} |
826 |
|
cc += 1 + 2 + cc[1]; |
827 |
|
break; |
828 |
|
|
829 |
|
case OP_RECURSE: |
830 |
|
if (common->has_set_som && !setsom_found) |
831 |
|
{ |
832 |
|
length += 2; |
833 |
|
setsom_found = TRUE; |
834 |
|
} |
835 |
|
if (common->mark_ptr != 0 && !setmark_found) |
836 |
|
{ |
837 |
|
length += 2; |
838 |
|
setmark_found = TRUE; |
839 |
|
} |
840 |
|
cc += 1 + LINK_SIZE; |
841 |
break; |
break; |
842 |
|
|
843 |
case OP_CBRA: |
case OP_CBRA: |
867 |
{ |
{ |
868 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
869 |
pcre_uchar *ccend = bracketend(cc); |
pcre_uchar *ccend = bracketend(cc); |
870 |
BOOL setsom_found = FALSE; |
BOOL setsom_found = recursive; |
871 |
|
BOOL setmark_found = recursive; |
872 |
int offset; |
int offset; |
873 |
|
|
874 |
/* >= 1 + shortest item size (2) */ |
/* >= 1 + shortest item size (2) */ |
883 |
switch(*cc) |
switch(*cc) |
884 |
{ |
{ |
885 |
case OP_SET_SOM: |
case OP_SET_SOM: |
886 |
case OP_RECURSE: |
SLJIT_ASSERT(common->has_set_som); |
887 |
if (!setsom_found) |
if (!setsom_found) |
888 |
{ |
{ |
889 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
893 |
stackpos += (int)sizeof(sljit_w); |
stackpos += (int)sizeof(sljit_w); |
894 |
setsom_found = TRUE; |
setsom_found = TRUE; |
895 |
} |
} |
896 |
cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE; |
cc += 1; |
897 |
|
break; |
898 |
|
|
899 |
|
case OP_MARK: |
900 |
|
SLJIT_ASSERT(common->mark_ptr != 0); |
901 |
|
if (!setmark_found) |
902 |
|
{ |
903 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
904 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); |
905 |
|
stackpos += (int)sizeof(sljit_w); |
906 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
907 |
|
stackpos += (int)sizeof(sljit_w); |
908 |
|
setmark_found = TRUE; |
909 |
|
} |
910 |
|
cc += 1 + 2 + cc[1]; |
911 |
|
break; |
912 |
|
|
913 |
|
case OP_RECURSE: |
914 |
|
if (common->has_set_som && !setsom_found) |
915 |
|
{ |
916 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
917 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); |
918 |
|
stackpos += (int)sizeof(sljit_w); |
919 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
920 |
|
stackpos += (int)sizeof(sljit_w); |
921 |
|
setsom_found = TRUE; |
922 |
|
} |
923 |
|
if (common->mark_ptr != 0 && !setmark_found) |
924 |
|
{ |
925 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
926 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); |
927 |
|
stackpos += (int)sizeof(sljit_w); |
928 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
929 |
|
stackpos += (int)sizeof(sljit_w); |
930 |
|
setmark_found = TRUE; |
931 |
|
} |
932 |
|
cc += 1 + LINK_SIZE; |
933 |
break; |
break; |
934 |
|
|
935 |
case OP_CBRA: |
case OP_CBRA: |
1056 |
switch(status) |
switch(status) |
1057 |
{ |
{ |
1058 |
case start: |
case start: |
1059 |
SLJIT_ASSERT(save); |
SLJIT_ASSERT(save && common->recursive_head != 0); |
1060 |
count = 1; |
count = 1; |
1061 |
srcw[0] = RECURSIVE_HEAD; |
srcw[0] = common->recursive_head; |
1062 |
status = loop; |
status = loop; |
1063 |
break; |
break; |
1064 |
|
|
1345 |
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); |
1346 |
|
|
1347 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
1348 |
|
if (common->mark_ptr != 0) |
1349 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
1350 |
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)); |
1351 |
|
if (common->mark_ptr != 0) |
1352 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); |
1353 |
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)); |
1354 |
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)); |
1355 |
OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START); |
OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START); |
1389 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
1390 |
|
|
1391 |
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); |
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); |
1392 |
|
SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); |
1393 |
|
|
1394 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
1395 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); |
1399 |
/* Store match begin and end. */ |
/* Store match begin and end. */ |
1400 |
OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); |
1401 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); |
1402 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? START_USED_PTR : HIT_START); |
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); |
1403 |
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); |
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); |
1404 |
#ifdef COMPILE_PCRE16 |
#ifdef COMPILE_PCRE16 |
1405 |
OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); |
1423 |
|
|
1424 |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1425 |
{ |
{ |
1426 |
/* The value of -1 must be kept for START_USED_PTR! */ |
/* The value of -1 must be kept for start_used_ptr! */ |
1427 |
OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, 1); |
OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1); |
1428 |
/* Jumps if START_USED_PTR < STR_PTR, or START_USED_PTR == -1. Although overwriting |
/* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting |
1429 |
is not necessary if START_USED_PTR == STR_PTR, it does not hurt as well. */ |
is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ |
1430 |
jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); |
jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); |
1431 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1432 |
JUMPHERE(jump); |
JUMPHERE(jump); |
1433 |
} |
} |
1434 |
else if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
else if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
1435 |
{ |
{ |
1436 |
jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1437 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1438 |
JUMPHERE(jump); |
JUMPHERE(jump); |
1439 |
} |
} |
1440 |
} |
} |
1560 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
1561 |
} |
} |
1562 |
|
|
1563 |
static void check_partial(compiler_common *common) |
static void check_partial(compiler_common *common, BOOL force) |
1564 |
{ |
{ |
1565 |
|
/* Checks whether a partial matching is occured. Does not modify registers. */ |
1566 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
1567 |
struct sljit_jump *jump; |
struct sljit_jump *jump = NULL; |
1568 |
|
|
1569 |
|
SLJIT_ASSERT(!force || common->mode != JIT_COMPILE); |
1570 |
|
|
1571 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
1572 |
return; |
return; |
1573 |
|
|
1574 |
jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
if (!force) |
1575 |
|
jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1576 |
|
else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1577 |
|
jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); |
1578 |
|
|
1579 |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1580 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
1581 |
else |
else |
1582 |
{ |
{ |
1583 |
if (common->partialmatchlabel != NULL) |
if (common->partialmatchlabel != NULL) |
1585 |
else |
else |
1586 |
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
1587 |
} |
} |
1588 |
JUMPHERE(jump); |
|
1589 |
|
if (jump != NULL) |
1590 |
|
JUMPHERE(jump); |
1591 |
} |
} |
1592 |
|
|
1593 |
static struct sljit_jump *check_str_end(compiler_common *common) |
static struct sljit_jump *check_str_end(compiler_common *common) |
1604 |
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
1605 |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1606 |
{ |
{ |
1607 |
nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1608 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
1609 |
JUMPHERE(nohit); |
JUMPHERE(nohit); |
1610 |
return_value = JUMP(SLJIT_JUMP); |
return_value = JUMP(SLJIT_JUMP); |
1611 |
} |
} |
1612 |
else |
else |
1613 |
{ |
{ |
1614 |
return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
1615 |
if (common->partialmatchlabel != NULL) |
if (common->partialmatchlabel != NULL) |
1616 |
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
1617 |
else |
else |
1634 |
|
|
1635 |
/* Partial matching mode. */ |
/* Partial matching mode. */ |
1636 |
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
1637 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); |
1638 |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
1639 |
{ |
{ |
1640 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
1641 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
1642 |
} |
} |
1643 |
else |
else |
1992 |
if (firstline) |
if (firstline) |
1993 |
{ |
{ |
1994 |
/* Search for the end of the first line. */ |
/* Search for the end of the first line. */ |
1995 |
|
SLJIT_ASSERT(common->first_line_end != 0); |
1996 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); |
1997 |
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); |
1998 |
|
|
1999 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
2000 |
{ |
{ |
2005 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
2006 |
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); |
2007 |
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); |
2008 |
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)); |
2009 |
} |
} |
2010 |
else |
else |
2011 |
{ |
{ |
2012 |
end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
2013 |
mainloop = LABEL(); |
mainloop = LABEL(); |
2014 |
/* Continual stores does not cause data dependency. */ |
/* Continual stores does not cause data dependency. */ |
2015 |
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); |
2016 |
read_char(common); |
read_char(common); |
2017 |
check_newlinechar(common, common->nltype, &newline, TRUE); |
check_newlinechar(common, common->nltype, &newline, TRUE); |
2018 |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
2019 |
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); |
2020 |
set_jumps(newline, LABEL()); |
set_jumps(newline, LABEL()); |
2021 |
} |
} |
2022 |
|
|
2099 |
if (firstline) |
if (firstline) |
2100 |
{ |
{ |
2101 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
2102 |
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); |
2103 |
} |
} |
2104 |
|
|
2105 |
start = LABEL(); |
start = LABEL(); |
2177 |
if (firstline) |
if (firstline) |
2178 |
{ |
{ |
2179 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
2180 |
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); |
2181 |
} |
} |
2182 |
|
|
2183 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
2261 |
if (firstline) |
if (firstline) |
2262 |
{ |
{ |
2263 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
2264 |
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); |
2265 |
} |
} |
2266 |
|
|
2267 |
start = LABEL(); |
start = LABEL(); |
2326 |
struct sljit_jump *notfound; |
struct sljit_jump *notfound; |
2327 |
pcre_uchar oc, bit; |
pcre_uchar oc, bit; |
2328 |
|
|
2329 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR); |
SLJIT_ASSERT(common->req_char_ptr != 0); |
2330 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); |
2331 |
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); |
2332 |
toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); |
toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); |
2333 |
alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); |
alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); |
2372 |
JUMPHERE(found); |
JUMPHERE(found); |
2373 |
if (foundoc) |
if (foundoc) |
2374 |
JUMPHERE(foundoc); |
JUMPHERE(foundoc); |
2375 |
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); |
2376 |
JUMPHERE(alreadyfound); |
JUMPHERE(alreadyfound); |
2377 |
JUMPHERE(toolong); |
JUMPHERE(toolong); |
2378 |
return notfound; |
return notfound; |
2411 |
JUMPTO(SLJIT_JUMP, mainloop); |
JUMPTO(SLJIT_JUMP, mainloop); |
2412 |
|
|
2413 |
JUMPHERE(jump); |
JUMPHERE(jump); |
2414 |
|
if (common->mark_ptr != 0) |
2415 |
|
{ |
2416 |
|
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark); |
2417 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
2418 |
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); |
2419 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
2420 |
|
JUMPTO(SLJIT_JUMP, mainloop); |
2421 |
|
|
2422 |
|
JUMPHERE(jump); |
2423 |
|
} |
2424 |
|
|
2425 |
/* Unknown command. */ |
/* Unknown command. */ |
2426 |
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)); |
2427 |
JUMPTO(SLJIT_JUMP, mainloop); |
JUMPTO(SLJIT_JUMP, mainloop); |
2714 |
{ |
{ |
2715 |
/* This function would be ineffective to do in JIT level. */ |
/* This function would be ineffective to do in JIT level. */ |
2716 |
int c1, c2; |
int c1, c2; |
2717 |
const pcre_uchar *src2 = args->ptr; |
const pcre_uchar *src2 = args->uchar_ptr; |
2718 |
const pcre_uchar *end2 = args->end; |
const pcre_uchar *end2 = args->end; |
2719 |
|
|
2720 |
while (src1 < end1) |
while (src1 < end1) |
3311 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3312 |
{ |
{ |
3313 |
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); |
3314 |
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
3315 |
|
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3316 |
|
else |
3317 |
|
jump[1] = check_str_end(common); |
3318 |
|
|
3319 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3320 |
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)); |
3321 |
JUMPHERE(jump[1]); |
if (jump[1] != NULL) |
3322 |
|
JUMPHERE(jump[1]); |
3323 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
3324 |
} |
} |
3325 |
else |
else |
3377 |
fallback_at_str_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
3378 |
read_char(common); |
read_char(common); |
3379 |
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); |
3380 |
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
/* We don't need to handle soft partial matching case. */ |
3381 |
|
if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
3382 |
|
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
3383 |
|
else |
3384 |
|
jump[1] = check_str_end(common); |
3385 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
3386 |
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); |
3387 |
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)); |
3430 |
if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
3431 |
{ |
{ |
3432 |
jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
3433 |
check_partial(common); |
/* Since we successfully read a char above, partial matching must occure. */ |
3434 |
|
check_partial(common, TRUE); |
3435 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
3436 |
} |
} |
3437 |
return cc; |
return cc; |
3438 |
#endif |
#endif |
3439 |
|
|
3440 |
case OP_EODN: |
case OP_EODN: |
3441 |
|
/* Requires rather complex checks. */ |
3442 |
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); |
3443 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3444 |
{ |
{ |
3445 |
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)); |
3446 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
3447 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
if (common->mode == JIT_COMPILE) |
3448 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
3449 |
|
else |
3450 |
|
{ |
3451 |
|
jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); |
3452 |
|
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); |
3453 |
|
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); |
3454 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
3455 |
|
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); |
3456 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL)); |
3457 |
|
check_partial(common, TRUE); |
3458 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3459 |
|
JUMPHERE(jump[1]); |
3460 |
|
} |
3461 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
3462 |
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)); |
3463 |
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)); |
3502 |
JUMPHERE(jump[3]); |
JUMPHERE(jump[3]); |
3503 |
} |
} |
3504 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
3505 |
check_partial(common); |
check_partial(common, FALSE); |
3506 |
return cc; |
return cc; |
3507 |
|
|
3508 |
case OP_EOD: |
case OP_EOD: |
3509 |
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)); |
3510 |
check_partial(common); |
check_partial(common, FALSE); |
3511 |
return cc; |
return cc; |
3512 |
|
|
3513 |
case OP_CIRC: |
case OP_CIRC: |
3556 |
else |
else |
3557 |
{ |
{ |
3558 |
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)); |
3559 |
check_partial(common); |
check_partial(common, FALSE); |
3560 |
} |
} |
3561 |
return cc; |
return cc; |
3562 |
|
|
3565 |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
3566 |
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)); |
3567 |
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)); |
3568 |
check_partial(common); |
check_partial(common, FALSE); |
3569 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
3570 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
3571 |
|
|
3572 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
3573 |
{ |
{ |
3574 |
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)); |
|
3575 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
3576 |
|
if (common->mode == JIT_COMPILE) |
3577 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); |
3578 |
|
else |
3579 |
|
{ |
3580 |
|
jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); |
3581 |
|
/* STR_PTR = STR_END - IN_UCHARS(1) */ |
3582 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
3583 |
|
check_partial(common, TRUE); |
3584 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3585 |
|
JUMPHERE(jump[1]); |
3586 |
|
} |
3587 |
|
|
3588 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
3589 |
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)); |
3590 |
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)); |
3704 |
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)); |
3705 |
} |
} |
3706 |
} |
} |
3707 |
return cc + 1; |
return cc + length; |
3708 |
|
|
3709 |
case OP_CLASS: |
case OP_CLASS: |
3710 |
case OP_NCLASS: |
case OP_NCLASS: |
3746 |
|
|
3747 |
case OP_REVERSE: |
case OP_REVERSE: |
3748 |
length = GET(cc, 0); |
length = GET(cc, 0); |
3749 |
SLJIT_ASSERT(length > 0); |
if (length == 0) |
3750 |
|
return cc + LINK_SIZE; |
3751 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
3752 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
3753 |
if (common->utf) |
if (common->utf) |
3918 |
/* Needed to save important temporary registers. */ |
/* Needed to save important temporary registers. */ |
3919 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
3920 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
3921 |
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); |
3922 |
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)); |
3923 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
3924 |
if (common->mode == JIT_COMPILE) |
if (common->mode == JIT_COMPILE) |
3927 |
{ |
{ |
3928 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
3929 |
nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
3930 |
check_partial(common); |
check_partial(common, FALSE); |
3931 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3932 |
JUMPHERE(nopartial); |
JUMPHERE(nopartial); |
3933 |
} |
} |
3960 |
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)); |
3961 |
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)); |
3962 |
JUMPHERE(partial); |
JUMPHERE(partial); |
3963 |
check_partial(common); |
check_partial(common, FALSE); |
3964 |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
3965 |
JUMPHERE(nopartial); |
JUMPHERE(nopartial); |
3966 |
} |
} |
4153 |
common->entries = entry; |
common->entries = entry; |
4154 |
} |
} |
4155 |
|
|
4156 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
if (common->has_set_som && common->mark_ptr != 0) |
4157 |
allocate_stack(common, 1); |
{ |
4158 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
4159 |
|
allocate_stack(common, 2); |
4160 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
4161 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
4162 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
4163 |
|
} |
4164 |
|
else if (common->has_set_som || common->mark_ptr != 0) |
4165 |
|
{ |
4166 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); |
4167 |
|
allocate_stack(common, 1); |
4168 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
4169 |
|
} |
4170 |
|
|
4171 |
if (entry->entry == NULL) |
if (entry->entry == NULL) |
4172 |
add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL)); |
4190 |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
4191 |
jump_list **found; |
jump_list **found; |
4192 |
/* Saving previous accept variables. */ |
/* Saving previous accept variables. */ |
4193 |
|
struct sljit_label *save_leavelabel = common->leavelabel; |
4194 |
struct sljit_label *save_acceptlabel = common->acceptlabel; |
struct sljit_label *save_acceptlabel = common->acceptlabel; |
4195 |
|
jump_list *save_leave = common->leave; |
4196 |
|
jump_list *save_accept = common->accept; |
4197 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
4198 |
struct sljit_jump *brajump = NULL; |
struct sljit_jump *brajump = NULL; |
|
jump_list *save_accept = common->accept; |
|
4199 |
|
|
4200 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
4201 |
{ |
{ |
4240 |
} |
} |
4241 |
|
|
4242 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altfallback, 0, sizeof(fallback_common)); |
4243 |
|
common->leavelabel = NULL; |
4244 |
|
common->leave = NULL; |
4245 |
while (1) |
while (1) |
4246 |
{ |
{ |
4247 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
4256 |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
4257 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
4258 |
{ |
{ |
4259 |
|
common->leavelabel = save_leavelabel; |
4260 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
4261 |
|
common->leave = save_leave; |
4262 |
common->accept = save_accept; |
common->accept = save_accept; |
4263 |
return NULL; |
return NULL; |
4264 |
} |
} |
4311 |
compile_fallbackpath(common, altfallback.top); |
compile_fallbackpath(common, altfallback.top); |
4312 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
4313 |
{ |
{ |
4314 |
|
common->leavelabel = save_leavelabel; |
4315 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
4316 |
|
common->leave = save_leave; |
4317 |
common->accept = save_accept; |
common->accept = save_accept; |
4318 |
return NULL; |
return NULL; |
4319 |
} |
} |
4326 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
4327 |
} |
} |
4328 |
/* None of them matched. */ |
/* None of them matched. */ |
4329 |
|
if (common->leave != NULL) |
4330 |
|
set_jumps(common->leave, LABEL()); |
4331 |
|
|
4332 |
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
4333 |
{ |
{ |
4452 |
} |
} |
4453 |
} |
} |
4454 |
|
|
4455 |
|
common->leavelabel = save_leavelabel; |
4456 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
4457 |
|
common->leave = save_leave; |
4458 |
common->accept = save_accept; |
common->accept = save_accept; |
4459 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
4460 |
} |
} |
4469 |
sljit_w no_capture; |
sljit_w no_capture; |
4470 |
int i; |
int i; |
4471 |
|
|
4472 |
locals += OVECTOR_START / sizeof(sljit_w); |
locals += refno & 0xff; |
4473 |
|
refno >>= 8; |
4474 |
no_capture = locals[1]; |
no_capture = locals[1]; |
4475 |
|
|
4476 |
for (i = 0; i < name_count; i++) |
for (i = 0; i < name_count; i++) |
4870 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
4871 |
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); |
4872 |
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); |
4873 |
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))); |
4874 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); |
4875 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
4876 |
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)); |
5645 |
|
|
5646 |
case OP_SET_SOM: |
case OP_SET_SOM: |
5647 |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
5648 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
5649 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
|
5650 |
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); |
5651 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
5652 |
cc++; |
cc++; |
5653 |
break; |
break; |
5654 |
|
|
5813 |
cc = compile_bracketpos_hotpath(common, cc, parent); |
cc = compile_bracketpos_hotpath(common, cc, parent); |
5814 |
break; |
break; |
5815 |
|
|
5816 |
|
case OP_MARK: |
5817 |
|
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
5818 |
|
SLJIT_ASSERT(common->mark_ptr != 0); |
5819 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
5820 |
|
allocate_stack(common, 1); |
5821 |
|
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
5822 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
5823 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2)); |
5824 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
5825 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
5826 |
|
cc += 1 + 2 + cc[1]; |
5827 |
|
break; |
5828 |
|
|
5829 |
|
case OP_COMMIT: |
5830 |
|
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
5831 |
|
cc += 1; |
5832 |
|
break; |
5833 |
|
|
5834 |
case OP_FAIL: |
case OP_FAIL: |
5835 |
case OP_ACCEPT: |
case OP_ACCEPT: |
5836 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
6024 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
6025 |
|
|
6026 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topfallbacks, LABEL()); |
6027 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
|
6028 |
free_stack(common, 1); |
if (common->has_set_som && common->mark_ptr != 0) |
6029 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); |
{ |
6030 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6031 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
6032 |
|
free_stack(common, 2); |
6033 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); |
6034 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); |
6035 |
|
} |
6036 |
|
else if (common->has_set_som || common->mark_ptr != 0) |
6037 |
|
{ |
6038 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6039 |
|
free_stack(common, 1); |
6040 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); |
6041 |
|
} |
6042 |
} |
} |
6043 |
|
|
6044 |
static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current) |
6674 |
compile_braminzero_fallbackpath(common, current); |
compile_braminzero_fallbackpath(common, current); |
6675 |
break; |
break; |
6676 |
|
|
6677 |
|
case OP_MARK: |
6678 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
6679 |
|
free_stack(common, 1); |
6680 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); |
6681 |
|
break; |
6682 |
|
|
6683 |
|
case OP_COMMIT: |
6684 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
6685 |
|
if (common->leavelabel == NULL) |
6686 |
|
add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); |
6687 |
|
else |
6688 |
|
JUMPTO(SLJIT_JUMP, common->leavelabel); |
6689 |
|
break; |
6690 |
|
|
6691 |
case OP_FAIL: |
case OP_FAIL: |
6692 |
case OP_ACCEPT: |
case OP_ACCEPT: |
6693 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
6713 |
int alternativesize; |
int alternativesize; |
6714 |
BOOL needsframe; |
BOOL needsframe; |
6715 |
fallback_common altfallback; |
fallback_common altfallback; |
6716 |
|
struct sljit_label *save_leavelabel = common->leavelabel; |
6717 |
|
jump_list *save_leave = common->leave; |
6718 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
6719 |
|
|
6720 |
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); |
6723 |
framesize = 0; |
framesize = 0; |
6724 |
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; |
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; |
6725 |
|
|
6726 |
SLJIT_ASSERT(common->currententry->entry == NULL); |
SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); |
6727 |
common->currententry->entry = LABEL(); |
common->currententry->entry = LABEL(); |
6728 |
set_jumps(common->currententry->calls, common->currententry->entry); |
set_jumps(common->currententry->calls, common->currententry->entry); |
6729 |
|
|
6731 |
allocate_stack(common, localsize + framesize + alternativesize); |
allocate_stack(common, localsize + framesize + alternativesize); |
6732 |
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); |
6733 |
copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); |
copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); |
6734 |
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); |
6735 |
if (needsframe) |
if (needsframe) |
6736 |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE); |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); |
6737 |
|
|
6738 |
if (alternativesize > 0) |
if (alternativesize > 0) |
6739 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
6740 |
|
|
6741 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altfallback, 0, sizeof(fallback_common)); |
6742 |
|
common->leavelabel = NULL; |
6743 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
6744 |
|
common->leave = NULL; |
6745 |
common->accept = NULL; |
common->accept = NULL; |
6746 |
altfallback.cc = ccbegin; |
altfallback.cc = ccbegin; |
6747 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
6755 |
|
|
6756 |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
6757 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
6758 |
|
{ |
6759 |
|
common->leavelabel = save_leavelabel; |
6760 |
|
common->leave = save_leave; |
6761 |
return; |
return; |
6762 |
|
} |
6763 |
|
|
6764 |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
6765 |
|
|
6766 |
compile_fallbackpath(common, altfallback.top); |
compile_fallbackpath(common, altfallback.top); |
6767 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
6768 |
|
{ |
6769 |
|
common->leavelabel = save_leavelabel; |
6770 |
|
common->leave = save_leave; |
6771 |
return; |
return; |
6772 |
|
} |
6773 |
set_jumps(altfallback.topfallbacks, LABEL()); |
set_jumps(altfallback.topfallbacks, LABEL()); |
6774 |
|
|
6775 |
if (*cc != OP_ALT) |
if (*cc != OP_ALT) |
6779 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
6780 |
} |
} |
6781 |
/* None of them matched. */ |
/* None of them matched. */ |
6782 |
|
if (common->leave != NULL) |
6783 |
|
set_jumps(common->leave, LABEL()); |
6784 |
|
|
6785 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); |
6786 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
6787 |
|
|
6788 |
set_jumps(common->accept, LABEL()); |
set_jumps(common->accept, LABEL()); |
6789 |
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); |
6790 |
if (needsframe) |
if (needsframe) |
6791 |
{ |
{ |
|
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
|
6792 |
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)); |
6793 |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
6794 |
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); |
|
6795 |
} |
} |
6796 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); |
6797 |
|
|
6800 |
free_stack(common, localsize + framesize + alternativesize); |
free_stack(common, localsize + framesize + alternativesize); |
6801 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); |
6802 |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
6803 |
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); |
6804 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
6805 |
|
|
6806 |
|
common->leavelabel = save_leavelabel; |
6807 |
|
common->leave = save_leave; |
6808 |
} |
} |
6809 |
|
|
6810 |
#undef COMPILE_FALLBACKPATH |
#undef COMPILE_FALLBACKPATH |
6823 |
executable_functions *functions; |
executable_functions *functions; |
6824 |
void *executable_func; |
void *executable_func; |
6825 |
sljit_uw executable_size; |
sljit_uw executable_size; |
|
struct sljit_label *leave; |
|
6826 |
struct sljit_label *mainloop = NULL; |
struct sljit_label *mainloop = NULL; |
6827 |
struct sljit_label *empty_match_found; |
struct sljit_label *empty_match_found; |
6828 |
struct sljit_label *empty_match_fallback; |
struct sljit_label *empty_match_fallback; |
6837 |
tables = PRIV(default_tables); |
tables = PRIV(default_tables); |
6838 |
|
|
6839 |
memset(&rootfallback, 0, sizeof(fallback_common)); |
memset(&rootfallback, 0, sizeof(fallback_common)); |
6840 |
|
memset(common, 0, sizeof(compiler_common)); |
6841 |
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; |
6842 |
|
|
|
common->compiler = NULL; |
|
6843 |
common->start = rootfallback.cc; |
common->start = rootfallback.cc; |
|
common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); |
|
6844 |
common->fcc = tables + fcc_offset; |
common->fcc = tables + fcc_offset; |
6845 |
common->lcc = (sljit_w)(tables + lcc_offset); |
common->lcc = (sljit_w)(tables + lcc_offset); |
6846 |
common->mode = mode; |
common->mode = mode; |
6881 |
common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); |
common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); |
6882 |
common->name_count = re->name_count; |
common->name_count = re->name_count; |
6883 |
common->name_entry_size = re->name_entry_size; |
common->name_entry_size = re->name_entry_size; |
|
common->partialmatchlabel = NULL; |
|
|
common->acceptlabel = NULL; |
|
|
common->stubs = NULL; |
|
|
common->entries = NULL; |
|
|
common->currententry = NULL; |
|
|
common->partialmatch = 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; |
|
6884 |
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; |
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; |
6885 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
6886 |
/* PCRE_UTF16 has the same value as PCRE_UTF8. */ |
/* PCRE_UTF16 has the same value as PCRE_UTF8. */ |
6888 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
6889 |
common->use_ucp = (re->options & PCRE_UCP) != 0; |
common->use_ucp = (re->options & PCRE_UCP) != 0; |
6890 |
#endif |
#endif |
|
common->utfreadchar = NULL; |
|
|
#ifdef COMPILE_PCRE8 |
|
|
common->utfreadtype8 = NULL; |
|
|
#endif |
|
6891 |
#endif /* SUPPORT_UTF */ |
#endif /* SUPPORT_UTF */ |
|
#ifdef SUPPORT_UCP |
|
|
common->getucd = NULL; |
|
|
#endif |
|
6892 |
ccend = bracketend(rootfallback.cc); |
ccend = bracketend(rootfallback.cc); |
6893 |
|
|
6894 |
|
/* Calculate the local space size on the stack. */ |
6895 |
|
common->ovector_start = CALL_LIMIT + sizeof(sljit_w); |
6896 |
|
|
6897 |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
6898 |
common->localsize = get_localspace(common, rootfallback.cc, ccend); |
common->localsize = get_localspace(common, rootfallback.cc, ccend); |
6899 |
if (common->localsize < 0) |
if (common->localsize < 0) |
6900 |
return; |
return; |
6901 |
|
|
6902 |
|
/* Checking flags and updating ovector_start. */ |
6903 |
|
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0) |
6904 |
|
{ |
6905 |
|
common->req_char_ptr = common->ovector_start; |
6906 |
|
common->ovector_start += sizeof(sljit_w); |
6907 |
|
} |
6908 |
|
if (mode != JIT_COMPILE) |
6909 |
|
{ |
6910 |
|
common->start_used_ptr = common->ovector_start; |
6911 |
|
common->ovector_start += sizeof(sljit_w); |
6912 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
6913 |
|
{ |
6914 |
|
common->hit_start = common->ovector_start; |
6915 |
|
common->ovector_start += sizeof(sljit_w); |
6916 |
|
} |
6917 |
|
} |
6918 |
|
if ((re->options & PCRE_FIRSTLINE) != 0) |
6919 |
|
{ |
6920 |
|
common->first_line_end = common->ovector_start; |
6921 |
|
common->ovector_start += sizeof(sljit_w); |
6922 |
|
} |
6923 |
|
|
6924 |
|
/* Aligning ovector to even number of sljit words. */ |
6925 |
|
if ((common->ovector_start & sizeof(sljit_w)) != 0) |
6926 |
|
common->ovector_start += sizeof(sljit_w); |
6927 |
|
|
6928 |
|
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); |
6929 |
|
common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); |
6930 |
common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
6931 |
if (common->localsize > SLJIT_MAX_LOCAL_SIZE) |
if (common->localsize > SLJIT_MAX_LOCAL_SIZE) |
6932 |
return; |
return; |
6950 |
/* Register init. */ |
/* Register init. */ |
6951 |
reset_ovector(common, (re->top_bracket + 1) * 2); |
reset_ovector(common, (re->top_bracket + 1) * 2); |
6952 |
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0) |
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0) |
6953 |
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); |
6954 |
|
|
6955 |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); |
6956 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); |
6963 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
6964 |
|
|
6965 |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
6966 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); |
6967 |
|
|
6968 |
/* Main part of the matching */ |
/* Main part of the matching */ |
6969 |
if ((re->options & PCRE_ANCHORED) == 0) |
if ((re->options & PCRE_ANCHORED) == 0) |
6984 |
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); |
6985 |
/* Copy the limit of allowed recursions. */ |
/* Copy the limit of allowed recursions. */ |
6986 |
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); |
6987 |
|
if (common->mark_ptr != 0) |
6988 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); |
6989 |
/* Copy the beginning of the string. */ |
/* Copy the beginning of the string. */ |
6990 |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
6991 |
{ |
{ |
6992 |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0); |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); |
6993 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
6994 |
JUMPHERE(jump); |
JUMPHERE(jump); |
6995 |
} |
} |
6996 |
else if (mode == JIT_PARTIAL_HARD_COMPILE) |
else if (mode == JIT_PARTIAL_HARD_COMPILE) |
6997 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
6998 |
|
|
6999 |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
7000 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
7013 |
|
|
7014 |
/* This means we have a match. Update the ovector. */ |
/* This means we have a match. Update the ovector. */ |
7015 |
copy_ovector(common, re->top_bracket + 1); |
copy_ovector(common, re->top_bracket + 1); |
7016 |
leave = LABEL(); |
common->leavelabel = LABEL(); |
7017 |
|
if (common->leave != NULL) |
7018 |
|
set_jumps(common->leave, common->leavelabel); |
7019 |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
7020 |
|
|
7021 |
if (mode != JIT_COMPILE) |
if (mode != JIT_COMPILE) |
7022 |
{ |
{ |
7023 |
common->partialmatchlabel = LABEL(); |
common->partialmatchlabel = LABEL(); |
7024 |
set_jumps(common->partialmatch, common->partialmatchlabel); |
set_jumps(common->partialmatch, common->partialmatchlabel); |
7025 |
return_with_partial_match(common, leave); |
return_with_partial_match(common, common->leavelabel); |
7026 |
} |
} |
7027 |
|
|
7028 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
7038 |
|
|
7039 |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
7040 |
{ |
{ |
7041 |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1); |
/* Update hit_start only in the first time. */ |
7042 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR); |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
7043 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr); |
7044 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); |
7045 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0); |
7046 |
JUMPHERE(jump); |
JUMPHERE(jump); |
7047 |
} |
} |
7048 |
|
|
7055 |
{ |
{ |
7056 |
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1) |
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1) |
7057 |
{ |
{ |
7058 |
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)); |
7059 |
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); |
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); |
7060 |
} |
} |
7061 |
else |
else |
7063 |
} |
} |
7064 |
else |
else |
7065 |
{ |
{ |
7066 |
|
SLJIT_ASSERT(common->first_line_end != 0); |
7067 |
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1) |
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1) |
7068 |
{ |
{ |
7069 |
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)); |
7070 |
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); |
7071 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); |
7072 |
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); |
7073 |
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); |
7074 |
JUMPTO(SLJIT_C_ZERO, mainloop); |
JUMPTO(SLJIT_C_ZERO, mainloop); |
7075 |
} |
} |
7076 |
else |
else |
7077 |
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); |
7078 |
} |
} |
7079 |
} |
} |
7080 |
|
|
7083 |
JUMPHERE(reqbyte_notfound); |
JUMPHERE(reqbyte_notfound); |
7084 |
|
|
7085 |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
7086 |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0, common->partialmatchlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); |
7087 |
|
|
7088 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
7089 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
7090 |
|
|
7091 |
flush_stubs(common); |
flush_stubs(common); |
7092 |
|
|
7139 |
JUMPHERE(jump); |
JUMPHERE(jump); |
7140 |
/* 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. */ |
7141 |
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); |
7142 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
7143 |
|
|
7144 |
/* Call limit reached. */ |
/* Call limit reached. */ |
7145 |
set_jumps(common->calllimit, LABEL()); |
set_jumps(common->calllimit, LABEL()); |
7146 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
7147 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
7148 |
|
|
7149 |
if (common->revertframes != NULL) |
if (common->revertframes != NULL) |
7150 |
{ |
{ |
7251 |
} |
} |
7252 |
|
|
7253 |
int |
int |
7254 |
PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs, |
PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, |
7255 |
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) |
|
7256 |
{ |
{ |
7257 |
executable_functions *functions = (executable_functions *)executable_funcs; |
executable_functions *functions = (executable_functions *)extra_data->executable_jit; |
7258 |
union { |
union { |
7259 |
void* executable_func; |
void* executable_func; |
7260 |
jit_function call_executable_func; |
jit_function call_executable_func; |
7277 |
arguments.str = subject + start_offset; |
arguments.str = subject + start_offset; |
7278 |
arguments.begin = subject; |
arguments.begin = subject; |
7279 |
arguments.end = subject + length; |
arguments.end = subject + length; |
7280 |
arguments.calllimit = match_limit; /* JIT decreases this value less times. */ |
arguments.mark_ptr = NULL; |
7281 |
|
/* JIT decreases this value less frequently than the interpreter. */ |
7282 |
|
arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; |
7283 |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
7284 |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
7285 |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
7314 |
|
|
7315 |
if (retval * 2 > offsetcount) |
if (retval * 2 > offsetcount) |
7316 |
retval = 0; |
retval = 0; |
7317 |
|
if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) |
7318 |
|
*(extra_data->mark) = arguments.mark_ptr; |
7319 |
|
|
7320 |
return retval; |
return retval; |
7321 |
} |
} |
7322 |
|
|
7336 |
int |
int |
7337 |
PRIV(jit_get_size)(void *executable_funcs) |
PRIV(jit_get_size)(void *executable_funcs) |
7338 |
{ |
{ |
7339 |
return ((executable_functions *)executable_funcs)->executable_sizes[PCRE_STUDY_JIT_COMPILE]; |
int i; |
7340 |
|
sljit_uw size = 0; |
7341 |
|
sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes; |
7342 |
|
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) |
7343 |
|
size += executable_sizes[i]; |
7344 |
|
return (int)size; |
7345 |
} |
} |
7346 |
|
|
7347 |
const char* |
const char* |