| 119 |
jump to D hot path |
jump to D hot path |
| 120 |
C fallback path |
C fallback path |
| 121 |
A fallback path |
A fallback path |
| 122 |
|
|
| 123 |
Notice, that the order of fallback code paths are the opposite of the fast |
Notice, that the order of fallback code paths are the opposite of the fast |
| 124 |
code paths. In this way the topmost value on the stack is always belong |
code paths. In this way the topmost value on the stack is always belong |
| 125 |
to the current fallback code path. The fallback code path must check |
to the current fallback code path. The fallback code path must check |
| 152 |
uschar *ptr; |
uschar *ptr; |
| 153 |
/* Everything else after. */ |
/* Everything else after. */ |
| 154 |
int offsetcount; |
int offsetcount; |
| 155 |
|
int calllimit; |
| 156 |
uschar notbol; |
uschar notbol; |
| 157 |
uschar noteol; |
uschar noteol; |
| 158 |
uschar notempty; |
uschar notempty; |
| 281 |
recurse_entry *entries; |
recurse_entry *entries; |
| 282 |
recurse_entry *currententry; |
recurse_entry *currententry; |
| 283 |
jump_list *accept; |
jump_list *accept; |
| 284 |
|
jump_list *calllimit; |
| 285 |
jump_list *stackalloc; |
jump_list *stackalloc; |
| 286 |
jump_list *revertframes; |
jump_list *revertframes; |
| 287 |
jump_list *wordboundary; |
jump_list *wordboundary; |
| 343 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
| 344 |
#define STACK_LIMIT SLJIT_GENERAL_REG3 |
#define STACK_LIMIT SLJIT_GENERAL_REG3 |
| 345 |
#define ARGUMENTS SLJIT_GENERAL_EREG1 |
#define ARGUMENTS SLJIT_GENERAL_EREG1 |
| 346 |
#define MAX_INDEX SLJIT_GENERAL_EREG2 |
#define CALL_COUNT SLJIT_GENERAL_EREG2 |
| 347 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
| 348 |
|
|
| 349 |
/* Locals layout. */ |
/* Locals layout. */ |
| 357 |
#define LOCALS_HEAD (4 * sizeof(sljit_w)) |
#define LOCALS_HEAD (4 * sizeof(sljit_w)) |
| 358 |
/* Head of the last recursion. */ |
/* Head of the last recursion. */ |
| 359 |
#define RECURSIVE_HEAD (5 * sizeof(sljit_w)) |
#define RECURSIVE_HEAD (5 * sizeof(sljit_w)) |
| 360 |
|
/* Number of recursions. */ |
| 361 |
|
#define MAX_INDEX (6 * sizeof(sljit_w)) |
| 362 |
|
/* Max limit of recursions. */ |
| 363 |
|
#define CALL_LIMIT (7 * sizeof(sljit_w)) |
| 364 |
/* Last known position of the requested byte. */ |
/* Last known position of the requested byte. */ |
| 365 |
#define REQ_BYTE_PTR (6 * sizeof(sljit_w)) |
#define REQ_BYTE_PTR (8 * sizeof(sljit_w)) |
| 366 |
/* End pointer of the first line. */ |
/* End pointer of the first line. */ |
| 367 |
#define FIRSTLINE_END (7 * sizeof(sljit_w)) |
#define FIRSTLINE_END (9 * sizeof(sljit_w)) |
| 368 |
/* The output vector is stored on the stack, and contains pointers |
/* The output vector is stored on the stack, and contains pointers |
| 369 |
to characters. The vector data is divided into two groups: the first |
to characters. The vector data is divided into two groups: the first |
| 370 |
group contains the start / end character pointers, and the second is |
group contains the start / end character pointers, and the second is |
| 371 |
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. */ |
| 372 |
#define OVECTOR_START (8 * sizeof(sljit_w)) |
#define OVECTOR_START (10 * sizeof(sljit_w)) |
| 373 |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
| 374 |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
| 375 |
#define PRIV(cc) (common->localptrs[(cc) - common->start]) |
#define PRIV(cc) (common->localptrs[(cc) - common->start]) |
| 405 |
return cc; |
return cc; |
| 406 |
} |
} |
| 407 |
|
|
| 408 |
/* Functions whose might need modification for all new supported opcodes: |
/* Functions whose might need modification for all new supported opcodes: |
| 409 |
next_opcode |
next_opcode |
| 410 |
get_localspace |
get_localspace |
| 411 |
set_localptrs |
set_localptrs |
| 829 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
| 830 |
if (!needs_maxindex) |
if (!needs_maxindex) |
| 831 |
{ |
{ |
| 832 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
| 833 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex); |
| 834 |
stackpos += (int)sizeof(sljit_w); |
stackpos += (int)sizeof(sljit_w); |
| 835 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); |
| 836 |
stackpos += (int)sizeof(sljit_w); |
stackpos += (int)sizeof(sljit_w); |
| 837 |
needs_maxindex = TRUE; |
needs_maxindex = TRUE; |
| 838 |
} |
} |
| 1173 |
break; |
break; |
| 1174 |
|
|
| 1175 |
case max_index: |
case max_index: |
| 1176 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, list_item->data); |
| 1177 |
break; |
break; |
| 1178 |
} |
} |
| 1179 |
JUMPTO(SLJIT_JUMP, list_item->leave); |
JUMPTO(SLJIT_JUMP, list_item->leave); |
| 1182 |
common->stubs = NULL; |
common->stubs = NULL; |
| 1183 |
} |
} |
| 1184 |
|
|
| 1185 |
|
static SLJIT_INLINE void decrease_call_count(compiler_common *common) |
| 1186 |
|
{ |
| 1187 |
|
DEFINE_COMPILER; |
| 1188 |
|
|
| 1189 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); |
| 1190 |
|
add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); |
| 1191 |
|
} |
| 1192 |
|
|
| 1193 |
static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) |
static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) |
| 1194 |
{ |
{ |
| 1195 |
/* May destroy all locals and registers except TMP2. */ |
/* May destroy all locals and registers except TMP2. */ |
| 1219 |
int i; |
int i; |
| 1220 |
/* At this point we can freely use all temporary registers. */ |
/* At this point we can freely use all temporary registers. */ |
| 1221 |
/* TMP1 returns with begin - 1. */ |
/* TMP1 returns with begin - 1. */ |
| 1222 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, 1); |
| 1223 |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1); |
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1); |
| 1224 |
if (length < 8) |
if (length < 8) |
| 1225 |
{ |
{ |
| 2002 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 2003 |
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex); |
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex); |
| 2004 |
/* Set max index. */ |
/* Set max index. */ |
| 2005 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
| 2006 |
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)); |
| 2007 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP2, 0); |
| 2008 |
JUMPTO(SLJIT_JUMP, mainloop); |
JUMPTO(SLJIT_JUMP, mainloop); |
| 2009 |
|
|
| 2010 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 2025 |
{ |
{ |
| 2026 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 2027 |
struct sljit_jump *beginend; |
struct sljit_jump *beginend; |
| 2028 |
|
#ifdef SUPPORT_UTF8 |
| 2029 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 2030 |
|
#endif |
| 2031 |
|
|
| 2032 |
SLJIT_ASSERT(ctype_word == 0x10); |
SLJIT_ASSERT(ctype_word == 0x10); |
| 2033 |
|
|
| 2386 |
} |
} |
| 2387 |
context->byteptr = 0; |
context->byteptr = 0; |
| 2388 |
} |
} |
| 2389 |
|
|
| 2390 |
#else |
#else |
| 2391 |
|
|
| 2392 |
/* Unaligned read is unsupported. */ |
/* Unaligned read is unsupported. */ |
| 2769 |
int length; |
int length; |
| 2770 |
unsigned int c, oc, bit; |
unsigned int c, oc, bit; |
| 2771 |
compare_context context; |
compare_context context; |
|
struct sljit_label *label; |
|
| 2772 |
struct sljit_jump *jump[4]; |
struct sljit_jump *jump[4]; |
| 2773 |
#ifdef SUPPORT_UTF8 |
#ifdef SUPPORT_UTF8 |
| 2774 |
|
struct sljit_label *label; |
| 2775 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
| 2776 |
uschar propdata[5]; |
uschar propdata[5]; |
| 2777 |
#endif |
#endif |
| 3234 |
else if (cc[1] >= 0xc0) |
else if (cc[1] >= 0xc0) |
| 3235 |
size += _pcre_utf8_table4[cc[1] & 0x3f]; |
size += _pcre_utf8_table4[cc[1] & 0x3f]; |
| 3236 |
} |
} |
| 3237 |
else |
else |
| 3238 |
#endif |
#endif |
| 3239 |
if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) |
if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0) |
| 3240 |
size = 0; |
size = 0; |
| 3471 |
|
|
| 3472 |
JUMPHERE(zerolength); |
JUMPHERE(zerolength); |
| 3473 |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
FALLBACK_AS(iterator_fallback)->hotpath = LABEL(); |
| 3474 |
|
|
| 3475 |
|
decrease_call_count(common); |
| 3476 |
return cc; |
return cc; |
| 3477 |
} |
} |
| 3478 |
|
|
| 3510 |
if (jump != NULL) |
if (jump != NULL) |
| 3511 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 3512 |
JUMPHERE(zerolength); |
JUMPHERE(zerolength); |
| 3513 |
|
|
| 3514 |
|
decrease_call_count(common); |
| 3515 |
return cc; |
return cc; |
| 3516 |
} |
} |
| 3517 |
|
|
| 4079 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
| 4080 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
| 4081 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
| 4082 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
| 4083 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4084 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); |
| 4085 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); |
| 4086 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP2, 0); |
| 4087 |
/* Update MAX_INDEX if necessary. */ |
/* Update MAX_INDEX if necessary. */ |
| 4088 |
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1)); |
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, (offset >> 1) + 1)); |
| 4089 |
} |
} |
| 4090 |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
| 4091 |
{ |
{ |
| 4233 |
/* Continue to the normal fallback. */ |
/* Continue to the normal fallback. */ |
| 4234 |
} |
} |
| 4235 |
|
|
| 4236 |
|
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) |
| 4237 |
|
decrease_call_count(common); |
| 4238 |
|
|
| 4239 |
/* Skip the other alternatives. */ |
/* Skip the other alternatives. */ |
| 4240 |
while (*cc == OP_ALT) |
while (*cc == OP_ALT) |
| 4241 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 4306 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
| 4307 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
| 4308 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
| 4309 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
| 4310 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
| 4311 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); |
| 4312 |
} |
} |
| 4313 |
else |
else |
| 4314 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 4365 |
if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) |
if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) |
| 4366 |
{ |
{ |
| 4367 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); |
| 4368 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
| 4369 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
| 4370 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 4371 |
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1)); |
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1)); |
| 4372 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
| 4373 |
} |
} |
| 4374 |
else |
else |
| 4389 |
if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) |
if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) |
| 4390 |
{ |
{ |
| 4391 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); |
| 4392 |
if (!zero) |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
|
| 4393 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
| 4394 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 4395 |
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1)); |
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1)); |
| 4396 |
|
if (!zero) |
| 4397 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4398 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
| 4399 |
} |
} |
| 4400 |
else |
else |
| 4463 |
|
|
| 4464 |
/* None of them matched. */ |
/* None of them matched. */ |
| 4465 |
set_jumps(emptymatch, LABEL()); |
set_jumps(emptymatch, LABEL()); |
| 4466 |
|
decrease_call_count(common); |
| 4467 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
| 4468 |
} |
} |
| 4469 |
|
|
| 4724 |
break; |
break; |
| 4725 |
} |
} |
| 4726 |
|
|
| 4727 |
|
decrease_call_count(common); |
| 4728 |
return end; |
return end; |
| 4729 |
} |
} |
| 4730 |
|
|
| 4783 |
return cc + 3; |
return cc + 3; |
| 4784 |
|
|
| 4785 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); |
| 4786 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
| 4787 |
offset <<= 1; |
offset <<= 1; |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
|
| 4788 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
| 4789 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 4790 |
offset = (offset >> 1) + 1; |
offset = (offset >> 1) + 1; |
| 4791 |
jump = CMP(SLJIT_C_GREATER_EQUAL, MAX_INDEX, 0, SLJIT_IMM, offset); |
jump = CMP(SLJIT_C_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, offset); |
| 4792 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, offset); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, offset); |
| 4793 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 4794 |
return cc + 3; |
return cc + 3; |
| 4795 |
} |
} |
| 4969 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); |
| 4970 |
} |
} |
| 4971 |
FALLBACK_AS(braminzero_fallback)->hotpath = LABEL(); |
FALLBACK_AS(braminzero_fallback)->hotpath = LABEL(); |
| 4972 |
|
if (cc[1] > OP_ASSERTBACK_NOT) |
| 4973 |
|
decrease_call_count(common); |
| 4974 |
break; |
break; |
| 4975 |
|
|
| 4976 |
case OP_ONCE: |
case OP_ONCE: |
| 5557 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 5558 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 5559 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); |
| 5560 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(3)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
| 5561 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(3)); |
| 5562 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0); |
| 5563 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); |
| 5564 |
free_stack(common, 4); |
free_stack(common, 4); |
| 5565 |
} |
} |
| 5566 |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
| 5649 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 5650 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 5651 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 5652 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
| 5653 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); |
| 5654 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0); |
| 5655 |
} |
} |
| 5656 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topfallbacks, LABEL()); |
| 5657 |
free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); |
free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); |
| 5949 |
compiler_common common_data; |
compiler_common common_data; |
| 5950 |
compiler_common *common = &common_data; |
compiler_common *common = &common_data; |
| 5951 |
const unsigned char *tables = re->tables; |
const unsigned char *tables = re->tables; |
| 5952 |
pcre_study_data *study = (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0 ? extra->study_data : NULL; |
pcre_study_data *study; |
| 5953 |
uschar *ccend; |
uschar *ccend; |
| 5954 |
executable_function *function; |
executable_function *function; |
| 5955 |
void *executable_func; |
void *executable_func; |
| 5961 |
struct sljit_jump *reqbyte_notfound = NULL; |
struct sljit_jump *reqbyte_notfound = NULL; |
| 5962 |
struct sljit_jump *empty_match; |
struct sljit_jump *empty_match; |
| 5963 |
|
|
| 5964 |
|
SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0); |
| 5965 |
|
study = extra->study_data; |
| 5966 |
|
|
| 5967 |
if (!tables) |
if (!tables) |
| 5968 |
tables = _pcre_default_tables; |
tables = _pcre_default_tables; |
| 5969 |
|
|
| 5978 |
common->nltype = NLTYPE_FIXED; |
common->nltype = NLTYPE_FIXED; |
| 5979 |
switch(re->options & PCRE_NEWLINE_BITS) |
switch(re->options & PCRE_NEWLINE_BITS) |
| 5980 |
{ |
{ |
| 5981 |
case 0: common->newline = NEWLINE; break; /* Compile-time default */ |
case 0: |
| 5982 |
|
/* Compile-time default */ |
| 5983 |
|
switch (NEWLINE) |
| 5984 |
|
{ |
| 5985 |
|
case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; |
| 5986 |
|
case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; |
| 5987 |
|
default: common->newline = NEWLINE; break; |
| 5988 |
|
} |
| 5989 |
|
break; |
| 5990 |
case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; |
case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; |
| 5991 |
case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; |
case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; |
| 5992 |
case PCRE_NEWLINE_CR+ |
case PCRE_NEWLINE_CR+ |
| 6014 |
common->entries = NULL; |
common->entries = NULL; |
| 6015 |
common->currententry = NULL; |
common->currententry = NULL; |
| 6016 |
common->accept = NULL; |
common->accept = NULL; |
| 6017 |
|
common->calllimit = NULL; |
| 6018 |
common->stackalloc = NULL; |
common->stackalloc = NULL; |
| 6019 |
common->revertframes = NULL; |
common->revertframes = NULL; |
| 6020 |
common->wordboundary = NULL; |
common->wordboundary = NULL; |
| 6071 |
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)); |
| 6072 |
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)); |
| 6073 |
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)); |
| 6074 |
|
OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit)); |
| 6075 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); |
| 6076 |
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)); |
| 6077 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
| 6078 |
|
|
| 6079 |
/* Main part of the matching */ |
/* Main part of the matching */ |
| 6080 |
if ((re->options & PCRE_ANCHORED) == 0) |
if ((re->options & PCRE_ANCHORED) == 0) |
| 6093 |
|
|
| 6094 |
/* Store the current STR_PTR in OVECTOR(0). */ |
/* Store the current STR_PTR in OVECTOR(0). */ |
| 6095 |
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); |
| 6096 |
|
/* Copy the limit of allowed recursions. */ |
| 6097 |
|
OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); |
| 6098 |
|
|
| 6099 |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
| 6100 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6116 |
|
|
| 6117 |
leave = LABEL(); |
leave = LABEL(); |
| 6118 |
copy_ovector(common); |
copy_ovector(common); |
| 6119 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX); |
| 6120 |
sljit_emit_return(compiler, SLJIT_UNUSED, 0); |
sljit_emit_return(compiler, SLJIT_UNUSED, 0); |
| 6121 |
|
|
| 6122 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
| 6165 |
JUMPHERE(reqbyte_notfound); |
JUMPHERE(reqbyte_notfound); |
| 6166 |
/* Copy OVECTOR(1) to OVECTOR(0) */ |
/* Copy OVECTOR(1) to OVECTOR(0) */ |
| 6167 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
| 6168 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
| 6169 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 6170 |
|
|
| 6171 |
flush_stubs(common); |
flush_stubs(common); |
| 6195 |
common->currententry = common->currententry->next; |
common->currententry = common->currententry->next; |
| 6196 |
} |
} |
| 6197 |
|
|
| 6198 |
/* Allocating stack, returns with PCRE_ERROR_NOMEMORY if fails. */ |
/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */ |
| 6199 |
/* This is a (really) rare case. */ |
/* This is a (really) rare case. */ |
| 6200 |
set_jumps(common->stackalloc, LABEL()); |
set_jumps(common->stackalloc, LABEL()); |
| 6201 |
/* RETURN_ADDR is not a saved register. */ |
/* RETURN_ADDR is not a saved register. */ |
| 6218 |
/* Allocation failed. */ |
/* Allocation failed. */ |
| 6219 |
JUMPHERE(alloc_error); |
JUMPHERE(alloc_error); |
| 6220 |
/* 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. */ |
| 6221 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMEMORY); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); |
| 6222 |
|
JUMPTO(SLJIT_JUMP, leave); |
| 6223 |
|
|
| 6224 |
|
/* Call limit reached. */ |
| 6225 |
|
set_jumps(common->calllimit, LABEL()); |
| 6226 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
| 6227 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 6228 |
|
|
| 6229 |
if (common->revertframes != NULL) |
if (common->revertframes != NULL) |
| 6323 |
|
|
| 6324 |
int |
int |
| 6325 |
_pcre_jit_exec(const real_pcre *re, void *executable_func, |
_pcre_jit_exec(const real_pcre *re, void *executable_func, |
| 6326 |
PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, |
PCRE_SPTR subject, int length, int start_offset, int options, |
| 6327 |
int offsetcount) |
int match_limit, int *offsets, int offsetcount) |
| 6328 |
{ |
{ |
| 6329 |
executable_function *function = (executable_function*)executable_func; |
executable_function *function = (executable_function*)executable_func; |
| 6330 |
union { |
union { |
| 6340 |
arguments.str = subject + start_offset; |
arguments.str = subject + start_offset; |
| 6341 |
arguments.begin = subject; |
arguments.begin = subject; |
| 6342 |
arguments.end = subject + length; |
arguments.end = subject + length; |
| 6343 |
|
arguments.calllimit = match_limit; /* JIT decreases this value less times. */ |
| 6344 |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
| 6345 |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
| 6346 |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
| 6404 |
} |
} |
| 6405 |
|
|
| 6406 |
PCRE_EXP_DECL void |
PCRE_EXP_DECL void |
| 6407 |
pcre_assign_jit_callback(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
| 6408 |
{ |
{ |
| 6409 |
executable_function *function; |
executable_function *function; |
| 6410 |
if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) |
if (extra != NULL && |
| 6411 |
|
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
| 6412 |
|
extra->executable_jit != NULL) |
| 6413 |
{ |
{ |
| 6414 |
function = (executable_function*)extra->executable_jit; |
function = (executable_function*)extra->executable_jit; |
| 6415 |
function->callback = callback; |
function->callback = callback; |
| 6419 |
|
|
| 6420 |
#else /* SUPPORT_JIT */ |
#else /* SUPPORT_JIT */ |
| 6421 |
|
|
| 6422 |
/* These are dummy functions to avoid linking errors when JIT support is not |
/* These are dummy functions to avoid linking errors when JIT support is not |
| 6423 |
being compiled. */ |
being compiled. */ |
| 6424 |
|
|
| 6425 |
PCRE_EXP_DECL pcre_jit_stack * |
PCRE_EXP_DECL pcre_jit_stack * |
| 6437 |
} |
} |
| 6438 |
|
|
| 6439 |
PCRE_EXP_DECL void |
PCRE_EXP_DECL void |
| 6440 |
pcre_assign_jit_callback(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) |
| 6441 |
{ |
{ |
| 6442 |
(void)extra; |
(void)extra; |
| 6443 |
(void)callback; |
(void)callback; |