| 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 |
| 170 |
struct jump_list *next; |
struct jump_list *next; |
| 171 |
} jump_list; |
} jump_list; |
| 172 |
|
|
| 173 |
enum stub_types { stack_alloc, max_index }; |
enum stub_types { stack_alloc }; |
| 174 |
|
|
| 175 |
typedef struct stub_list { |
typedef struct stub_list { |
| 176 |
enum stub_types type; |
enum stub_types type; |
| 328 |
|
|
| 329 |
enum { |
enum { |
| 330 |
frame_end = 0, |
frame_end = 0, |
| 331 |
frame_setmaxindex = -1, |
frame_setstrbegin = -1 |
|
frame_setstrbegin = -2 |
|
| 332 |
}; |
}; |
| 333 |
|
|
| 334 |
/* Used for accessing the elements of the stack. */ |
/* Used for accessing the elements of the stack. */ |
| 342 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
#define STACK_TOP SLJIT_TEMPORARY_REG2 |
| 343 |
#define STACK_LIMIT SLJIT_GENERAL_REG3 |
#define STACK_LIMIT SLJIT_GENERAL_REG3 |
| 344 |
#define ARGUMENTS SLJIT_GENERAL_EREG1 |
#define ARGUMENTS SLJIT_GENERAL_EREG1 |
| 345 |
#define MAX_INDEX SLJIT_GENERAL_EREG2 |
#define CALL_COUNT SLJIT_GENERAL_EREG2 |
| 346 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
| 347 |
|
|
| 348 |
/* Locals layout. */ |
/* Locals layout. */ |
| 356 |
#define LOCALS_HEAD (4 * sizeof(sljit_w)) |
#define LOCALS_HEAD (4 * sizeof(sljit_w)) |
| 357 |
/* Head of the last recursion. */ |
/* Head of the last recursion. */ |
| 358 |
#define RECURSIVE_HEAD (5 * sizeof(sljit_w)) |
#define RECURSIVE_HEAD (5 * sizeof(sljit_w)) |
|
/* Number of recursions. */ |
|
|
#define CALL_COUNT (6 * sizeof(sljit_w)) |
|
| 359 |
/* Max limit of recursions. */ |
/* Max limit of recursions. */ |
| 360 |
#define CALL_LIMIT (7 * sizeof(sljit_w)) |
#define CALL_LIMIT (7 * sizeof(sljit_w)) |
| 361 |
/* Last known position of the requested byte. */ |
/* Last known position of the requested byte. */ |
| 402 |
return cc; |
return cc; |
| 403 |
} |
} |
| 404 |
|
|
| 405 |
/* Functions whose might need modification for all new supported opcodes: |
/* Functions whose might need modification for all new supported opcodes: |
| 406 |
next_opcode |
next_opcode |
| 407 |
get_localspace |
get_localspace |
| 408 |
set_localptrs |
set_localptrs |
| 697 |
int length = 0; |
int length = 0; |
| 698 |
BOOL possessive = FALSE; |
BOOL possessive = FALSE; |
| 699 |
BOOL needs_frame = FALSE; |
BOOL needs_frame = FALSE; |
|
BOOL needs_maxindex = FALSE; |
|
| 700 |
BOOL setsom_found = FALSE; |
BOOL setsom_found = FALSE; |
| 701 |
|
|
| 702 |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
| 703 |
{ |
{ |
| 704 |
length = 3 + 2; |
length = 3; |
|
needs_maxindex = TRUE; |
|
| 705 |
possessive = TRUE; |
possessive = TRUE; |
| 706 |
} |
} |
| 707 |
|
|
| 746 |
case OP_CBRAPOS: |
case OP_CBRAPOS: |
| 747 |
case OP_SCBRA: |
case OP_SCBRA: |
| 748 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
|
if (!needs_maxindex) |
|
|
{ |
|
|
needs_maxindex = TRUE; |
|
|
length += 2; |
|
|
} |
|
| 749 |
length += 3; |
length += 3; |
| 750 |
cc += 1 + LINK_SIZE + 2; |
cc += 1 + LINK_SIZE + 2; |
| 751 |
break; |
break; |
| 770 |
/* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */ |
/* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */ |
| 771 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 772 |
uschar *ccend = bracketend(cc); |
uschar *ccend = bracketend(cc); |
|
BOOL needs_maxindex = FALSE; |
|
| 773 |
BOOL setsom_found = FALSE; |
BOOL setsom_found = FALSE; |
| 774 |
int offset; |
int offset; |
| 775 |
|
|
| 816 |
case OP_CBRAPOS: |
case OP_CBRAPOS: |
| 817 |
case OP_SCBRA: |
case OP_SCBRA: |
| 818 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
|
if (!needs_maxindex) |
|
|
{ |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex); |
|
|
stackpos += (int)sizeof(sljit_w); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0); |
|
|
stackpos += (int)sizeof(sljit_w); |
|
|
needs_maxindex = TRUE; |
|
|
} |
|
| 819 |
offset = (GET2(cc, 1 + LINK_SIZE)) << 1; |
offset = (GET2(cc, 1 + LINK_SIZE)) << 1; |
| 820 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); |
| 821 |
stackpos += (int)sizeof(sljit_w); |
stackpos += (int)sizeof(sljit_w); |
| 1151 |
case stack_alloc: |
case stack_alloc: |
| 1152 |
add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); |
| 1153 |
break; |
break; |
|
|
|
|
case max_index: |
|
|
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data); |
|
|
break; |
|
| 1154 |
} |
} |
| 1155 |
JUMPTO(SLJIT_JUMP, list_item->leave); |
JUMPTO(SLJIT_JUMP, list_item->leave); |
| 1156 |
list_item = list_item->next; |
list_item = list_item->next; |
| 1162 |
{ |
{ |
| 1163 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 1164 |
|
|
| 1165 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1); |
OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); |
| 1166 |
add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); |
add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); |
| 1167 |
} |
} |
| 1168 |
|
|
| 1195 |
int i; |
int i; |
| 1196 |
/* At this point we can freely use all temporary registers. */ |
/* At this point we can freely use all temporary registers. */ |
| 1197 |
/* TMP1 returns with begin - 1. */ |
/* TMP1 returns with begin - 1. */ |
|
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1); |
|
| 1198 |
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); |
| 1199 |
if (length < 8) |
if (length < 8) |
| 1200 |
{ |
{ |
| 1212 |
} |
} |
| 1213 |
} |
} |
| 1214 |
|
|
| 1215 |
static SLJIT_INLINE void copy_ovector(compiler_common *common) |
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) |
| 1216 |
{ |
{ |
| 1217 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 1218 |
struct sljit_label *loop; |
struct sljit_label *loop; |
| 1219 |
struct sljit_jump *earlyexit; |
struct sljit_jump *earlyexit; |
| 1220 |
|
|
| 1221 |
/* At this point we can freely use all registers. */ |
/* At this point we can freely use all registers. */ |
| 1222 |
|
OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
| 1223 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); |
| 1224 |
|
|
| 1225 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); |
| 1226 |
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)); |
| 1227 |
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 |
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); |
| 1238 |
JUMPTO(SLJIT_C_NOT_ZERO, loop); |
JUMPTO(SLJIT_C_NOT_ZERO, loop); |
| 1239 |
JUMPHERE(earlyexit); |
JUMPHERE(earlyexit); |
| 1240 |
|
|
| 1241 |
|
/* Calculate the return value, which is the maximum ovector value. */ |
| 1242 |
|
if (topbracket > 1) |
| 1243 |
|
{ |
| 1244 |
|
OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); |
| 1245 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); |
| 1246 |
|
|
| 1247 |
|
/* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */ |
| 1248 |
|
loop = LABEL(); |
| 1249 |
|
OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); |
| 1250 |
|
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); |
| 1251 |
|
CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop); |
| 1252 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); |
| 1253 |
|
} |
| 1254 |
|
else |
| 1255 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
| 1256 |
} |
} |
| 1257 |
|
|
| 1258 |
static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc) |
static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc) |
| 1994 |
sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
sljit_emit_fast_return(compiler, RETURN_ADDR, 0); |
| 1995 |
|
|
| 1996 |
JUMPHERE(jump); |
JUMPHERE(jump); |
|
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex); |
|
|
/* Set max index. */ |
|
|
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
|
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); |
|
|
JUMPTO(SLJIT_JUMP, mainloop); |
|
|
|
|
|
JUMPHERE(jump); |
|
| 1997 |
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); |
jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); |
| 1998 |
/* Set max index. */ |
/* Set string begin. */ |
| 1999 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); |
| 2000 |
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)); |
| 2001 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); |
| 2372 |
} |
} |
| 2373 |
context->byteptr = 0; |
context->byteptr = 0; |
| 2374 |
} |
} |
| 2375 |
|
|
| 2376 |
#else |
#else |
| 2377 |
|
|
| 2378 |
/* Unaligned read is unsupported. */ |
/* Unaligned read is unsupported. */ |
| 2434 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
| 2435 |
BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; |
BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; |
| 2436 |
BOOL charsaved = FALSE; |
BOOL charsaved = FALSE; |
| 2437 |
int typereg = TMP1, scriptreg = TMP1, typeoffset; |
int typereg = TMP1, scriptreg = TMP1; |
| 2438 |
|
unsigned int typeoffset; |
| 2439 |
#endif |
#endif |
| 2440 |
int charoffset, invertcmp, numberofcmps; |
int invertcmp, numberofcmps; |
| 2441 |
|
unsigned int charoffset; |
| 2442 |
|
|
| 2443 |
/* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */ |
/* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */ |
| 2444 |
check_input_end(common, fallbacks); |
check_input_end(common, fallbacks); |
| 3222 |
else if (cc[1] >= 0xc0) |
else if (cc[1] >= 0xc0) |
| 3223 |
size += _pcre_utf8_table4[cc[1] & 0x3f]; |
size += _pcre_utf8_table4[cc[1] & 0x3f]; |
| 3224 |
} |
} |
| 3225 |
else |
else |
| 3226 |
#endif |
#endif |
| 3227 |
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) |
| 3228 |
size = 0; |
size = 0; |
| 3835 |
A - Push the current STR_PTR. Needed for restoring the STR_PTR |
A - Push the current STR_PTR. Needed for restoring the STR_PTR |
| 3836 |
before the next alternative. Not pushed if there are no alternatives. |
before the next alternative. Not pushed if there are no alternatives. |
| 3837 |
M - Any values pushed by the current alternative. Can be empty, or anything. |
M - Any values pushed by the current alternative. Can be empty, or anything. |
| 3838 |
C - Push the previous OVECTOR(i), OVECTOR(i+1), MAX_INDEX and OVECTOR_PRIV(i) to the stack. |
C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack. |
| 3839 |
L - Push the previous local (pointed by localptr) to the stack |
L - Push the previous local (pointed by localptr) to the stack |
| 3840 |
() - opional values stored on the stack |
() - opional values stored on the stack |
| 3841 |
()* - optonal, can be stored multiple times |
()* - optonal, can be stored multiple times |
| 4062 |
else if (opcode == OP_CBRA || opcode == OP_SCBRA) |
else if (opcode == OP_CBRA || opcode == OP_SCBRA) |
| 4063 |
{ |
{ |
| 4064 |
/* Saving the previous values. */ |
/* Saving the previous values. */ |
| 4065 |
allocate_stack(common, 4); |
allocate_stack(common, 3); |
| 4066 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
| 4067 |
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)); |
| 4068 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
| 4069 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
| 4070 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0); |
|
| 4071 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); |
| 4072 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); |
|
/* Update MAX_INDEX if necessary. */ |
|
|
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1)); |
|
| 4073 |
} |
} |
| 4074 |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
| 4075 |
{ |
{ |
| 4278 |
FALLBACK_AS(bracketpos_fallback)->framesize = framesize; |
FALLBACK_AS(bracketpos_fallback)->framesize = framesize; |
| 4279 |
if (framesize < 0) |
if (framesize < 0) |
| 4280 |
{ |
{ |
| 4281 |
stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1; |
stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1; |
| 4282 |
if (!zero) |
if (!zero) |
| 4283 |
stacksize++; |
stacksize++; |
| 4284 |
FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize; |
FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize; |
| 4291 |
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)); |
| 4292 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
| 4293 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0); |
|
| 4294 |
} |
} |
| 4295 |
else |
else |
| 4296 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 4348 |
{ |
{ |
| 4349 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); |
| 4350 |
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); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
|
|
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1)); |
|
| 4351 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
| 4352 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 4353 |
} |
} |
| 4354 |
else |
else |
| 4355 |
{ |
{ |
| 4372 |
if (!zero) |
if (!zero) |
| 4373 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); |
| 4374 |
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); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
|
|
add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1)); |
|
| 4375 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); |
| 4376 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 4377 |
} |
} |
| 4378 |
else |
else |
| 4379 |
{ |
{ |
| 4753 |
static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc) |
static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc) |
| 4754 |
{ |
{ |
| 4755 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
|
struct sljit_jump *jump; |
|
| 4756 |
int offset = GET2(cc, 1); |
int offset = GET2(cc, 1); |
| 4757 |
|
|
| 4758 |
/* Data will be discarded anyway... */ |
/* Data will be discarded anyway... */ |
| 4761 |
|
|
| 4762 |
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)); |
| 4763 |
offset <<= 1; |
offset <<= 1; |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
|
| 4764 |
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); |
| 4765 |
offset = (offset >> 1) + 1; |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
|
jump = CMP(SLJIT_C_GREATER_EQUAL, MAX_INDEX, 0, SLJIT_IMM, offset); |
|
|
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, offset); |
|
|
JUMPHERE(jump); |
|
| 4766 |
return cc + 3; |
return cc + 3; |
| 4767 |
} |
} |
| 4768 |
|
|
| 5529 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 5530 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 5531 |
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); |
| 5532 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(3)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2)); |
| 5533 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
free_stack(common, 3); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); |
|
|
free_stack(common, 4); |
|
| 5534 |
} |
} |
| 5535 |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
else if (opcode == OP_SBRA || opcode == OP_SCOND) |
| 5536 |
{ |
{ |
| 5619 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); |
| 5620 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
| 5621 |
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); |
|
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); |
|
| 5622 |
} |
} |
| 5623 |
set_jumps(current->topfallbacks, LABEL()); |
set_jumps(current->topfallbacks, LABEL()); |
| 5624 |
free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); |
free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize); |
| 5945 |
common->nltype = NLTYPE_FIXED; |
common->nltype = NLTYPE_FIXED; |
| 5946 |
switch(re->options & PCRE_NEWLINE_BITS) |
switch(re->options & PCRE_NEWLINE_BITS) |
| 5947 |
{ |
{ |
| 5948 |
case 0: common->newline = NEWLINE; break; /* Compile-time default */ |
case 0: |
| 5949 |
|
/* Compile-time default */ |
| 5950 |
|
switch (NEWLINE) |
| 5951 |
|
{ |
| 5952 |
|
case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; |
| 5953 |
|
case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; |
| 5954 |
|
default: common->newline = NEWLINE; break; |
| 5955 |
|
} |
| 5956 |
|
break; |
| 5957 |
case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; |
case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break; |
| 5958 |
case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; |
case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break; |
| 5959 |
case PCRE_NEWLINE_CR+ |
case PCRE_NEWLINE_CR+ |
| 6058 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if ((re->flags & PCRE_REQCHSET) != 0) |
| 6059 |
reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0); |
reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0); |
| 6060 |
|
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); |
|
| 6061 |
/* Store the current STR_PTR in OVECTOR(0). */ |
/* Store the current STR_PTR in OVECTOR(0). */ |
| 6062 |
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); |
| 6063 |
/* Copy the limit of allowed recursions. */ |
/* Copy the limit of allowed recursions. */ |
| 6064 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, TMP1, 0); |
OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); |
| 6065 |
|
|
| 6066 |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
| 6067 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6079 |
set_jumps(common->accept, common->acceptlabel); |
set_jumps(common->accept, common->acceptlabel); |
| 6080 |
|
|
| 6081 |
/* This means we have a match. Update the ovector. */ |
/* This means we have a match. Update the ovector. */ |
| 6082 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); |
copy_ovector(common, re->top_bracket + 1); |
|
|
|
| 6083 |
leave = LABEL(); |
leave = LABEL(); |
|
copy_ovector(common); |
|
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0); |
|
| 6084 |
sljit_emit_return(compiler, SLJIT_UNUSED, 0); |
sljit_emit_return(compiler, SLJIT_UNUSED, 0); |
| 6085 |
|
|
| 6086 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
| 6129 |
JUMPHERE(reqbyte_notfound); |
JUMPHERE(reqbyte_notfound); |
| 6130 |
/* Copy OVECTOR(1) to OVECTOR(0) */ |
/* Copy OVECTOR(1) to OVECTOR(0) */ |
| 6131 |
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)); |
| 6132 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
| 6133 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 6134 |
|
|
| 6135 |
flush_stubs(common); |
flush_stubs(common); |
| 6182 |
/* Allocation failed. */ |
/* Allocation failed. */ |
| 6183 |
JUMPHERE(alloc_error); |
JUMPHERE(alloc_error); |
| 6184 |
/* 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. */ |
| 6185 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); |
| 6186 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 6187 |
|
|
| 6188 |
/* Call limit reached. */ |
/* Call limit reached. */ |
| 6189 |
set_jumps(common->calllimit, LABEL()); |
set_jumps(common->calllimit, LABEL()); |
| 6190 |
OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
| 6191 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 6192 |
|
|
| 6193 |
if (common->revertframes != NULL) |
if (common->revertframes != NULL) |
| 6372 |
{ |
{ |
| 6373 |
executable_function *function; |
executable_function *function; |
| 6374 |
if (extra != NULL && |
if (extra != NULL && |
| 6375 |
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
| 6376 |
extra->executable_jit != NULL) |
extra->executable_jit != NULL) |
| 6377 |
{ |
{ |
| 6378 |
function = (executable_function*)extra->executable_jit; |
function = (executable_function*)extra->executable_jit; |
| 6383 |
|
|
| 6384 |
#else /* SUPPORT_JIT */ |
#else /* SUPPORT_JIT */ |
| 6385 |
|
|
| 6386 |
/* 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 |
| 6387 |
being compiled. */ |
being compiled. */ |
| 6388 |
|
|
| 6389 |
PCRE_EXP_DECL pcre_jit_stack * |
PCRE_EXP_DECL pcre_jit_stack * |