| 162 |
pcre_uint8 notempty_atstart; |
pcre_uint8 notempty_atstart; |
| 163 |
} jit_arguments; |
} jit_arguments; |
| 164 |
|
|
| 165 |
typedef struct executable_function { |
typedef struct executable_functions { |
| 166 |
void *executable_func; |
void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; |
| 167 |
PUBL(jit_callback) callback; |
PUBL(jit_callback) callback; |
| 168 |
void *userdata; |
void *userdata; |
| 169 |
sljit_uw executable_size; |
sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; |
| 170 |
} executable_function; |
} executable_functions; |
| 171 |
|
|
| 172 |
typedef struct jump_list { |
typedef struct jump_list { |
| 173 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 270 |
typedef struct compiler_common { |
typedef struct compiler_common { |
| 271 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
| 272 |
pcre_uchar *start; |
pcre_uchar *start; |
| 273 |
|
|
| 274 |
|
/* Local stack area size and variable pointers. */ |
| 275 |
int localsize; |
int localsize; |
| 276 |
int *localptrs; |
int *localptrs; |
| 277 |
|
int cbraptr; |
| 278 |
|
/* OVector starting point. Must be divisible by 2. */ |
| 279 |
|
int ovector_start; |
| 280 |
|
/* Last known position of the requested byte. */ |
| 281 |
|
int req_char_ptr; |
| 282 |
|
/* Head of the last recursion. */ |
| 283 |
|
int recursive_head; |
| 284 |
|
/* First inspected character for partial matching. */ |
| 285 |
|
int start_used_ptr; |
| 286 |
|
/* Starting pointer for partial soft matches. */ |
| 287 |
|
int hit_start; |
| 288 |
|
/* End pointer of the first line. */ |
| 289 |
|
int first_line_end; |
| 290 |
|
|
| 291 |
|
/* Other */ |
| 292 |
const pcre_uint8 *fcc; |
const pcre_uint8 *fcc; |
| 293 |
sljit_w lcc; |
sljit_w lcc; |
| 294 |
int cbraptr; |
int mode; |
| 295 |
int nltype; |
int nltype; |
| 296 |
int newline; |
int newline; |
| 297 |
int bsr_nltype; |
int bsr_nltype; |
| 300 |
sljit_uw name_table; |
sljit_uw name_table; |
| 301 |
sljit_w name_count; |
sljit_w name_count; |
| 302 |
sljit_w name_entry_size; |
sljit_w name_entry_size; |
| 303 |
|
|
| 304 |
|
/* Labels and jump lists. */ |
| 305 |
|
struct sljit_label *partialmatchlabel; |
| 306 |
struct sljit_label *acceptlabel; |
struct sljit_label *acceptlabel; |
| 307 |
stub_list *stubs; |
stub_list *stubs; |
| 308 |
recurse_entry *entries; |
recurse_entry *entries; |
| 309 |
recurse_entry *currententry; |
recurse_entry *currententry; |
| 310 |
|
jump_list *partialmatch; |
| 311 |
jump_list *accept; |
jump_list *accept; |
| 312 |
jump_list *calllimit; |
jump_list *calllimit; |
| 313 |
jump_list *stackalloc; |
jump_list *stackalloc; |
| 397 |
/* Two local variables for possessive quantifiers (char1 cannot use them). */ |
/* Two local variables for possessive quantifiers (char1 cannot use them). */ |
| 398 |
#define POSSESSIVE0 (2 * sizeof(sljit_w)) |
#define POSSESSIVE0 (2 * sizeof(sljit_w)) |
| 399 |
#define POSSESSIVE1 (3 * sizeof(sljit_w)) |
#define POSSESSIVE1 (3 * sizeof(sljit_w)) |
|
/* Head of the last recursion. */ |
|
|
#define RECURSIVE_HEAD (4 * sizeof(sljit_w)) |
|
| 400 |
/* Max limit of recursions. */ |
/* Max limit of recursions. */ |
| 401 |
#define CALL_LIMIT (5 * sizeof(sljit_w)) |
#define CALL_LIMIT (4 * sizeof(sljit_w)) |
|
/* Last known position of the requested byte. */ |
|
|
#define REQ_CHAR_PTR (6 * sizeof(sljit_w)) |
|
|
/* End pointer of the first line. */ |
|
|
#define FIRSTLINE_END (7 * sizeof(sljit_w)) |
|
| 402 |
/* The output vector is stored on the stack, and contains pointers |
/* The output vector is stored on the stack, and contains pointers |
| 403 |
to characters. The vector data is divided into two groups: the first |
to characters. The vector data is divided into two groups: the first |
| 404 |
group contains the start / end character pointers, and the second is |
group contains the start / end character pointers, and the second is |
| 405 |
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. */ |
| 406 |
#define OVECTOR_START (8 * sizeof(sljit_w)) |
#define OVECTOR_START (common->ovector_start) |
| 407 |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) |
| 408 |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) |
| 409 |
#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) |
#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) |
| 692 |
cc += 1 + LINK_SIZE; |
cc += 1 + LINK_SIZE; |
| 693 |
break; |
break; |
| 694 |
|
|
| 695 |
|
case OP_RECURSE: |
| 696 |
|
/* Set its value only once. */ |
| 697 |
|
if (common->recursive_head == 0) |
| 698 |
|
{ |
| 699 |
|
common->recursive_head = common->ovector_start; |
| 700 |
|
common->ovector_start += sizeof(sljit_w); |
| 701 |
|
} |
| 702 |
|
cc += 1 + LINK_SIZE; |
| 703 |
|
break; |
| 704 |
|
|
| 705 |
default: |
default: |
| 706 |
cc = next_opcode(common, cc); |
cc = next_opcode(common, cc); |
| 707 |
if (cc == NULL) |
if (cc == NULL) |
| 969 |
switch(status) |
switch(status) |
| 970 |
{ |
{ |
| 971 |
case start: |
case start: |
| 972 |
SLJIT_ASSERT(save); |
SLJIT_ASSERT(save && common->recursive_head != 0); |
| 973 |
count = 1; |
count = 1; |
| 974 |
srcw[0] = RECURSIVE_HEAD; |
srcw[0] = common->recursive_head; |
| 975 |
status = loop; |
status = loop; |
| 976 |
break; |
break; |
| 977 |
|
|
| 1293 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
| 1294 |
} |
} |
| 1295 |
|
|
| 1296 |
|
static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave) |
| 1297 |
|
{ |
| 1298 |
|
DEFINE_COMPILER; |
| 1299 |
|
|
| 1300 |
|
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); |
| 1301 |
|
SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); |
| 1302 |
|
|
| 1303 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); |
| 1304 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); |
| 1305 |
|
OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); |
| 1306 |
|
CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave); |
| 1307 |
|
|
| 1308 |
|
/* Store match begin and end. */ |
| 1309 |
|
OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 1310 |
|
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); |
| 1311 |
|
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); |
| 1312 |
|
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); |
| 1313 |
|
#ifdef COMPILE_PCRE16 |
| 1314 |
|
OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); |
| 1315 |
|
#endif |
| 1316 |
|
OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); |
| 1317 |
|
|
| 1318 |
|
OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); |
| 1319 |
|
#ifdef COMPILE_PCRE16 |
| 1320 |
|
OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); |
| 1321 |
|
#endif |
| 1322 |
|
OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); |
| 1323 |
|
|
| 1324 |
|
JUMPTO(SLJIT_JUMP, leave); |
| 1325 |
|
} |
| 1326 |
|
|
| 1327 |
|
static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) |
| 1328 |
|
{ |
| 1329 |
|
/* May destroy TMP1. */ |
| 1330 |
|
DEFINE_COMPILER; |
| 1331 |
|
struct sljit_jump *jump; |
| 1332 |
|
|
| 1333 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
| 1334 |
|
{ |
| 1335 |
|
/* The value of -1 must be kept for start_used_ptr! */ |
| 1336 |
|
OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1); |
| 1337 |
|
/* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting |
| 1338 |
|
is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */ |
| 1339 |
|
jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0); |
| 1340 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 1341 |
|
JUMPHERE(jump); |
| 1342 |
|
} |
| 1343 |
|
else if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
| 1344 |
|
{ |
| 1345 |
|
jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 1346 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 1347 |
|
JUMPHERE(jump); |
| 1348 |
|
} |
| 1349 |
|
} |
| 1350 |
|
|
| 1351 |
static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) |
static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc) |
| 1352 |
{ |
{ |
| 1353 |
/* Detects if the character has an othercase. */ |
/* Detects if the character has an othercase. */ |
| 1469 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
| 1470 |
} |
} |
| 1471 |
|
|
| 1472 |
static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks) |
static void check_partial(compiler_common *common, BOOL force) |
| 1473 |
{ |
{ |
| 1474 |
|
/* Checks whether a partial matching is occured. Does not modify registers. */ |
| 1475 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 1476 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
struct sljit_jump *jump = NULL; |
| 1477 |
|
|
| 1478 |
|
SLJIT_ASSERT(!force || common->mode != JIT_COMPILE); |
| 1479 |
|
|
| 1480 |
|
if (common->mode == JIT_COMPILE) |
| 1481 |
|
return; |
| 1482 |
|
|
| 1483 |
|
if (!force) |
| 1484 |
|
jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 1485 |
|
else if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
| 1486 |
|
jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); |
| 1487 |
|
|
| 1488 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
| 1489 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
| 1490 |
|
else |
| 1491 |
|
{ |
| 1492 |
|
if (common->partialmatchlabel != NULL) |
| 1493 |
|
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
| 1494 |
|
else |
| 1495 |
|
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
| 1496 |
|
} |
| 1497 |
|
|
| 1498 |
|
if (jump != NULL) |
| 1499 |
|
JUMPHERE(jump); |
| 1500 |
|
} |
| 1501 |
|
|
| 1502 |
|
static struct sljit_jump *check_str_end(compiler_common *common) |
| 1503 |
|
{ |
| 1504 |
|
/* Does not affect registers. Usually used in a tight spot. */ |
| 1505 |
|
DEFINE_COMPILER; |
| 1506 |
|
struct sljit_jump *jump; |
| 1507 |
|
struct sljit_jump *nohit; |
| 1508 |
|
struct sljit_jump *return_value; |
| 1509 |
|
|
| 1510 |
|
if (common->mode == JIT_COMPILE) |
| 1511 |
|
return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
| 1512 |
|
|
| 1513 |
|
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
| 1514 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
| 1515 |
|
{ |
| 1516 |
|
nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 1517 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
| 1518 |
|
JUMPHERE(nohit); |
| 1519 |
|
return_value = JUMP(SLJIT_JUMP); |
| 1520 |
|
} |
| 1521 |
|
else |
| 1522 |
|
{ |
| 1523 |
|
return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 1524 |
|
if (common->partialmatchlabel != NULL) |
| 1525 |
|
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
| 1526 |
|
else |
| 1527 |
|
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
| 1528 |
|
} |
| 1529 |
|
JUMPHERE(jump); |
| 1530 |
|
return return_value; |
| 1531 |
|
} |
| 1532 |
|
|
| 1533 |
|
static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks) |
| 1534 |
|
{ |
| 1535 |
|
DEFINE_COMPILER; |
| 1536 |
|
struct sljit_jump *jump; |
| 1537 |
|
|
| 1538 |
|
if (common->mode == JIT_COMPILE) |
| 1539 |
|
{ |
| 1540 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
| 1541 |
|
return; |
| 1542 |
|
} |
| 1543 |
|
|
| 1544 |
|
/* Partial matching mode. */ |
| 1545 |
|
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
| 1546 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0)); |
| 1547 |
|
if (common->mode == JIT_PARTIAL_SOFT_COMPILE) |
| 1548 |
|
{ |
| 1549 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
| 1550 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
| 1551 |
|
} |
| 1552 |
|
else |
| 1553 |
|
{ |
| 1554 |
|
if (common->partialmatchlabel != NULL) |
| 1555 |
|
JUMPTO(SLJIT_JUMP, common->partialmatchlabel); |
| 1556 |
|
else |
| 1557 |
|
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP)); |
| 1558 |
|
} |
| 1559 |
|
JUMPHERE(jump); |
| 1560 |
} |
} |
| 1561 |
|
|
| 1562 |
static void read_char(compiler_common *common) |
static void read_char(compiler_common *common) |
| 1901 |
if (firstline) |
if (firstline) |
| 1902 |
{ |
{ |
| 1903 |
/* Search for the end of the first line. */ |
/* Search for the end of the first line. */ |
| 1904 |
|
SLJIT_ASSERT(common->first_line_end != 0); |
| 1905 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); |
| 1906 |
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); |
| 1907 |
|
|
| 1908 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 1909 |
{ |
{ |
| 1914 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
| 1915 |
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); |
| 1916 |
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); |
| 1917 |
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)); |
| 1918 |
} |
} |
| 1919 |
else |
else |
| 1920 |
{ |
{ |
| 1921 |
end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
| 1922 |
mainloop = LABEL(); |
mainloop = LABEL(); |
| 1923 |
/* Continual stores does not cause data dependency. */ |
/* Continual stores does not cause data dependency. */ |
| 1924 |
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); |
| 1925 |
read_char(common); |
read_char(common); |
| 1926 |
check_newlinechar(common, common->nltype, &newline, TRUE); |
check_newlinechar(common, common->nltype, &newline, TRUE); |
| 1927 |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); |
| 1928 |
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); |
| 1929 |
set_jumps(newline, LABEL()); |
set_jumps(newline, LABEL()); |
| 1930 |
} |
} |
| 1931 |
|
|
| 2008 |
if (firstline) |
if (firstline) |
| 2009 |
{ |
{ |
| 2010 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
| 2011 |
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); |
| 2012 |
} |
} |
| 2013 |
|
|
| 2014 |
start = LABEL(); |
start = LABEL(); |
| 2086 |
if (firstline) |
if (firstline) |
| 2087 |
{ |
{ |
| 2088 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
| 2089 |
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); |
| 2090 |
} |
} |
| 2091 |
|
|
| 2092 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 2170 |
if (firstline) |
if (firstline) |
| 2171 |
{ |
{ |
| 2172 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); |
| 2173 |
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); |
| 2174 |
} |
} |
| 2175 |
|
|
| 2176 |
start = LABEL(); |
start = LABEL(); |
| 2235 |
struct sljit_jump *notfound; |
struct sljit_jump *notfound; |
| 2236 |
pcre_uchar oc, bit; |
pcre_uchar oc, bit; |
| 2237 |
|
|
| 2238 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR); |
SLJIT_ASSERT(common->req_char_ptr != 0); |
| 2239 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); |
| 2240 |
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); |
| 2241 |
toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); |
toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0); |
| 2242 |
alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); |
alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0); |
| 2281 |
JUMPHERE(found); |
JUMPHERE(found); |
| 2282 |
if (foundoc) |
if (foundoc) |
| 2283 |
JUMPHERE(foundoc); |
JUMPHERE(foundoc); |
| 2284 |
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); |
| 2285 |
JUMPHERE(alreadyfound); |
JUMPHERE(alreadyfound); |
| 2286 |
JUMPHERE(toolong); |
JUMPHERE(toolong); |
| 2287 |
return notfound; |
return notfound; |
| 2328 |
static void check_wordboundary(compiler_common *common) |
static void check_wordboundary(compiler_common *common) |
| 2329 |
{ |
{ |
| 2330 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 2331 |
struct sljit_jump *beginend; |
struct sljit_jump *skipread; |
| 2332 |
#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF |
#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF |
| 2333 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 2334 |
#endif |
#endif |
| 2340 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
| 2341 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 2342 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0); |
| 2343 |
beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); |
skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0); |
| 2344 |
skip_char_back(common); |
skip_char_back(common); |
| 2345 |
|
check_start_used_ptr(common); |
| 2346 |
read_char(common); |
read_char(common); |
| 2347 |
|
|
| 2348 |
/* Testing char type. */ |
/* Testing char type. */ |
| 2383 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 2384 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
| 2385 |
} |
} |
| 2386 |
JUMPHERE(beginend); |
JUMPHERE(skipread); |
| 2387 |
|
|
| 2388 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
| 2389 |
beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
skipread = check_str_end(common); |
| 2390 |
peek_char(common); |
peek_char(common); |
| 2391 |
|
|
| 2392 |
/* Testing char type. This is a code duplication. */ |
/* Testing char type. This is a code duplication. */ |
| 2427 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 2428 |
#endif /* COMPILE_PCRE8 */ |
#endif /* COMPILE_PCRE8 */ |
| 2429 |
} |
} |
| 2430 |
JUMPHERE(beginend); |
JUMPHERE(skipread); |
| 2431 |
|
|
| 2432 |
OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); |
OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1); |
| 2433 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
| 2618 |
while (src1 < end1) |
while (src1 < end1) |
| 2619 |
{ |
{ |
| 2620 |
if (src2 >= end2) |
if (src2 >= end2) |
| 2621 |
return 0; |
return (pcre_uchar*)1; |
| 2622 |
GETCHARINC(c1, src1); |
GETCHARINC(c1, src1); |
| 2623 |
GETCHARINC(c2, src2); |
GETCHARINC(c2, src2); |
| 2624 |
if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0; |
if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL; |
| 2625 |
} |
} |
| 2626 |
return src2; |
return src2; |
| 2627 |
} |
} |
| 2827 |
unsigned int charoffset; |
unsigned int charoffset; |
| 2828 |
|
|
| 2829 |
/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ |
/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ |
| 2830 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 2831 |
read_char(common); |
read_char(common); |
| 2832 |
|
|
| 2833 |
if ((*cc++ & XCL_MAP) != 0) |
if ((*cc++ & XCL_MAP) != 0) |
| 3181 |
|
|
| 3182 |
case OP_NOT_DIGIT: |
case OP_NOT_DIGIT: |
| 3183 |
case OP_DIGIT: |
case OP_DIGIT: |
| 3184 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3185 |
read_char8_type(common); |
read_char8_type(common); |
| 3186 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); |
| 3187 |
add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
| 3189 |
|
|
| 3190 |
case OP_NOT_WHITESPACE: |
case OP_NOT_WHITESPACE: |
| 3191 |
case OP_WHITESPACE: |
case OP_WHITESPACE: |
| 3192 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3193 |
read_char8_type(common); |
read_char8_type(common); |
| 3194 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); |
| 3195 |
add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
| 3197 |
|
|
| 3198 |
case OP_NOT_WORDCHAR: |
case OP_NOT_WORDCHAR: |
| 3199 |
case OP_WORDCHAR: |
case OP_WORDCHAR: |
| 3200 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3201 |
read_char8_type(common); |
read_char8_type(common); |
| 3202 |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); |
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); |
| 3203 |
add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); |
| 3204 |
return cc; |
return cc; |
| 3205 |
|
|
| 3206 |
case OP_ANY: |
case OP_ANY: |
| 3207 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3208 |
read_char(common); |
read_char(common); |
| 3209 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 3210 |
{ |
{ |
| 3211 |
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); |
| 3212 |
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
| 3213 |
|
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
| 3214 |
|
else |
| 3215 |
|
jump[1] = check_str_end(common); |
| 3216 |
|
|
| 3217 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
| 3218 |
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)); |
| 3219 |
JUMPHERE(jump[1]); |
if (jump[1] != NULL) |
| 3220 |
|
JUMPHERE(jump[1]); |
| 3221 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3222 |
} |
} |
| 3223 |
else |
else |
| 3225 |
return cc; |
return cc; |
| 3226 |
|
|
| 3227 |
case OP_ALLANY: |
case OP_ALLANY: |
| 3228 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3229 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3230 |
if (common->utf) |
if (common->utf) |
| 3231 |
{ |
{ |
| 3253 |
return cc; |
return cc; |
| 3254 |
|
|
| 3255 |
case OP_ANYBYTE: |
case OP_ANYBYTE: |
| 3256 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3257 |
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)); |
| 3258 |
return cc; |
return cc; |
| 3259 |
|
|
| 3272 |
#endif |
#endif |
| 3273 |
|
|
| 3274 |
case OP_ANYNL: |
case OP_ANYNL: |
| 3275 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3276 |
read_char(common); |
read_char(common); |
| 3277 |
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); |
| 3278 |
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
/* We don't need to handle soft partial matching case. */ |
| 3279 |
|
if (common->mode != JIT_PARTIAL_HARD_COMPILE) |
| 3280 |
|
jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); |
| 3281 |
|
else |
| 3282 |
|
jump[1] = check_str_end(common); |
| 3283 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); |
| 3284 |
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); |
| 3285 |
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)); |
| 3293 |
|
|
| 3294 |
case OP_NOT_HSPACE: |
case OP_NOT_HSPACE: |
| 3295 |
case OP_HSPACE: |
case OP_HSPACE: |
| 3296 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3297 |
read_char(common); |
read_char(common); |
| 3298 |
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); |
| 3299 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 3301 |
|
|
| 3302 |
case OP_NOT_VSPACE: |
case OP_NOT_VSPACE: |
| 3303 |
case OP_VSPACE: |
case OP_VSPACE: |
| 3304 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3305 |
read_char(common); |
read_char(common); |
| 3306 |
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); |
| 3307 |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); |
| 3309 |
|
|
| 3310 |
#ifdef SUPPORT_UCP |
#ifdef SUPPORT_UCP |
| 3311 |
case OP_EXTUNI: |
case OP_EXTUNI: |
| 3312 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3313 |
read_char(common); |
read_char(common); |
| 3314 |
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); |
| 3315 |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); |
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); |
| 3325 |
|
|
| 3326 |
OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
| 3327 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3328 |
|
if (common->mode == JIT_PARTIAL_HARD_COMPILE) |
| 3329 |
|
{ |
| 3330 |
|
jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); |
| 3331 |
|
/* Since we successfully read a char above, partial matching must occure. */ |
| 3332 |
|
check_partial(common, TRUE); |
| 3333 |
|
JUMPHERE(jump[0]); |
| 3334 |
|
} |
| 3335 |
return cc; |
return cc; |
| 3336 |
#endif |
#endif |
| 3337 |
|
|
| 3338 |
case OP_EODN: |
case OP_EODN: |
| 3339 |
|
/* Requires rather complex checks. */ |
| 3340 |
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); |
| 3341 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 3342 |
{ |
{ |
| 3343 |
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)); |
| 3344 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
| 3345 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
if (common->mode == JIT_COMPILE) |
| 3346 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0)); |
| 3347 |
|
else |
| 3348 |
|
{ |
| 3349 |
|
jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); |
| 3350 |
|
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); |
| 3351 |
|
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); |
| 3352 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); |
| 3353 |
|
COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); |
| 3354 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL)); |
| 3355 |
|
check_partial(common, TRUE); |
| 3356 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
| 3357 |
|
JUMPHERE(jump[1]); |
| 3358 |
|
} |
| 3359 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
| 3360 |
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)); |
| 3361 |
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)); |
| 3400 |
JUMPHERE(jump[3]); |
JUMPHERE(jump[3]); |
| 3401 |
} |
} |
| 3402 |
JUMPHERE(jump[0]); |
JUMPHERE(jump[0]); |
| 3403 |
|
check_partial(common, FALSE); |
| 3404 |
return cc; |
return cc; |
| 3405 |
|
|
| 3406 |
case OP_EOD: |
case OP_EOD: |
| 3407 |
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)); |
| 3408 |
|
check_partial(common, FALSE); |
| 3409 |
return cc; |
return cc; |
| 3410 |
|
|
| 3411 |
case OP_CIRC: |
case OP_CIRC: |
| 3425 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
| 3426 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3427 |
|
|
| 3428 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); |
| 3429 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 3430 |
{ |
{ |
| 3431 |
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); |
| 3452 |
if (!common->endonly) |
if (!common->endonly) |
| 3453 |
compile_char1_hotpath(common, OP_EODN, cc, fallbacks); |
compile_char1_hotpath(common, OP_EODN, cc, fallbacks); |
| 3454 |
else |
else |
| 3455 |
|
{ |
| 3456 |
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)); |
| 3457 |
|
check_partial(common, FALSE); |
| 3458 |
|
} |
| 3459 |
return cc; |
return cc; |
| 3460 |
|
|
| 3461 |
case OP_DOLLM: |
case OP_DOLLM: |
| 3463 |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); |
| 3464 |
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)); |
| 3465 |
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)); |
| 3466 |
|
check_partial(common, FALSE); |
| 3467 |
jump[0] = JUMP(SLJIT_JUMP); |
jump[0] = JUMP(SLJIT_JUMP); |
| 3468 |
JUMPHERE(jump[1]); |
JUMPHERE(jump[1]); |
| 3469 |
|
|
| 3470 |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
if (common->nltype == NLTYPE_FIXED && common->newline > 255) |
| 3471 |
{ |
{ |
| 3472 |
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)); |
|
| 3473 |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); |
| 3474 |
|
if (common->mode == JIT_COMPILE) |
| 3475 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0)); |
| 3476 |
|
else |
| 3477 |
|
{ |
| 3478 |
|
jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0); |
| 3479 |
|
/* STR_PTR = STR_END - IN_UCHARS(1) */ |
| 3480 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); |
| 3481 |
|
check_partial(common, TRUE); |
| 3482 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
| 3483 |
|
JUMPHERE(jump[1]); |
| 3484 |
|
} |
| 3485 |
|
|
| 3486 |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); |
| 3487 |
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)); |
| 3488 |
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)); |
| 3501 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3502 |
if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); |
if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); |
| 3503 |
#endif |
#endif |
| 3504 |
if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) |
if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) |
| 3505 |
{ |
{ |
| 3506 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
| 3507 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
| 3513 |
#endif |
#endif |
| 3514 |
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks); |
return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks); |
| 3515 |
} |
} |
| 3516 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3517 |
read_char(common); |
read_char(common); |
| 3518 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3519 |
if (common->utf) |
if (common->utf) |
| 3523 |
else |
else |
| 3524 |
#endif |
#endif |
| 3525 |
c = *cc; |
c = *cc; |
| 3526 |
|
if (type == OP_CHAR || !char_has_othercase(common, cc)) |
| 3527 |
|
{ |
| 3528 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); |
| 3529 |
|
return cc + length; |
| 3530 |
|
} |
| 3531 |
|
oc = char_othercase(common, c); |
| 3532 |
|
bit = c ^ oc; |
| 3533 |
|
if (ispowerof2(bit)) |
| 3534 |
|
{ |
| 3535 |
|
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); |
| 3536 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); |
| 3537 |
|
return cc + length; |
| 3538 |
|
} |
| 3539 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); |
| 3540 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
| 3541 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); |
| 3545 |
|
|
| 3546 |
case OP_NOT: |
case OP_NOT: |
| 3547 |
case OP_NOTI: |
case OP_NOTI: |
| 3548 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3549 |
length = 1; |
length = 1; |
| 3550 |
#ifdef SUPPORT_UTF |
#ifdef SUPPORT_UTF |
| 3551 |
if (common->utf) |
if (common->utf) |
| 3606 |
|
|
| 3607 |
case OP_CLASS: |
case OP_CLASS: |
| 3608 |
case OP_NCLASS: |
case OP_NCLASS: |
| 3609 |
check_input_end(common, fallbacks); |
fallback_at_str_end(common, fallbacks); |
| 3610 |
read_char(common); |
read_char(common); |
| 3611 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
| 3612 |
jump[0] = NULL; |
jump[0] = NULL; |
| 3656 |
skip_char_back(common); |
skip_char_back(common); |
| 3657 |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); |
| 3658 |
JUMPTO(SLJIT_C_NOT_ZERO, label); |
JUMPTO(SLJIT_C_NOT_ZERO, label); |
|
return cc + LINK_SIZE; |
|
| 3659 |
} |
} |
| 3660 |
|
else |
| 3661 |
#endif |
#endif |
| 3662 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
{ |
| 3663 |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); |
| 3664 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); |
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); |
| 3665 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0)); |
| 3666 |
|
} |
| 3667 |
|
check_start_used_ptr(common); |
| 3668 |
return cc + LINK_SIZE; |
return cc + LINK_SIZE; |
| 3669 |
} |
} |
| 3670 |
SLJIT_ASSERT_STOP(); |
SLJIT_ASSERT_STOP(); |
| 3747 |
{ |
{ |
| 3748 |
if (fallbacks == NULL) |
if (fallbacks == NULL) |
| 3749 |
{ |
{ |
| 3750 |
|
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
| 3751 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
| 3752 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); |
| 3753 |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
| 3789 |
} \ |
} \ |
| 3790 |
while (0) |
while (0) |
| 3791 |
|
|
| 3792 |
#define FALLBACK_AS(type) ((type*)fallback) |
#define FALLBACK_AS(type) ((type *)fallback) |
| 3793 |
|
|
| 3794 |
static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail) |
static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail) |
| 3795 |
{ |
{ |
| 3796 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
| 3797 |
int offset = GET2(cc, 1) << 1; |
int offset = GET2(cc, 1) << 1; |
| 3798 |
struct sljit_jump *jump = NULL; |
struct sljit_jump *jump = NULL; |
| 3799 |
|
struct sljit_jump *partial; |
| 3800 |
|
struct sljit_jump *nopartial; |
| 3801 |
|
|
| 3802 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
| 3803 |
|
/* OVECTOR(1) contains the "string begin - 1" constant. */ |
| 3804 |
if (withchecks && !common->jscript_compat) |
if (withchecks && !common->jscript_compat) |
| 3805 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
| 3806 |
|
|
| 3818 |
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, ptr), STR_PTR, 0); |
| 3819 |
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)); |
| 3820 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
| 3821 |
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
if (common->mode == JIT_COMPILE) |
| 3822 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); |
| 3823 |
|
else |
| 3824 |
|
{ |
| 3825 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); |
| 3826 |
|
nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); |
| 3827 |
|
check_partial(common, FALSE); |
| 3828 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
| 3829 |
|
JUMPHERE(nopartial); |
| 3830 |
|
} |
| 3831 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); |
| 3832 |
} |
} |
| 3833 |
else |
else |
| 3836 |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); |
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0); |
| 3837 |
if (withchecks) |
if (withchecks) |
| 3838 |
jump = JUMP(SLJIT_C_ZERO); |
jump = JUMP(SLJIT_C_ZERO); |
| 3839 |
|
|
| 3840 |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); |
| 3841 |
|
partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0); |
| 3842 |
|
if (common->mode == JIT_COMPILE) |
| 3843 |
|
add_jump(compiler, fallbacks, partial); |
| 3844 |
|
|
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0)); |
|
| 3845 |
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)); |
| 3846 |
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)); |
| 3847 |
|
|
| 3848 |
|
if (common->mode != JIT_COMPILE) |
| 3849 |
|
{ |
| 3850 |
|
nopartial = JUMP(SLJIT_JUMP); |
| 3851 |
|
JUMPHERE(partial); |
| 3852 |
|
/* TMP2 -= STR_END - STR_PTR */ |
| 3853 |
|
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0); |
| 3854 |
|
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0); |
| 3855 |
|
partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0); |
| 3856 |
|
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); |
| 3857 |
|
add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL)); |
| 3858 |
|
add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); |
| 3859 |
|
JUMPHERE(partial); |
| 3860 |
|
check_partial(common, FALSE); |
| 3861 |
|
add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP)); |
| 3862 |
|
JUMPHERE(nopartial); |
| 3863 |
|
} |
| 3864 |
} |
} |
| 3865 |
|
|
| 3866 |
if (jump != NULL) |
if (jump != NULL) |
| 4343 |
sljit_w no_capture; |
sljit_w no_capture; |
| 4344 |
int i; |
int i; |
| 4345 |
|
|
| 4346 |
locals += OVECTOR_START / sizeof(sljit_w); |
locals += refno & 0xff; |
| 4347 |
|
refno >>= 8; |
| 4348 |
no_capture = locals[1]; |
no_capture = locals[1]; |
| 4349 |
|
|
| 4350 |
for (i = 0; i < name_count; i++) |
for (i = 0; i < name_count; i++) |
| 4744 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
| 4745 |
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); |
| 4746 |
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); |
| 4747 |
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))); |
| 4748 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0); |
| 4749 |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); |
| 4750 |
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)); |
| 4908 |
if (bra == OP_BRAMINZERO) |
if (bra == OP_BRAMINZERO) |
| 4909 |
{ |
{ |
| 4910 |
/* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */ |
/* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */ |
| 4911 |
JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath); |
JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath); |
| 4912 |
if (braminzerojump != NULL) |
if (braminzerojump != NULL) |
| 4913 |
{ |
{ |
| 4914 |
JUMPHERE(braminzerojump); |
JUMPHERE(braminzerojump); |
| 5528 |
|
|
| 5529 |
case OP_CHAR: |
case OP_CHAR: |
| 5530 |
case OP_CHARI: |
case OP_CHARI: |
| 5531 |
cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
if (common->mode == JIT_COMPILE) |
| 5532 |
|
cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
| 5533 |
|
else |
| 5534 |
|
cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks); |
| 5535 |
break; |
break; |
| 5536 |
|
|
| 5537 |
case OP_STAR: |
case OP_STAR: |
| 5724 |
} \ |
} \ |
| 5725 |
while (0) |
while (0) |
| 5726 |
|
|
| 5727 |
#define CURRENT_AS(type) ((type*)current) |
#define CURRENT_AS(type) ((type *)current) |
| 5728 |
|
|
| 5729 |
static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) |
static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current) |
| 5730 |
{ |
{ |
| 6551 |
framesize = 0; |
framesize = 0; |
| 6552 |
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; |
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0; |
| 6553 |
|
|
| 6554 |
SLJIT_ASSERT(common->currententry->entry == NULL); |
SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0); |
| 6555 |
common->currententry->entry = LABEL(); |
common->currententry->entry = LABEL(); |
| 6556 |
set_jumps(common->currententry->calls, common->currententry->entry); |
set_jumps(common->currententry->calls, common->currententry->entry); |
| 6557 |
|
|
| 6559 |
allocate_stack(common, localsize + framesize + alternativesize); |
allocate_stack(common, localsize + framesize + alternativesize); |
| 6560 |
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); |
| 6561 |
copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); |
copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); |
| 6562 |
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); |
| 6563 |
if (needsframe) |
if (needsframe) |
| 6564 |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE); |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE); |
| 6565 |
|
|
| 6601 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
| 6602 |
|
|
| 6603 |
set_jumps(common->accept, LABEL()); |
set_jumps(common->accept, LABEL()); |
| 6604 |
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); |
| 6605 |
if (needsframe) |
if (needsframe) |
| 6606 |
{ |
{ |
| 6607 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
| 6617 |
free_stack(common, localsize + framesize + alternativesize); |
free_stack(common, localsize + framesize + alternativesize); |
| 6618 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); |
| 6619 |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
| 6620 |
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); |
| 6621 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
| 6622 |
} |
} |
| 6623 |
|
|
| 6625 |
#undef CURRENT_AS |
#undef CURRENT_AS |
| 6626 |
|
|
| 6627 |
void |
void |
| 6628 |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra) |
PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode) |
| 6629 |
{ |
{ |
| 6630 |
struct sljit_compiler *compiler; |
struct sljit_compiler *compiler; |
| 6631 |
fallback_common rootfallback; |
fallback_common rootfallback; |
| 6634 |
const pcre_uint8 *tables = re->tables; |
const pcre_uint8 *tables = re->tables; |
| 6635 |
pcre_study_data *study; |
pcre_study_data *study; |
| 6636 |
pcre_uchar *ccend; |
pcre_uchar *ccend; |
| 6637 |
executable_function *function; |
executable_functions *functions; |
| 6638 |
void *executable_func; |
void *executable_func; |
| 6639 |
sljit_uw executable_size; |
sljit_uw executable_size; |
| 6640 |
struct sljit_label *leave; |
struct sljit_label *leave; |
| 6641 |
struct sljit_label *mainloop = NULL; |
struct sljit_label *mainloop = NULL; |
| 6642 |
struct sljit_label *empty_match_found; |
struct sljit_label *empty_match_found; |
| 6643 |
struct sljit_label *empty_match_fallback; |
struct sljit_label *empty_match_fallback; |
| 6644 |
struct sljit_jump *alloc_error; |
struct sljit_jump *jump; |
| 6645 |
struct sljit_jump *reqbyte_notfound = NULL; |
struct sljit_jump *reqbyte_notfound = NULL; |
| 6646 |
struct sljit_jump *empty_match; |
struct sljit_jump *empty_match; |
| 6647 |
|
|
| 6656 |
|
|
| 6657 |
common->compiler = NULL; |
common->compiler = NULL; |
| 6658 |
common->start = rootfallback.cc; |
common->start = rootfallback.cc; |
|
common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); |
|
| 6659 |
common->fcc = tables + fcc_offset; |
common->fcc = tables + fcc_offset; |
| 6660 |
common->lcc = (sljit_w)(tables + lcc_offset); |
common->lcc = (sljit_w)(tables + lcc_offset); |
| 6661 |
|
common->mode = mode; |
| 6662 |
common->nltype = NLTYPE_FIXED; |
common->nltype = NLTYPE_FIXED; |
| 6663 |
switch(re->options & PCRE_NEWLINE_BITS) |
switch(re->options & PCRE_NEWLINE_BITS) |
| 6664 |
{ |
{ |
| 6696 |
common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); |
common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); |
| 6697 |
common->name_count = re->name_count; |
common->name_count = re->name_count; |
| 6698 |
common->name_entry_size = re->name_entry_size; |
common->name_entry_size = re->name_entry_size; |
| 6699 |
|
common->partialmatchlabel = NULL; |
| 6700 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
| 6701 |
common->stubs = NULL; |
common->stubs = NULL; |
| 6702 |
common->entries = NULL; |
common->entries = NULL; |
| 6703 |
common->currententry = NULL; |
common->currententry = NULL; |
| 6704 |
|
common->partialmatch = NULL; |
| 6705 |
common->accept = NULL; |
common->accept = NULL; |
| 6706 |
common->calllimit = NULL; |
common->calllimit = NULL; |
| 6707 |
common->stackalloc = NULL; |
common->stackalloc = NULL; |
| 6728 |
common->getucd = NULL; |
common->getucd = NULL; |
| 6729 |
#endif |
#endif |
| 6730 |
ccend = bracketend(rootfallback.cc); |
ccend = bracketend(rootfallback.cc); |
| 6731 |
|
|
| 6732 |
|
/* Calculate the local space size on the stack. */ |
| 6733 |
|
common->ovector_start = CALL_LIMIT + sizeof(sljit_w); |
| 6734 |
|
common->req_char_ptr = 0; |
| 6735 |
|
common->recursive_head = 0; |
| 6736 |
|
common->start_used_ptr = 0; |
| 6737 |
|
common->hit_start = 0; |
| 6738 |
|
common->first_line_end = 0; |
| 6739 |
|
|
| 6740 |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); |
| 6741 |
common->localsize = get_localspace(common, rootfallback.cc, ccend); |
common->localsize = get_localspace(common, rootfallback.cc, ccend); |
| 6742 |
if (common->localsize < 0) |
if (common->localsize < 0) |
| 6743 |
return; |
return; |
| 6744 |
|
|
| 6745 |
|
/* Checking flags and updating ovector_start. */ |
| 6746 |
|
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0) |
| 6747 |
|
{ |
| 6748 |
|
common->req_char_ptr = common->ovector_start; |
| 6749 |
|
common->ovector_start += sizeof(sljit_w); |
| 6750 |
|
} |
| 6751 |
|
if (mode != JIT_COMPILE) |
| 6752 |
|
{ |
| 6753 |
|
common->start_used_ptr = common->ovector_start; |
| 6754 |
|
common->ovector_start += sizeof(sljit_w); |
| 6755 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
| 6756 |
|
{ |
| 6757 |
|
common->hit_start = common->ovector_start; |
| 6758 |
|
common->ovector_start += sizeof(sljit_w); |
| 6759 |
|
} |
| 6760 |
|
} |
| 6761 |
|
if ((re->options & PCRE_FIRSTLINE) != 0) |
| 6762 |
|
{ |
| 6763 |
|
common->first_line_end = common->ovector_start; |
| 6764 |
|
common->ovector_start += sizeof(sljit_w); |
| 6765 |
|
} |
| 6766 |
|
|
| 6767 |
|
/* Aligning ovector to even number of sljit words. */ |
| 6768 |
|
if ((common->ovector_start & sizeof(sljit_w)) != 0) |
| 6769 |
|
common->ovector_start += sizeof(sljit_w); |
| 6770 |
|
|
| 6771 |
|
common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); |
| 6772 |
common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); |
| 6773 |
if (common->localsize > SLJIT_MAX_LOCAL_SIZE) |
if (common->localsize > SLJIT_MAX_LOCAL_SIZE) |
| 6774 |
return; |
return; |
| 6775 |
common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int)); |
common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int)); |
| 6776 |
if (!common->localptrs) |
if (!common->localptrs) |
| 6777 |
return; |
return; |
| 6778 |
memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int)); |
memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int)); |
| 6791 |
|
|
| 6792 |
/* Register init. */ |
/* Register init. */ |
| 6793 |
reset_ovector(common, (re->top_bracket + 1) * 2); |
reset_ovector(common, (re->top_bracket + 1) * 2); |
| 6794 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0) |
| 6795 |
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); |
| 6796 |
|
|
| 6797 |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); |
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); |
| 6798 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); |
| 6804 |
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)); |
| 6805 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
| 6806 |
|
|
| 6807 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
| 6808 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); |
| 6809 |
|
|
| 6810 |
/* Main part of the matching */ |
/* Main part of the matching */ |
| 6811 |
if ((re->options & PCRE_ANCHORED) == 0) |
if ((re->options & PCRE_ANCHORED) == 0) |
| 6812 |
{ |
{ |
| 6813 |
mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
| 6814 |
/* Forward search if possible. */ |
/* Forward search if possible. */ |
| 6815 |
if ((re->flags & PCRE_FIRSTSET) != 0) |
if ((re->flags & PCRE_FIRSTSET) != 0) |
| 6816 |
fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); |
| 6817 |
else if ((re->flags & PCRE_STARTLINE) != 0) |
else if ((re->flags & PCRE_STARTLINE) != 0) |
| 6818 |
fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); |
fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); |
| 6819 |
else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) |
else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) |
| 6820 |
fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); |
fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); |
| 6821 |
} |
} |
| 6822 |
if ((re->flags & PCRE_REQCHSET) != 0) |
if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0) |
| 6823 |
reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); |
reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0); |
| 6824 |
|
|
| 6825 |
/* Store the current STR_PTR in OVECTOR(0). */ |
/* Store the current STR_PTR in OVECTOR(0). */ |
| 6826 |
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); |
| 6827 |
/* Copy the limit of allowed recursions. */ |
/* Copy the limit of allowed recursions. */ |
| 6828 |
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); |
| 6829 |
|
/* Copy the beginning of the string. */ |
| 6830 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
| 6831 |
|
{ |
| 6832 |
|
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0); |
| 6833 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 6834 |
|
JUMPHERE(jump); |
| 6835 |
|
} |
| 6836 |
|
else if (mode == JIT_PARTIAL_HARD_COMPILE) |
| 6837 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); |
| 6838 |
|
|
| 6839 |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
compile_hotpath(common, rootfallback.cc, ccend, &rootfallback); |
| 6840 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6856 |
leave = LABEL(); |
leave = LABEL(); |
| 6857 |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
| 6858 |
|
|
| 6859 |
|
if (mode != JIT_COMPILE) |
| 6860 |
|
{ |
| 6861 |
|
common->partialmatchlabel = LABEL(); |
| 6862 |
|
set_jumps(common->partialmatch, common->partialmatchlabel); |
| 6863 |
|
return_with_partial_match(common, leave); |
| 6864 |
|
} |
| 6865 |
|
|
| 6866 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
| 6867 |
compile_fallbackpath(common, rootfallback.top); |
compile_fallbackpath(common, rootfallback.top); |
| 6868 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6874 |
|
|
| 6875 |
SLJIT_ASSERT(rootfallback.prev == NULL); |
SLJIT_ASSERT(rootfallback.prev == NULL); |
| 6876 |
|
|
| 6877 |
|
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
| 6878 |
|
{ |
| 6879 |
|
/* Update hit_start only in the first time. */ |
| 6880 |
|
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
| 6881 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr); |
| 6882 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1); |
| 6883 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0); |
| 6884 |
|
JUMPHERE(jump); |
| 6885 |
|
} |
| 6886 |
|
|
| 6887 |
/* Check we have remaining characters. */ |
/* Check we have remaining characters. */ |
| 6888 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); |
| 6889 |
|
|
| 6891 |
{ |
{ |
| 6892 |
if ((re->options & PCRE_FIRSTLINE) == 0) |
if ((re->options & PCRE_FIRSTLINE) == 0) |
| 6893 |
{ |
{ |
| 6894 |
if (study != NULL && study->minlength > 1) |
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1) |
| 6895 |
{ |
{ |
| 6896 |
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)); |
| 6897 |
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); |
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop); |
| 6901 |
} |
} |
| 6902 |
else |
else |
| 6903 |
{ |
{ |
| 6904 |
if (study != NULL && study->minlength > 1) |
SLJIT_ASSERT(common->first_line_end != 0); |
| 6905 |
|
if (mode == JIT_COMPILE && study != NULL && study->minlength > 1) |
| 6906 |
{ |
{ |
| 6907 |
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)); |
| 6908 |
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); |
| 6909 |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); |
COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); |
| 6910 |
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); |
| 6911 |
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); |
| 6912 |
JUMPTO(SLJIT_C_ZERO, mainloop); |
JUMPTO(SLJIT_C_ZERO, mainloop); |
| 6913 |
} |
} |
| 6914 |
else |
else |
| 6915 |
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); |
| 6916 |
} |
} |
| 6917 |
} |
} |
| 6918 |
|
|
| 6919 |
|
/* No more remaining characters. */ |
| 6920 |
if (reqbyte_notfound != NULL) |
if (reqbyte_notfound != NULL) |
| 6921 |
JUMPHERE(reqbyte_notfound); |
JUMPHERE(reqbyte_notfound); |
| 6922 |
/* Copy OVECTOR(1) to OVECTOR(0) */ |
|
| 6923 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
| 6924 |
|
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); |
| 6925 |
|
|
| 6926 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
| 6927 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 6928 |
|
|
| 6965 |
OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); |
OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE); |
| 6966 |
|
|
| 6967 |
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); |
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize)); |
| 6968 |
alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); |
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); |
| 6969 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
| 6970 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
| 6971 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top)); |
| 6974 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
| 6975 |
|
|
| 6976 |
/* Allocation failed. */ |
/* Allocation failed. */ |
| 6977 |
JUMPHERE(alloc_error); |
JUMPHERE(jump); |
| 6978 |
/* 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. */ |
| 6979 |
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); |
| 6980 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, leave); |
| 7048 |
if (executable_func == NULL) |
if (executable_func == NULL) |
| 7049 |
return; |
return; |
| 7050 |
|
|
| 7051 |
function = SLJIT_MALLOC(sizeof(executable_function)); |
/* Reuse the function descriptor if possible. */ |
| 7052 |
if (function == NULL) |
if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL) |
| 7053 |
|
functions = (executable_functions *)extra->executable_jit; |
| 7054 |
|
else |
| 7055 |
{ |
{ |
| 7056 |
/* This case is highly unlikely since we just recently |
functions = SLJIT_MALLOC(sizeof(executable_functions)); |
| 7057 |
freed a lot of memory. Although not impossible. */ |
if (functions == NULL) |
| 7058 |
sljit_free_code(executable_func); |
{ |
| 7059 |
return; |
/* This case is highly unlikely since we just recently |
| 7060 |
|
freed a lot of memory. Although not impossible. */ |
| 7061 |
|
sljit_free_code(executable_func); |
| 7062 |
|
return; |
| 7063 |
|
} |
| 7064 |
|
memset(functions, 0, sizeof(executable_functions)); |
| 7065 |
|
extra->executable_jit = functions; |
| 7066 |
|
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; |
| 7067 |
} |
} |
| 7068 |
|
|
| 7069 |
function->executable_func = executable_func; |
functions->executable_funcs[mode] = executable_func; |
| 7070 |
function->executable_size = executable_size; |
functions->executable_sizes[mode] = executable_size; |
|
function->callback = NULL; |
|
|
function->userdata = NULL; |
|
|
extra->executable_jit = function; |
|
|
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; |
|
| 7071 |
} |
} |
| 7072 |
|
|
| 7073 |
static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function) |
static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func) |
| 7074 |
{ |
{ |
| 7075 |
union { |
union { |
| 7076 |
void* executable_func; |
void* executable_func; |
| 7084 |
local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; |
local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; |
| 7085 |
local_stack.max_limit = local_stack.limit; |
local_stack.max_limit = local_stack.limit; |
| 7086 |
arguments->stack = &local_stack; |
arguments->stack = &local_stack; |
| 7087 |
convert_executable_func.executable_func = function->executable_func; |
convert_executable_func.executable_func = executable_func; |
| 7088 |
return convert_executable_func.call_executable_func(arguments); |
return convert_executable_func.call_executable_func(arguments); |
| 7089 |
} |
} |
| 7090 |
|
|
| 7091 |
int |
int |
| 7092 |
PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func, |
PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs, |
| 7093 |
const pcre_uchar *subject, int length, int start_offset, int options, |
const pcre_uchar *subject, int length, int start_offset, int options, |
| 7094 |
int match_limit, int *offsets, int offsetcount) |
int match_limit, int *offsets, int offsetcount) |
| 7095 |
{ |
{ |
| 7096 |
executable_function *function = (executable_function*)executable_func; |
executable_functions *functions = (executable_functions *)executable_funcs; |
| 7097 |
union { |
union { |
| 7098 |
void* executable_func; |
void* executable_func; |
| 7099 |
jit_function call_executable_func; |
jit_function call_executable_func; |
| 7101 |
jit_arguments arguments; |
jit_arguments arguments; |
| 7102 |
int maxoffsetcount; |
int maxoffsetcount; |
| 7103 |
int retval; |
int retval; |
| 7104 |
|
int mode = JIT_COMPILE; |
| 7105 |
|
|
| 7106 |
|
if ((options & PCRE_PARTIAL_HARD) != 0) |
| 7107 |
|
mode = JIT_PARTIAL_HARD_COMPILE; |
| 7108 |
|
else if ((options & PCRE_PARTIAL_SOFT) != 0) |
| 7109 |
|
mode = JIT_PARTIAL_SOFT_COMPILE; |
| 7110 |
|
|
| 7111 |
|
if (functions->executable_funcs[mode] == NULL) |
| 7112 |
|
return PCRE_ERROR_NULL; |
| 7113 |
|
|
| 7114 |
/* Sanity checks should be handled by pcre_exec. */ |
/* Sanity checks should be handled by pcre_exec. */ |
| 7115 |
arguments.stack = NULL; |
arguments.stack = NULL; |
| 7136 |
offsetcount = maxoffsetcount; |
offsetcount = maxoffsetcount; |
| 7137 |
arguments.offsetcount = offsetcount; |
arguments.offsetcount = offsetcount; |
| 7138 |
|
|
| 7139 |
if (function->callback) |
if (functions->callback) |
| 7140 |
arguments.stack = (struct sljit_stack*)function->callback(function->userdata); |
arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata); |
| 7141 |
else |
else |
| 7142 |
arguments.stack = (struct sljit_stack*)function->userdata; |
arguments.stack = (struct sljit_stack *)functions->userdata; |
| 7143 |
|
|
| 7144 |
if (arguments.stack == NULL) |
if (arguments.stack == NULL) |
| 7145 |
retval = jit_machine_stack_exec(&arguments, function); |
retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]); |
| 7146 |
else |
else |
| 7147 |
{ |
{ |
| 7148 |
convert_executable_func.executable_func = function->executable_func; |
convert_executable_func.executable_func = functions->executable_funcs[mode]; |
| 7149 |
retval = convert_executable_func.call_executable_func(&arguments); |
retval = convert_executable_func.call_executable_func(&arguments); |
| 7150 |
} |
} |
| 7151 |
|
|
| 7155 |
} |
} |
| 7156 |
|
|
| 7157 |
void |
void |
| 7158 |
PRIV(jit_free)(void *executable_func) |
PRIV(jit_free)(void *executable_funcs) |
| 7159 |
{ |
{ |
| 7160 |
executable_function *function = (executable_function*)executable_func; |
int i; |
| 7161 |
sljit_free_code(function->executable_func); |
executable_functions *functions = (executable_functions *)executable_funcs; |
| 7162 |
SLJIT_FREE(function); |
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) |
| 7163 |
|
{ |
| 7164 |
|
if (functions->executable_funcs[i] != NULL) |
| 7165 |
|
sljit_free_code(functions->executable_funcs[i]); |
| 7166 |
|
} |
| 7167 |
|
SLJIT_FREE(functions); |
| 7168 |
} |
} |
| 7169 |
|
|
| 7170 |
int |
int |
| 7171 |
PRIV(jit_get_size)(void *executable_func) |
PRIV(jit_get_size)(void *executable_funcs) |
| 7172 |
{ |
{ |
| 7173 |
return ((executable_function*)executable_func)->executable_size; |
return ((executable_functions *)executable_funcs)->executable_sizes[PCRE_STUDY_JIT_COMPILE]; |
| 7174 |
} |
} |
| 7175 |
|
|
| 7176 |
const char* |
const char* |
| 7204 |
pcre16_jit_stack_free(pcre16_jit_stack *stack) |
pcre16_jit_stack_free(pcre16_jit_stack *stack) |
| 7205 |
#endif |
#endif |
| 7206 |
{ |
{ |
| 7207 |
sljit_free_stack((struct sljit_stack*)stack); |
sljit_free_stack((struct sljit_stack *)stack); |
| 7208 |
} |
} |
| 7209 |
|
|
| 7210 |
#ifdef COMPILE_PCRE8 |
#ifdef COMPILE_PCRE8 |
| 7215 |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) |
pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) |
| 7216 |
#endif |
#endif |
| 7217 |
{ |
{ |
| 7218 |
executable_function *function; |
executable_functions *functions; |
| 7219 |
if (extra != NULL && |
if (extra != NULL && |
| 7220 |
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
(extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && |
| 7221 |
extra->executable_jit != NULL) |
extra->executable_jit != NULL) |
| 7222 |
{ |
{ |
| 7223 |
function = (executable_function*)extra->executable_jit; |
functions = (executable_functions *)extra->executable_jit; |
| 7224 |
function->callback = callback; |
functions->callback = callback; |
| 7225 |
function->userdata = userdata; |
functions->userdata = userdata; |
| 7226 |
} |
} |
| 7227 |
} |
} |
| 7228 |
|
|