| 307 |
|
|
| 308 |
/* Labels and jump lists. */ |
/* Labels and jump lists. */ |
| 309 |
struct sljit_label *partialmatchlabel; |
struct sljit_label *partialmatchlabel; |
| 310 |
|
struct sljit_label *leavelabel; |
| 311 |
struct sljit_label *acceptlabel; |
struct sljit_label *acceptlabel; |
| 312 |
stub_list *stubs; |
stub_list *stubs; |
| 313 |
recurse_entry *entries; |
recurse_entry *entries; |
| 314 |
recurse_entry *currententry; |
recurse_entry *currententry; |
| 315 |
jump_list *partialmatch; |
jump_list *partialmatch; |
| 316 |
|
jump_list *leave; |
| 317 |
jump_list *accept; |
jump_list *accept; |
| 318 |
jump_list *calllimit; |
jump_list *calllimit; |
| 319 |
jump_list *stackalloc; |
jump_list *stackalloc; |
| 519 |
case OP_BRAZERO: |
case OP_BRAZERO: |
| 520 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
| 521 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
| 522 |
|
case OP_COMMIT: |
| 523 |
case OP_FAIL: |
case OP_FAIL: |
| 524 |
case OP_ACCEPT: |
case OP_ACCEPT: |
| 525 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
| 4162 |
} |
} |
| 4163 |
else if (common->has_set_som || common->mark_ptr != 0) |
else if (common->has_set_som || common->mark_ptr != 0) |
| 4164 |
{ |
{ |
| 4165 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr); |
| 4166 |
allocate_stack(common, 1); |
allocate_stack(common, 1); |
| 4167 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
| 4168 |
} |
} |
| 4189 |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks; |
| 4190 |
jump_list **found; |
jump_list **found; |
| 4191 |
/* Saving previous accept variables. */ |
/* Saving previous accept variables. */ |
| 4192 |
|
struct sljit_label *save_leavelabel = common->leavelabel; |
| 4193 |
struct sljit_label *save_acceptlabel = common->acceptlabel; |
struct sljit_label *save_acceptlabel = common->acceptlabel; |
| 4194 |
|
jump_list *save_leave = common->leave; |
| 4195 |
|
jump_list *save_accept = common->accept; |
| 4196 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 4197 |
struct sljit_jump *brajump = NULL; |
struct sljit_jump *brajump = NULL; |
|
jump_list *save_accept = common->accept; |
|
| 4198 |
|
|
| 4199 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
| 4200 |
{ |
{ |
| 4239 |
} |
} |
| 4240 |
|
|
| 4241 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altfallback, 0, sizeof(fallback_common)); |
| 4242 |
|
common->leavelabel = NULL; |
| 4243 |
|
common->leave = NULL; |
| 4244 |
while (1) |
while (1) |
| 4245 |
{ |
{ |
| 4246 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
| 4255 |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback); |
| 4256 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 4257 |
{ |
{ |
| 4258 |
|
common->leavelabel = save_leavelabel; |
| 4259 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
| 4260 |
|
common->leave = save_leave; |
| 4261 |
common->accept = save_accept; |
common->accept = save_accept; |
| 4262 |
return NULL; |
return NULL; |
| 4263 |
} |
} |
| 4310 |
compile_fallbackpath(common, altfallback.top); |
compile_fallbackpath(common, altfallback.top); |
| 4311 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 4312 |
{ |
{ |
| 4313 |
|
common->leavelabel = save_leavelabel; |
| 4314 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
| 4315 |
|
common->leave = save_leave; |
| 4316 |
common->accept = save_accept; |
common->accept = save_accept; |
| 4317 |
return NULL; |
return NULL; |
| 4318 |
} |
} |
| 4325 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 4326 |
} |
} |
| 4327 |
/* None of them matched. */ |
/* None of them matched. */ |
| 4328 |
|
if (common->leave != NULL) |
| 4329 |
|
set_jumps(common->leave, LABEL()); |
| 4330 |
|
|
| 4331 |
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) |
| 4332 |
{ |
{ |
| 4451 |
} |
} |
| 4452 |
} |
} |
| 4453 |
|
|
| 4454 |
|
common->leavelabel = save_leavelabel; |
| 4455 |
common->acceptlabel = save_acceptlabel; |
common->acceptlabel = save_acceptlabel; |
| 4456 |
|
common->leave = save_leave; |
| 4457 |
common->accept = save_accept; |
common->accept = save_accept; |
| 4458 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
| 4459 |
} |
} |
| 5825 |
cc += 1 + 2 + cc[1]; |
cc += 1 + 2 + cc[1]; |
| 5826 |
break; |
break; |
| 5827 |
|
|
| 5828 |
|
case OP_COMMIT: |
| 5829 |
|
PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc); |
| 5830 |
|
cc += 1; |
| 5831 |
|
break; |
| 5832 |
|
|
| 5833 |
case OP_FAIL: |
case OP_FAIL: |
| 5834 |
case OP_ACCEPT: |
case OP_ACCEPT: |
| 5835 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
| 6036 |
{ |
{ |
| 6037 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
| 6038 |
free_stack(common, 1); |
free_stack(common, 1); |
| 6039 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0); |
| 6040 |
} |
} |
| 6041 |
} |
} |
| 6042 |
|
|
| 6679 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0); |
| 6680 |
break; |
break; |
| 6681 |
|
|
| 6682 |
|
case OP_COMMIT: |
| 6683 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
| 6684 |
|
if (common->leavelabel == NULL) |
| 6685 |
|
add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); |
| 6686 |
|
else |
| 6687 |
|
JUMPTO(SLJIT_JUMP, common->leavelabel); |
| 6688 |
|
break; |
| 6689 |
|
|
| 6690 |
case OP_FAIL: |
case OP_FAIL: |
| 6691 |
case OP_ACCEPT: |
case OP_ACCEPT: |
| 6692 |
case OP_ASSERT_ACCEPT: |
case OP_ASSERT_ACCEPT: |
| 6712 |
int alternativesize; |
int alternativesize; |
| 6713 |
BOOL needsframe; |
BOOL needsframe; |
| 6714 |
fallback_common altfallback; |
fallback_common altfallback; |
| 6715 |
|
struct sljit_label *save_leavelabel = common->leavelabel; |
| 6716 |
|
jump_list *save_leave = common->leave; |
| 6717 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
| 6718 |
|
|
| 6719 |
SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); |
SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); |
| 6738 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
| 6739 |
|
|
| 6740 |
memset(&altfallback, 0, sizeof(fallback_common)); |
memset(&altfallback, 0, sizeof(fallback_common)); |
| 6741 |
|
common->leavelabel = NULL; |
| 6742 |
common->acceptlabel = NULL; |
common->acceptlabel = NULL; |
| 6743 |
|
common->leave = NULL; |
| 6744 |
common->accept = NULL; |
common->accept = NULL; |
| 6745 |
altfallback.cc = ccbegin; |
altfallback.cc = ccbegin; |
| 6746 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 6754 |
|
|
| 6755 |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
compile_hotpath(common, altfallback.cc, cc, &altfallback); |
| 6756 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6757 |
|
{ |
| 6758 |
|
common->leavelabel = save_leavelabel; |
| 6759 |
|
common->leave = save_leave; |
| 6760 |
return; |
return; |
| 6761 |
|
} |
| 6762 |
|
|
| 6763 |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); |
| 6764 |
|
|
| 6765 |
compile_fallbackpath(common, altfallback.top); |
compile_fallbackpath(common, altfallback.top); |
| 6766 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
| 6767 |
|
{ |
| 6768 |
|
common->leavelabel = save_leavelabel; |
| 6769 |
|
common->leave = save_leave; |
| 6770 |
return; |
return; |
| 6771 |
|
} |
| 6772 |
set_jumps(altfallback.topfallbacks, LABEL()); |
set_jumps(altfallback.topfallbacks, LABEL()); |
| 6773 |
|
|
| 6774 |
if (*cc != OP_ALT) |
if (*cc != OP_ALT) |
| 6778 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
| 6779 |
} |
} |
| 6780 |
/* None of them matched. */ |
/* None of them matched. */ |
| 6781 |
|
if (common->leave != NULL) |
| 6782 |
|
set_jumps(common->leave, LABEL()); |
| 6783 |
|
|
| 6784 |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); |
| 6785 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
| 6786 |
|
|
| 6801 |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); |
| 6802 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); |
| 6803 |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); |
| 6804 |
|
|
| 6805 |
|
common->leavelabel = save_leavelabel; |
| 6806 |
|
common->leave = save_leave; |
| 6807 |
} |
} |
| 6808 |
|
|
| 6809 |
#undef COMPILE_FALLBACKPATH |
#undef COMPILE_FALLBACKPATH |
| 6822 |
executable_functions *functions; |
executable_functions *functions; |
| 6823 |
void *executable_func; |
void *executable_func; |
| 6824 |
sljit_uw executable_size; |
sljit_uw executable_size; |
|
struct sljit_label *leave; |
|
| 6825 |
struct sljit_label *mainloop = NULL; |
struct sljit_label *mainloop = NULL; |
| 6826 |
struct sljit_label *empty_match_found; |
struct sljit_label *empty_match_found; |
| 6827 |
struct sljit_label *empty_match_fallback; |
struct sljit_label *empty_match_fallback; |
| 7012 |
|
|
| 7013 |
/* This means we have a match. Update the ovector. */ |
/* This means we have a match. Update the ovector. */ |
| 7014 |
copy_ovector(common, re->top_bracket + 1); |
copy_ovector(common, re->top_bracket + 1); |
| 7015 |
leave = LABEL(); |
common->leavelabel = LABEL(); |
| 7016 |
|
if (common->leave != NULL) |
| 7017 |
|
set_jumps(common->leave, common->leavelabel); |
| 7018 |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); |
| 7019 |
|
|
| 7020 |
if (mode != JIT_COMPILE) |
if (mode != JIT_COMPILE) |
| 7021 |
{ |
{ |
| 7022 |
common->partialmatchlabel = LABEL(); |
common->partialmatchlabel = LABEL(); |
| 7023 |
set_jumps(common->partialmatch, common->partialmatchlabel); |
set_jumps(common->partialmatch, common->partialmatchlabel); |
| 7024 |
return_with_partial_match(common, leave); |
return_with_partial_match(common, common->leavelabel); |
| 7025 |
} |
} |
| 7026 |
|
|
| 7027 |
empty_match_fallback = LABEL(); |
empty_match_fallback = LABEL(); |
| 7085 |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); |
| 7086 |
|
|
| 7087 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
| 7088 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
| 7089 |
|
|
| 7090 |
flush_stubs(common); |
flush_stubs(common); |
| 7091 |
|
|
| 7138 |
JUMPHERE(jump); |
JUMPHERE(jump); |
| 7139 |
/* 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. */ |
| 7140 |
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); |
| 7141 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
| 7142 |
|
|
| 7143 |
/* Call limit reached. */ |
/* Call limit reached. */ |
| 7144 |
set_jumps(common->calllimit, LABEL()); |
set_jumps(common->calllimit, LABEL()); |
| 7145 |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); |
| 7146 |
JUMPTO(SLJIT_JUMP, leave); |
JUMPTO(SLJIT_JUMP, common->leavelabel); |
| 7147 |
|
|
| 7148 |
if (common->revertframes != NULL) |
if (common->revertframes != NULL) |
| 7149 |
{ |
{ |
| 7250 |
} |
} |
| 7251 |
|
|
| 7252 |
int |
int |
| 7253 |
PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs, |
PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, |
| 7254 |
const pcre_uchar *subject, int length, int start_offset, int options, |
int length, int start_offset, int options, int *offsets, int offsetcount) |
|
int match_limit, int *offsets, int offsetcount, pcre_uchar **mark_ptr) |
|
| 7255 |
{ |
{ |
| 7256 |
executable_functions *functions = (executable_functions *)executable_funcs; |
executable_functions *functions = (executable_functions *)extra_data->executable_jit; |
| 7257 |
union { |
union { |
| 7258 |
void* executable_func; |
void* executable_func; |
| 7259 |
jit_function call_executable_func; |
jit_function call_executable_func; |
| 7278 |
arguments.end = subject + length; |
arguments.end = subject + length; |
| 7279 |
arguments.mark_ptr = NULL; |
arguments.mark_ptr = NULL; |
| 7280 |
/* JIT decreases this value less frequently than the interpreter. */ |
/* JIT decreases this value less frequently than the interpreter. */ |
| 7281 |
arguments.calllimit = match_limit; |
arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; |
| 7282 |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
| 7283 |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
| 7284 |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
| 7313 |
|
|
| 7314 |
if (retval * 2 > offsetcount) |
if (retval * 2 > offsetcount) |
| 7315 |
retval = 0; |
retval = 0; |
| 7316 |
if (mark_ptr != NULL) |
if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) |
| 7317 |
*mark_ptr = arguments.mark_ptr; |
*(extra_data->mark) = arguments.mark_ptr; |
| 7318 |
|
|
| 7319 |
return retval; |
return retval; |
| 7320 |
} |
} |