| 164 |
|
|
| 165 |
typedef struct executable_function { |
typedef struct executable_function { |
| 166 |
void *executable_func; |
void *executable_func; |
| 167 |
pcre_jit_callback callback; |
PUBL(jit_callback) callback; |
| 168 |
void *userdata; |
void *userdata; |
| 169 |
sljit_uw executable_size; |
sljit_uw executable_size; |
| 170 |
} executable_function; |
} executable_function; |
| 352 |
frame_setstrbegin = -1 |
frame_setstrbegin = -1 |
| 353 |
}; |
}; |
| 354 |
|
|
| 355 |
|
/* Undefine sljit macros. */ |
| 356 |
|
#undef CMP |
| 357 |
|
|
| 358 |
/* Used for accessing the elements of the stack. */ |
/* Used for accessing the elements of the stack. */ |
| 359 |
#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) |
#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) |
| 360 |
|
|
| 361 |
#define TMP1 SLJIT_TEMPORARY_REG1 |
#define TMP1 SLJIT_TEMPORARY_REG1 |
| 362 |
#define TMP2 SLJIT_TEMPORARY_REG3 |
#define TMP2 SLJIT_TEMPORARY_REG3 |
| 363 |
#define TMP3 SLJIT_TEMPORARY_EREG2 |
#define TMP3 SLJIT_TEMPORARY_EREG2 |
| 364 |
#define STR_PTR SLJIT_GENERAL_REG1 |
#define STR_PTR SLJIT_SAVED_REG1 |
| 365 |
#define STR_END SLJIT_GENERAL_REG2 |
#define STR_END SLJIT_SAVED_REG2 |
| 366 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
| 367 |
#define STACK_LIMIT SLJIT_GENERAL_REG3 |
#define STACK_LIMIT SLJIT_SAVED_REG3 |
| 368 |
#define ARGUMENTS SLJIT_GENERAL_EREG1 |
#define ARGUMENTS SLJIT_SAVED_EREG1 |
| 369 |
#define CALL_COUNT SLJIT_GENERAL_EREG2 |
#define CALL_COUNT SLJIT_SAVED_EREG2 |
| 370 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
| 371 |
|
|
| 372 |
/* Locals layout. */ |
/* Locals layout. */ |
| 1204 |
int i; |
int i; |
| 1205 |
/* At this point we can freely use all temporary registers. */ |
/* At this point we can freely use all temporary registers. */ |
| 1206 |
/* TMP1 returns with begin - 1. */ |
/* TMP1 returns with begin - 1. */ |
| 1207 |
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)); |
| 1208 |
if (length < 8) |
if (length < 8) |
| 1209 |
{ |
{ |
| 1210 |
for (i = 0; i < length; i++) |
for (i = 0; i < length; i++) |
| 1228 |
struct sljit_jump *earlyexit; |
struct sljit_jump *earlyexit; |
| 1229 |
|
|
| 1230 |
/* At this point we can freely use all registers. */ |
/* At this point we can freely use all registers. */ |
| 1231 |
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)); |
| 1232 |
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); |
| 1233 |
|
|
| 1234 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
| 1235 |
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)); |
| 1236 |
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)); |
| 1237 |
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)); |
| 1238 |
OP2(SLJIT_ADD, SLJIT_GENERAL_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); |
| 1239 |
/* Unlikely, but possible */ |
/* Unlikely, but possible */ |
| 1240 |
earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); |
earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); |
| 1241 |
loop = LABEL(); |
loop = LABEL(); |
| 1242 |
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); |
| 1243 |
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)); |
| 1244 |
/* Copy the integer value to the output buffer */ |
/* Copy the integer value to the output buffer */ |
| 1245 |
#ifdef COMPILE_PCRE16 |
#ifdef COMPILE_PCRE16 |
| 1246 |
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); |
| 1247 |
#endif |
#endif |
| 1248 |
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); |
| 1249 |
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); |
| 1250 |
JUMPTO(SLJIT_C_NOT_ZERO, loop); |
JUMPTO(SLJIT_C_NOT_ZERO, loop); |
| 1251 |
JUMPHERE(earlyexit); |
JUMPHERE(earlyexit); |
| 1256 |
OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); |
OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); |
| 1257 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); |
| 1258 |
|
|
| 1259 |
/* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */ |
/* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ |
| 1260 |
loop = LABEL(); |
loop = LABEL(); |
| 1261 |
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))); |
| 1262 |
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); |
| 1263 |
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); |
| 1264 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); |
| 1265 |
} |
} |
| 1266 |
else |
else |
| 6357 |
#undef CURRENT_AS |
#undef CURRENT_AS |
| 6358 |
|
|
| 6359 |
void |
void |
| 6360 |
PRIV(jit_compile)(const real_pcre *re, PUBL(extra) *extra) |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra) |
| 6361 |
{ |
{ |
| 6362 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
| 6363 |
fallback_common rootfallback; |
fallback_common rootfallback; |
| 6487 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if ((re->flags & PCRE_REQCHSET) != 0) |
| 6488 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0); |
| 6489 |
|
|
| 6490 |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0); |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); |
| 6491 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); |
| 6492 |
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)); |
| 6493 |
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)); |
| 6494 |
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)); |
| 6535 |
/* This means we have a match. Update the ovector. */ |
/* This means we have a match. Update the ovector. */ |
| 6536 |
copy_ovector(common, re->top_bracket + 1); |
copy_ovector(common, re->top_bracket + 1); |
| 6537 |
leave = LABEL(); |
leave = LABEL(); |
| 6538 |
sljit_emit_return(compiler, SLJIT_UNUSED, 0); |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
| 6539 |
|
|
| 6540 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
| 6541 |
compile_fallbackpath(common, rootfallback.top); |
compile_fallbackpath(common, rootfallback.top); |
| 6744 |
} |
} |
| 6745 |
|
|
| 6746 |
int |
int |
| 6747 |
PRIV(jit_exec)(const real_pcre *re, void *executable_func, |
PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func, |
| 6748 |
const pcre_uchar *subject, int length, int start_offset, int options, |
const pcre_uchar *subject, int length, int start_offset, int options, |
| 6749 |
int match_limit, int *offsets, int offsetcount) |
int match_limit, int *offsets, int offsetcount) |
| 6750 |
{ |
{ |
| 6775 |
number of captured strings in the same way as pcre_exec(), so that the user |
number of captured strings in the same way as pcre_exec(), so that the user |
| 6776 |
gets the same result with and without JIT. */ |
gets the same result with and without JIT. */ |
| 6777 |
|
|
| 6778 |
offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3; |
if (offsetcount != 2) |
| 6779 |
|
offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3; |
| 6780 |
maxoffsetcount = (re->top_bracket + 1) * 2; |
maxoffsetcount = (re->top_bracket + 1) * 2; |
| 6781 |
if (offsetcount > maxoffsetcount) |
if (offsetcount > maxoffsetcount) |
| 6782 |
offsetcount = maxoffsetcount; |
offsetcount = maxoffsetcount; |
| 6818 |
PCRE_EXP_DECL pcre_jit_stack * |
PCRE_EXP_DECL pcre_jit_stack * |
| 6819 |
pcre_jit_stack_alloc(int startsize, int maxsize) |
pcre_jit_stack_alloc(int startsize, int maxsize) |
| 6820 |
#else |
#else |
| 6821 |
PCRE_EXP_DECL pcre_jit_stack * |
PCRE_EXP_DECL pcre16_jit_stack * |
| 6822 |
pcre16_jit_stack_alloc(int startsize, int maxsize) |
pcre16_jit_stack_alloc(int startsize, int maxsize) |
| 6823 |
#endif |
#endif |
| 6824 |
{ |
{ |
| 6828 |
startsize = maxsize; |
startsize = maxsize; |
| 6829 |
startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); |
startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); |
| 6830 |
maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); |
maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); |
| 6831 |
return (pcre_jit_stack*)sljit_allocate_stack(startsize, maxsize); |
return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize); |
| 6832 |
} |
} |
| 6833 |
|
|
| 6834 |
#ifdef COMPILE_PCRE8 |
#ifdef COMPILE_PCRE8 |
| 6836 |
pcre_jit_stack_free(pcre_jit_stack *stack) |
pcre_jit_stack_free(pcre_jit_stack *stack) |
| 6837 |
#else |
#else |
| 6838 |
PCRE_EXP_DECL void |
PCRE_EXP_DECL void |
| 6839 |
pcre16_jit_stack_free(pcre_jit_stack *stack) |
pcre16_jit_stack_free(pcre16_jit_stack *stack) |
| 6840 |
#endif |
#endif |
| 6841 |
{ |
{ |
| 6842 |
sljit_free_stack((struct sljit_stack*)stack); |
sljit_free_stack((struct sljit_stack*)stack); |
| 6847 |
pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
| 6848 |
#else |
#else |
| 6849 |
PCRE_EXP_DECL void |
PCRE_EXP_DECL void |
| 6850 |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre_jit_callback callback, void *userdata) |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) |
| 6851 |
#endif |
#endif |
| 6852 |
{ |
{ |
| 6853 |
executable_function *function; |
executable_function *function; |
| 6870 |
PCRE_EXP_DECL pcre_jit_stack * |
PCRE_EXP_DECL pcre_jit_stack * |
| 6871 |
pcre_jit_stack_alloc(int startsize, int maxsize) |
pcre_jit_stack_alloc(int startsize, int maxsize) |
| 6872 |
#else |
#else |
| 6873 |
PCRE_EXP_DECL pcre_jit_stack * |
PCRE_EXP_DECL pcre16_jit_stack * |
| 6874 |
pcre16_jit_stack_alloc(int startsize, int maxsize) |
pcre16_jit_stack_alloc(int startsize, int maxsize) |
| 6875 |
#endif |
#endif |
| 6876 |
{ |
{ |
| 6884 |
pcre_jit_stack_free(pcre_jit_stack *stack) |
pcre_jit_stack_free(pcre_jit_stack *stack) |
| 6885 |
#else |
#else |
| 6886 |
PCRE_EXP_DECL void |
PCRE_EXP_DECL void |
| 6887 |
pcre16_jit_stack_free(pcre_jit_stack *stack) |
pcre16_jit_stack_free(pcre16_jit_stack *stack) |
| 6888 |
#endif |
#endif |
| 6889 |
{ |
{ |
| 6890 |
(void)stack; |
(void)stack; |
| 6895 |
pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
| 6896 |
#else |
#else |
| 6897 |
PCRE_EXP_DECL void |
PCRE_EXP_DECL void |
| 6898 |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre_jit_callback callback, void *userdata) |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) |
| 6899 |
#endif |
#endif |
| 6900 |
{ |
{ |
| 6901 |
(void)extra; |
(void)extra; |