168 |
pcre_uchar *mark_ptr; |
pcre_uchar *mark_ptr; |
169 |
void *callout_data; |
void *callout_data; |
170 |
/* Everything else after. */ |
/* Everything else after. */ |
171 |
|
pcre_uint32 limit_match; |
172 |
int real_offset_count; |
int real_offset_count; |
173 |
int offset_count; |
int offset_count; |
|
int call_limit; |
|
174 |
pcre_uint8 notbol; |
pcre_uint8 notbol; |
175 |
pcre_uint8 noteol; |
pcre_uint8 noteol; |
176 |
pcre_uint8 notempty; |
pcre_uint8 notempty; |
182 |
PUBL(jit_callback) callback; |
PUBL(jit_callback) callback; |
183 |
void *userdata; |
void *userdata; |
184 |
pcre_uint32 top_bracket; |
pcre_uint32 top_bracket; |
185 |
|
pcre_uint32 limit_match; |
186 |
sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; |
sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; |
187 |
} executable_functions; |
} executable_functions; |
188 |
|
|
203 |
}; |
}; |
204 |
|
|
205 |
enum control_types { |
enum control_types { |
206 |
type_commit = 0, |
type_mark = 0, |
207 |
type_prune = 1, |
type_then_trap = 1 |
|
type_skip = 2 |
|
208 |
}; |
}; |
209 |
|
|
210 |
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); |
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); |
211 |
|
|
212 |
/* The following structure is the key data type for the recursive |
/* The following structure is the key data type for the recursive |
213 |
code generator. It is allocated by compile_matchingpath, and contains |
code generator. It is allocated by compile_matchingpath, and contains |
214 |
the aguments for compile_backtrackingpath. Must be the first member |
the arguments for compile_backtrackingpath. Must be the first member |
215 |
of its descendants. */ |
of its descendants. */ |
216 |
typedef struct backtrack_common { |
typedef struct backtrack_common { |
217 |
/* Concatenation stack. */ |
/* Concatenation stack. */ |
227 |
typedef struct assert_backtrack { |
typedef struct assert_backtrack { |
228 |
backtrack_common common; |
backtrack_common common; |
229 |
jump_list *condfailed; |
jump_list *condfailed; |
230 |
/* Less than 0 (-1) if a frame is not needed. */ |
/* Less than 0 if a frame is not needed. */ |
231 |
int framesize; |
int framesize; |
232 |
/* Points to our private memory word on the stack. */ |
/* Points to our private memory word on the stack. */ |
233 |
int private_data_ptr; |
int private_data_ptr; |
248 |
/* Both for OP_COND, OP_SCOND. */ |
/* Both for OP_COND, OP_SCOND. */ |
249 |
jump_list *condfailed; |
jump_list *condfailed; |
250 |
assert_backtrack *assert; |
assert_backtrack *assert; |
251 |
/* For OP_ONCE. -1 if not needed. */ |
/* For OP_ONCE. Less than 0 if not needed. */ |
252 |
int framesize; |
int framesize; |
253 |
} u; |
} u; |
254 |
/* Points to our private memory word on the stack. */ |
/* Points to our private memory word on the stack. */ |
283 |
/* Collects the calls until the function is not created. */ |
/* Collects the calls until the function is not created. */ |
284 |
jump_list *calls; |
jump_list *calls; |
285 |
/* Points to the starting opcode. */ |
/* Points to the starting opcode. */ |
286 |
int start; |
sljit_sw start; |
287 |
} recurse_entry; |
} recurse_entry; |
288 |
|
|
289 |
typedef struct recurse_backtrack { |
typedef struct recurse_backtrack { |
291 |
BOOL inlined_pattern; |
BOOL inlined_pattern; |
292 |
} recurse_backtrack; |
} recurse_backtrack; |
293 |
|
|
294 |
|
#define OP_THEN_TRAP OP_TABLE_LENGTH |
295 |
|
|
296 |
|
typedef struct then_trap_backtrack { |
297 |
|
backtrack_common common; |
298 |
|
/* If then_trap is not NULL, this structure contains the real |
299 |
|
then_trap for the backtracking path. */ |
300 |
|
struct then_trap_backtrack *then_trap; |
301 |
|
/* Points to the starting opcode. */ |
302 |
|
sljit_sw start; |
303 |
|
/* Exit point for the then opcodes of this alternative. */ |
304 |
|
jump_list *quit; |
305 |
|
/* Frame size of the current alternative. */ |
306 |
|
int framesize; |
307 |
|
} then_trap_backtrack; |
308 |
|
|
309 |
#define MAX_RANGE_SIZE 6 |
#define MAX_RANGE_SIZE 6 |
310 |
|
|
311 |
typedef struct compiler_common { |
typedef struct compiler_common { |
314 |
/* First byte code. */ |
/* First byte code. */ |
315 |
pcre_uchar *start; |
pcre_uchar *start; |
316 |
/* Maps private data offset to each opcode. */ |
/* Maps private data offset to each opcode. */ |
317 |
int *private_data_ptrs; |
sljit_si *private_data_ptrs; |
318 |
/* Tells whether the capturing bracket is optimized. */ |
/* Tells whether the capturing bracket is optimized. */ |
319 |
pcre_uint8 *optimized_cbracket; |
pcre_uint8 *optimized_cbracket; |
320 |
|
/* Tells whether the starting offset is a target of then. */ |
321 |
|
pcre_uint8 *then_offsets; |
322 |
|
/* Current position where a THEN must jump. */ |
323 |
|
then_trap_backtrack *then_trap; |
324 |
/* Starting offset of private data for capturing brackets. */ |
/* Starting offset of private data for capturing brackets. */ |
325 |
int cbra_ptr; |
int cbra_ptr; |
326 |
/* Output vector starting point. Must be divisible by 2. */ |
/* Output vector starting point. Must be divisible by 2. */ |
349 |
sljit_sw lcc; |
sljit_sw lcc; |
350 |
/* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ |
/* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ |
351 |
int mode; |
int mode; |
352 |
/* \K is in the pattern. */ |
/* \K is found in the pattern. */ |
353 |
BOOL has_set_som; |
BOOL has_set_som; |
354 |
|
/* (*SKIP:arg) is found in the pattern. */ |
355 |
|
BOOL has_skip_arg; |
356 |
|
/* (*THEN) is found in the pattern. */ |
357 |
|
BOOL has_then; |
358 |
/* Needs to know the start position anytime. */ |
/* Needs to know the start position anytime. */ |
359 |
BOOL needs_start_ptr; |
BOOL needs_start_ptr; |
360 |
/* Currently in recurse or assert. */ |
/* Currently in recurse or negative assert. */ |
361 |
BOOL local_exit; |
BOOL local_exit; |
362 |
|
/* Currently in a positive assert. */ |
363 |
|
BOOL positive_assert; |
364 |
/* Newline control. */ |
/* Newline control. */ |
365 |
int nltype; |
int nltype; |
366 |
int newline; |
int newline; |
371 |
sljit_sw ctypes; |
sljit_sw ctypes; |
372 |
int digits[2 + MAX_RANGE_SIZE]; |
int digits[2 + MAX_RANGE_SIZE]; |
373 |
/* Named capturing brackets. */ |
/* Named capturing brackets. */ |
374 |
sljit_uw name_table; |
pcre_uchar *name_table; |
375 |
sljit_sw name_count; |
sljit_sw name_count; |
376 |
sljit_sw name_entry_size; |
sljit_sw name_entry_size; |
377 |
|
|
385 |
recurse_entry *currententry; |
recurse_entry *currententry; |
386 |
jump_list *partialmatch; |
jump_list *partialmatch; |
387 |
jump_list *quit; |
jump_list *quit; |
388 |
|
jump_list *positive_assert_quit; |
389 |
jump_list *forced_quit; |
jump_list *forced_quit; |
390 |
jump_list *accept; |
jump_list *accept; |
391 |
jump_list *calllimit; |
jump_list *calllimit; |
464 |
#define STACK_TOP SLJIT_SCRATCH_REG2 |
#define STACK_TOP SLJIT_SCRATCH_REG2 |
465 |
#define STACK_LIMIT SLJIT_SAVED_REG3 |
#define STACK_LIMIT SLJIT_SAVED_REG3 |
466 |
#define ARGUMENTS SLJIT_SAVED_EREG1 |
#define ARGUMENTS SLJIT_SAVED_EREG1 |
467 |
#define CALL_COUNT SLJIT_SAVED_EREG2 |
#define COUNT_MATCH SLJIT_SAVED_EREG2 |
468 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1 |
469 |
|
|
470 |
/* Local space layout. */ |
/* Local space layout. */ |
475 |
#define POSSESSIVE0 (2 * sizeof(sljit_sw)) |
#define POSSESSIVE0 (2 * sizeof(sljit_sw)) |
476 |
#define POSSESSIVE1 (3 * sizeof(sljit_sw)) |
#define POSSESSIVE1 (3 * sizeof(sljit_sw)) |
477 |
/* Max limit of recursions. */ |
/* Max limit of recursions. */ |
478 |
#define CALL_LIMIT (4 * sizeof(sljit_sw)) |
#define LIMIT_MATCH (4 * sizeof(sljit_sw)) |
479 |
/* The output vector is stored on the stack, and contains pointers |
/* The output vector is stored on the stack, and contains pointers |
480 |
to characters. The vector data is divided into two groups: the first |
to characters. The vector data is divided into two groups: the first |
481 |
group contains the start / end character pointers, and the second is |
group contains the start / end character pointers, and the second is |
482 |
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. */ |
483 |
#define OVECTOR_START (common->ovector_start) |
#define OVECTOR_START (common->ovector_start) |
484 |
#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_sw)) |
#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw)) |
485 |
#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * sizeof(sljit_sw)) |
#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw)) |
486 |
#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) |
#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) |
487 |
|
|
488 |
#if defined COMPILE_PCRE8 |
#if defined COMPILE_PCRE8 |
535 |
|
|
536 |
/* Functions whose might need modification for all new supported opcodes: |
/* Functions whose might need modification for all new supported opcodes: |
537 |
next_opcode |
next_opcode |
538 |
get_private_data_length |
check_opcode_types |
539 |
set_private_data_ptrs |
set_private_data_ptrs |
540 |
get_framesize |
get_framesize |
541 |
init_frame |
init_frame |
542 |
get_private_data_length_for_copy |
get_private_data_copy_length |
543 |
copy_private_data |
copy_private_data |
544 |
compile_matchingpath |
compile_matchingpath |
545 |
compile_backtrackingpath |
compile_backtrackingpath |
614 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
615 |
case OP_SCOND: |
case OP_SCOND: |
616 |
case OP_CREF: |
case OP_CREF: |
617 |
case OP_NCREF: |
case OP_DNCREF: |
618 |
case OP_RREF: |
case OP_RREF: |
619 |
case OP_NRREF: |
case OP_DNRREF: |
620 |
case OP_DEF: |
case OP_DEF: |
621 |
case OP_BRAZERO: |
case OP_BRAZERO: |
622 |
case OP_BRAMINZERO: |
case OP_BRAMINZERO: |
623 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
624 |
case OP_PRUNE: |
case OP_PRUNE: |
625 |
case OP_SKIP: |
case OP_SKIP: |
626 |
|
case OP_THEN: |
627 |
case OP_COMMIT: |
case OP_COMMIT: |
628 |
case OP_FAIL: |
case OP_FAIL: |
629 |
case OP_ACCEPT: |
case OP_ACCEPT: |
723 |
|
|
724 |
case OP_MARK: |
case OP_MARK: |
725 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
726 |
|
case OP_SKIP_ARG: |
727 |
|
case OP_THEN_ARG: |
728 |
return cc + 1 + 2 + cc[1]; |
return cc + 1 + 2 + cc[1]; |
729 |
|
|
730 |
default: |
default: |
731 |
|
/* All opcodes are supported now! */ |
732 |
|
SLJIT_ASSERT_STOP(); |
733 |
return NULL; |
return NULL; |
734 |
} |
} |
735 |
} |
} |
736 |
|
|
737 |
#define CASE_ITERATOR_PRIVATE_DATA_1 \ |
static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) |
|
case OP_MINSTAR: \ |
|
|
case OP_MINPLUS: \ |
|
|
case OP_QUERY: \ |
|
|
case OP_MINQUERY: \ |
|
|
case OP_MINSTARI: \ |
|
|
case OP_MINPLUSI: \ |
|
|
case OP_QUERYI: \ |
|
|
case OP_MINQUERYI: \ |
|
|
case OP_NOTMINSTAR: \ |
|
|
case OP_NOTMINPLUS: \ |
|
|
case OP_NOTQUERY: \ |
|
|
case OP_NOTMINQUERY: \ |
|
|
case OP_NOTMINSTARI: \ |
|
|
case OP_NOTMINPLUSI: \ |
|
|
case OP_NOTQUERYI: \ |
|
|
case OP_NOTMINQUERYI: |
|
|
|
|
|
#define CASE_ITERATOR_PRIVATE_DATA_2A \ |
|
|
case OP_STAR: \ |
|
|
case OP_PLUS: \ |
|
|
case OP_STARI: \ |
|
|
case OP_PLUSI: \ |
|
|
case OP_NOTSTAR: \ |
|
|
case OP_NOTPLUS: \ |
|
|
case OP_NOTSTARI: \ |
|
|
case OP_NOTPLUSI: |
|
|
|
|
|
#define CASE_ITERATOR_PRIVATE_DATA_2B \ |
|
|
case OP_UPTO: \ |
|
|
case OP_MINUPTO: \ |
|
|
case OP_UPTOI: \ |
|
|
case OP_MINUPTOI: \ |
|
|
case OP_NOTUPTO: \ |
|
|
case OP_NOTMINUPTO: \ |
|
|
case OP_NOTUPTOI: \ |
|
|
case OP_NOTMINUPTOI: |
|
|
|
|
|
#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ |
|
|
case OP_TYPEMINSTAR: \ |
|
|
case OP_TYPEMINPLUS: \ |
|
|
case OP_TYPEQUERY: \ |
|
|
case OP_TYPEMINQUERY: |
|
|
|
|
|
#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ |
|
|
case OP_TYPESTAR: \ |
|
|
case OP_TYPEPLUS: |
|
|
|
|
|
#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ |
|
|
case OP_TYPEUPTO: \ |
|
|
case OP_TYPEMINUPTO: |
|
|
|
|
|
static int get_class_iterator_size(pcre_uchar *cc) |
|
738 |
{ |
{ |
739 |
switch(*cc) |
pcre_uchar *slot; |
740 |
{ |
int i; |
|
case OP_CRSTAR: |
|
|
case OP_CRPLUS: |
|
|
return 2; |
|
|
|
|
|
case OP_CRMINSTAR: |
|
|
case OP_CRMINPLUS: |
|
|
case OP_CRQUERY: |
|
|
case OP_CRMINQUERY: |
|
|
return 1; |
|
|
|
|
|
case OP_CRRANGE: |
|
|
case OP_CRMINRANGE: |
|
|
if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) |
|
|
return 0; |
|
|
return 2; |
|
|
|
|
|
default: |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) |
|
|
{ |
|
|
int private_data_length = 0; |
|
|
pcre_uchar *alternative; |
|
|
pcre_uchar *name; |
|
|
pcre_uchar *end = NULL; |
|
|
int space, size, i; |
|
|
pcre_uint32 bracketlen; |
|
741 |
|
|
742 |
/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ |
/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ |
743 |
while (cc < ccend) |
while (cc < ccend) |
744 |
{ |
{ |
|
space = 0; |
|
|
size = 0; |
|
|
bracketlen = 0; |
|
745 |
switch(*cc) |
switch(*cc) |
746 |
{ |
{ |
747 |
case OP_SET_SOM: |
case OP_SET_SOM: |
755 |
cc += 1 + IMM2_SIZE; |
cc += 1 + IMM2_SIZE; |
756 |
break; |
break; |
757 |
|
|
|
case OP_ASSERT: |
|
|
case OP_ASSERT_NOT: |
|
|
case OP_ASSERTBACK: |
|
|
case OP_ASSERTBACK_NOT: |
|
|
case OP_ONCE: |
|
|
case OP_ONCE_NC: |
|
|
case OP_BRAPOS: |
|
|
case OP_SBRA: |
|
|
case OP_SBRAPOS: |
|
|
private_data_length += sizeof(sljit_sw); |
|
|
bracketlen = 1 + LINK_SIZE; |
|
|
break; |
|
|
|
|
758 |
case OP_CBRAPOS: |
case OP_CBRAPOS: |
759 |
case OP_SCBRAPOS: |
case OP_SCBRAPOS: |
|
private_data_length += sizeof(sljit_sw); |
|
760 |
common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; |
common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; |
761 |
bracketlen = 1 + LINK_SIZE + IMM2_SIZE; |
cc += 1 + LINK_SIZE + IMM2_SIZE; |
762 |
break; |
break; |
763 |
|
|
764 |
case OP_COND: |
case OP_COND: |
766 |
/* Only AUTO_CALLOUT can insert this opcode. We do |
/* Only AUTO_CALLOUT can insert this opcode. We do |
767 |
not intend to support this case. */ |
not intend to support this case. */ |
768 |
if (cc[1 + LINK_SIZE] == OP_CALLOUT) |
if (cc[1 + LINK_SIZE] == OP_CALLOUT) |
769 |
return -1; |
return FALSE; |
770 |
|
cc += 1 + LINK_SIZE; |
|
if (*cc == OP_COND) |
|
|
{ |
|
|
/* Might be a hidden SCOND. */ |
|
|
alternative = cc + GET(cc, 1); |
|
|
if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) |
|
|
private_data_length += sizeof(sljit_sw); |
|
|
} |
|
|
else |
|
|
private_data_length += sizeof(sljit_sw); |
|
|
bracketlen = 1 + LINK_SIZE; |
|
771 |
break; |
break; |
772 |
|
|
773 |
case OP_CREF: |
case OP_CREF: |
776 |
cc += 1 + IMM2_SIZE; |
cc += 1 + IMM2_SIZE; |
777 |
break; |
break; |
778 |
|
|
779 |
case OP_NCREF: |
case OP_DNCREF: |
780 |
bracketlen = GET2(cc, 1); |
i = GET2(cc, 1 + IMM2_SIZE); |
781 |
name = (pcre_uchar *)common->name_table; |
slot = common->name_table + GET2(cc, 1) * common->name_entry_size; |
782 |
alternative = name; |
while (i-- > 0) |
|
for (i = 0; i < common->name_count; i++) |
|
783 |
{ |
{ |
784 |
if (GET2(name, 0) == bracketlen) break; |
common->optimized_cbracket[GET2(slot, 0)] = 0; |
785 |
name += common->name_entry_size; |
slot += common->name_entry_size; |
786 |
} |
} |
787 |
SLJIT_ASSERT(i != common->name_count); |
cc += 1 + 2 * IMM2_SIZE; |
|
|
|
|
for (i = 0; i < common->name_count; i++) |
|
|
{ |
|
|
if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0) |
|
|
common->optimized_cbracket[GET2(alternative, 0)] = 0; |
|
|
alternative += common->name_entry_size; |
|
|
} |
|
|
bracketlen = 0; |
|
|
cc += 1 + IMM2_SIZE; |
|
788 |
break; |
break; |
789 |
|
|
|
case OP_BRA: |
|
|
bracketlen = 1 + LINK_SIZE; |
|
|
break; |
|
|
|
|
|
case OP_CBRA: |
|
|
case OP_SCBRA: |
|
|
bracketlen = 1 + LINK_SIZE + IMM2_SIZE; |
|
|
break; |
|
|
|
|
|
CASE_ITERATOR_PRIVATE_DATA_1 |
|
|
space = 1; |
|
|
size = -2; |
|
|
break; |
|
|
|
|
|
CASE_ITERATOR_PRIVATE_DATA_2A |
|
|
space = 2; |
|
|
size = -2; |
|
|
break; |
|
|
|
|
|
CASE_ITERATOR_PRIVATE_DATA_2B |
|
|
space = 2; |
|
|
size = -(2 + IMM2_SIZE); |
|
|
break; |
|
|
|
|
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_1 |
|
|
space = 1; |
|
|
size = 1; |
|
|
break; |
|
|
|
|
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_2A |
|
|
if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) |
|
|
space = 2; |
|
|
size = 1; |
|
|
break; |
|
|
|
|
|
CASE_ITERATOR_TYPE_PRIVATE_DATA_2B |
|
|
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) |
|
|
space = 2; |
|
|
size = 1 + IMM2_SIZE; |
|
|
break; |
|
|
|
|
|
case OP_CLASS: |
|
|
case OP_NCLASS: |
|
|
size += 1 + 32 / sizeof(pcre_uchar); |
|
|
space = get_class_iterator_size(cc + size); |
|
|
break; |
|
|
|
|
|
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 |
|
|
case OP_XCLASS: |
|
|
size = GET(cc, 1); |
|
|
space = get_class_iterator_size(cc + size); |
|
|
break; |
|
|
#endif |
|
|
|
|
790 |
case OP_RECURSE: |
case OP_RECURSE: |
791 |
/* Set its value only once. */ |
/* Set its value only once. */ |
792 |
if (common->recursive_head_ptr == 0) |
if (common->recursive_head_ptr == 0) |
806 |
cc += 2 + 2 * LINK_SIZE; |
cc += 2 + 2 * LINK_SIZE; |
807 |
break; |
break; |
808 |
|
|
809 |
|
case OP_THEN_ARG: |
810 |
|
common->has_then = TRUE; |
811 |
|
common->control_head_ptr = 1; |
812 |
|
/* Fall through. */ |
813 |
|
|
814 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
815 |
common->needs_start_ptr = TRUE; |
common->needs_start_ptr = TRUE; |
|
common->control_head_ptr = 1; |
|
816 |
/* Fall through. */ |
/* Fall through. */ |
817 |
|
|
818 |
case OP_MARK: |
case OP_MARK: |
824 |
cc += 1 + 2 + cc[1]; |
cc += 1 + 2 + cc[1]; |
825 |
break; |
break; |
826 |
|
|
827 |
|
case OP_THEN: |
828 |
|
common->has_then = TRUE; |
829 |
|
common->control_head_ptr = 1; |
830 |
|
/* Fall through. */ |
831 |
|
|
832 |
case OP_PRUNE: |
case OP_PRUNE: |
833 |
case OP_SKIP: |
case OP_SKIP: |
834 |
common->needs_start_ptr = TRUE; |
common->needs_start_ptr = TRUE; |
835 |
/* Fall through. */ |
cc += 1; |
836 |
|
break; |
837 |
|
|
838 |
case OP_COMMIT: |
case OP_SKIP_ARG: |
839 |
common->control_head_ptr = 1; |
common->control_head_ptr = 1; |
840 |
cc += 1; |
common->has_skip_arg = TRUE; |
841 |
|
cc += 1 + 2 + cc[1]; |
842 |
break; |
break; |
843 |
|
|
844 |
default: |
default: |
845 |
cc = next_opcode(common, cc); |
cc = next_opcode(common, cc); |
846 |
if (cc == NULL) |
if (cc == NULL) |
847 |
return -1; |
return FALSE; |
848 |
break; |
break; |
849 |
} |
} |
850 |
|
} |
851 |
|
return TRUE; |
852 |
|
} |
853 |
|
|
854 |
if (space > 0 && cc >= end) |
static int get_class_iterator_size(pcre_uchar *cc) |
855 |
private_data_length += sizeof(sljit_sw) * space; |
{ |
856 |
|
switch(*cc) |
857 |
|
{ |
858 |
|
case OP_CRSTAR: |
859 |
|
case OP_CRPLUS: |
860 |
|
return 2; |
861 |
|
|
862 |
if (size != 0) |
case OP_CRMINSTAR: |
863 |
|
case OP_CRMINPLUS: |
864 |
|
case OP_CRQUERY: |
865 |
|
case OP_CRMINQUERY: |
866 |
|
return 1; |
867 |
|
|
868 |
|
case OP_CRRANGE: |
869 |
|
case OP_CRMINRANGE: |
870 |
|
if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) |
871 |
|
return 0; |
872 |
|
return 2; |
873 |
|
|
874 |
|
default: |
875 |
|
return 0; |
876 |
|
} |
877 |
|
} |
878 |
|
|
879 |
|
static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin) |
880 |
|
{ |
881 |
|
pcre_uchar *end = bracketend(begin); |
882 |
|
pcre_uchar *next; |
883 |
|
pcre_uchar *next_end; |
884 |
|
pcre_uchar *max_end; |
885 |
|
pcre_uchar type; |
886 |
|
sljit_sw length = end - begin; |
887 |
|
int min, max, i; |
888 |
|
|
889 |
|
/* Detect fixed iterations first. */ |
890 |
|
if (end[-(1 + LINK_SIZE)] != OP_KET) |
891 |
|
return FALSE; |
892 |
|
|
893 |
|
/* Already detected repeat. */ |
894 |
|
if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0) |
895 |
|
return TRUE; |
896 |
|
|
897 |
|
next = end; |
898 |
|
min = 1; |
899 |
|
while (1) |
900 |
|
{ |
901 |
|
if (*next != *begin) |
902 |
|
break; |
903 |
|
next_end = bracketend(next); |
904 |
|
if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0) |
905 |
|
break; |
906 |
|
next = next_end; |
907 |
|
min++; |
908 |
|
} |
909 |
|
|
910 |
|
if (min == 2) |
911 |
|
return FALSE; |
912 |
|
|
913 |
|
max = 0; |
914 |
|
max_end = next; |
915 |
|
if (*next == OP_BRAZERO || *next == OP_BRAMINZERO) |
916 |
|
{ |
917 |
|
type = *next; |
918 |
|
while (1) |
919 |
{ |
{ |
920 |
if (size < 0) |
if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin) |
921 |
{ |
break; |
922 |
cc += -size; |
next_end = bracketend(next + 2 + LINK_SIZE); |
923 |
#ifdef SUPPORT_UTF |
if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0) |
924 |
if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); |
break; |
925 |
#endif |
next = next_end; |
926 |
} |
max++; |
|
else |
|
|
cc += size; |
|
927 |
} |
} |
928 |
|
|
929 |
if (bracketlen != 0) |
if (next[0] == type && next[1] == *begin && max >= 1) |
930 |
{ |
{ |
931 |
if (cc >= end) |
next_end = bracketend(next + 1); |
932 |
|
if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0) |
933 |
{ |
{ |
934 |
end = bracketend(cc); |
for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE) |
935 |
if (end[-1 - LINK_SIZE] == OP_KET) |
if (*next_end != OP_KET) |
936 |
end = NULL; |
break; |
937 |
|
|
938 |
|
if (i == max) |
939 |
|
{ |
940 |
|
common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end; |
941 |
|
common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO; |
942 |
|
/* +2 the original and the last. */ |
943 |
|
common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2; |
944 |
|
if (min == 1) |
945 |
|
return TRUE; |
946 |
|
min--; |
947 |
|
max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE); |
948 |
|
} |
949 |
} |
} |
|
cc += bracketlen; |
|
950 |
} |
} |
951 |
} |
} |
952 |
return private_data_length; |
|
953 |
|
if (min >= 3) |
954 |
|
{ |
955 |
|
common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end; |
956 |
|
common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT; |
957 |
|
common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min; |
958 |
|
return TRUE; |
959 |
|
} |
960 |
|
|
961 |
|
return FALSE; |
962 |
} |
} |
963 |
|
|
964 |
static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend) |
#define CASE_ITERATOR_PRIVATE_DATA_1 \ |
965 |
|
case OP_MINSTAR: \ |
966 |
|
case OP_MINPLUS: \ |
967 |
|
case OP_QUERY: \ |
968 |
|
case OP_MINQUERY: \ |
969 |
|
case OP_MINSTARI: \ |
970 |
|
case OP_MINPLUSI: \ |
971 |
|
case OP_QUERYI: \ |
972 |
|
case OP_MINQUERYI: \ |
973 |
|
case OP_NOTMINSTAR: \ |
974 |
|
case OP_NOTMINPLUS: \ |
975 |
|
case OP_NOTQUERY: \ |
976 |
|
case OP_NOTMINQUERY: \ |
977 |
|
case OP_NOTMINSTARI: \ |
978 |
|
case OP_NOTMINPLUSI: \ |
979 |
|
case OP_NOTQUERYI: \ |
980 |
|
case OP_NOTMINQUERYI: |
981 |
|
|
982 |
|
#define CASE_ITERATOR_PRIVATE_DATA_2A \ |
983 |
|
case OP_STAR: \ |
984 |
|
case OP_PLUS: \ |
985 |
|
case OP_STARI: \ |
986 |
|
case OP_PLUSI: \ |
987 |
|
case OP_NOTSTAR: \ |
988 |
|
case OP_NOTPLUS: \ |
989 |
|
case OP_NOTSTARI: \ |
990 |
|
case OP_NOTPLUSI: |
991 |
|
|
992 |
|
#define CASE_ITERATOR_PRIVATE_DATA_2B \ |
993 |
|
case OP_UPTO: \ |
994 |
|
case OP_MINUPTO: \ |
995 |
|
case OP_UPTOI: \ |
996 |
|
case OP_MINUPTOI: \ |
997 |
|
case OP_NOTUPTO: \ |
998 |
|
case OP_NOTMINUPTO: \ |
999 |
|
case OP_NOTUPTOI: \ |
1000 |
|
case OP_NOTMINUPTOI: |
1001 |
|
|
1002 |
|
#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ |
1003 |
|
case OP_TYPEMINSTAR: \ |
1004 |
|
case OP_TYPEMINPLUS: \ |
1005 |
|
case OP_TYPEQUERY: \ |
1006 |
|
case OP_TYPEMINQUERY: |
1007 |
|
|
1008 |
|
#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ |
1009 |
|
case OP_TYPESTAR: \ |
1010 |
|
case OP_TYPEPLUS: |
1011 |
|
|
1012 |
|
#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ |
1013 |
|
case OP_TYPEUPTO: \ |
1014 |
|
case OP_TYPEMINUPTO: |
1015 |
|
|
1016 |
|
static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend) |
1017 |
{ |
{ |
1018 |
pcre_uchar *cc = common->start; |
pcre_uchar *cc = common->start; |
1019 |
pcre_uchar *alternative; |
pcre_uchar *alternative; |
1020 |
pcre_uchar *end = NULL; |
pcre_uchar *end = NULL; |
1021 |
|
int private_data_ptr = *private_data_start; |
1022 |
int space, size, bracketlen; |
int space, size, bracketlen; |
1023 |
|
|
1024 |
while (cc < ccend) |
while (cc < ccend) |
1026 |
space = 0; |
space = 0; |
1027 |
size = 0; |
size = 0; |
1028 |
bracketlen = 0; |
bracketlen = 0; |
1029 |
|
if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE) |
1030 |
|
return; |
1031 |
|
|
1032 |
|
if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND) |
1033 |
|
if (detect_repeat(common, cc)) |
1034 |
|
{ |
1035 |
|
/* These brackets are converted to repeats, so no global |
1036 |
|
based single character repeat is allowed. */ |
1037 |
|
if (cc >= end) |
1038 |
|
end = bracketend(cc); |
1039 |
|
} |
1040 |
|
|
1041 |
switch(*cc) |
switch(*cc) |
1042 |
{ |
{ |
1043 |
|
case OP_KET: |
1044 |
|
if (common->private_data_ptrs[cc + 1 - common->start] != 0) |
1045 |
|
{ |
1046 |
|
common->private_data_ptrs[cc - common->start] = private_data_ptr; |
1047 |
|
private_data_ptr += sizeof(sljit_sw); |
1048 |
|
cc += common->private_data_ptrs[cc + 1 - common->start]; |
1049 |
|
} |
1050 |
|
cc += 1 + LINK_SIZE; |
1051 |
|
break; |
1052 |
|
|
1053 |
case OP_ASSERT: |
case OP_ASSERT: |
1054 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
1055 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
1143 |
break; |
break; |
1144 |
} |
} |
1145 |
|
|
1146 |
|
/* Character iterators, which are not inside a repeated bracket, |
1147 |
|
gets a private slot instead of allocating it on the stack. */ |
1148 |
if (space > 0 && cc >= end) |
if (space > 0 && cc >= end) |
1149 |
{ |
{ |
1150 |
common->private_data_ptrs[cc - common->start] = private_data_ptr; |
common->private_data_ptrs[cc - common->start] = private_data_ptr; |
1175 |
cc += bracketlen; |
cc += bracketlen; |
1176 |
} |
} |
1177 |
} |
} |
1178 |
|
*private_data_start = private_data_ptr; |
1179 |
} |
} |
1180 |
|
|
1181 |
/* Returns with a frame_types (always < 0) if no need for frame. */ |
/* Returns with a frame_types (always < 0) if no need for frame. */ |
1182 |
static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive) |
static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head) |
1183 |
{ |
{ |
|
pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE); |
|
1184 |
int length = 0; |
int length = 0; |
1185 |
int possessive = 0; |
int possessive = 0; |
1186 |
BOOL stack_restore = FALSE; |
BOOL stack_restore = FALSE; |
1189 |
/* The last capture is a local variable even for recursions. */ |
/* The last capture is a local variable even for recursions. */ |
1190 |
BOOL capture_last_found = FALSE; |
BOOL capture_last_found = FALSE; |
1191 |
|
|
1192 |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD |
1193 |
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
1194 |
|
*needs_control_head = TRUE; |
1195 |
|
#else |
1196 |
|
*needs_control_head = FALSE; |
1197 |
|
#endif |
1198 |
|
|
1199 |
|
if (ccend == NULL) |
1200 |
{ |
{ |
1201 |
possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; |
ccend = bracketend(cc) - (1 + LINK_SIZE); |
1202 |
/* This is correct regardless of common->capture_last_ptr. */ |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
1203 |
capture_last_found = TRUE; |
{ |
1204 |
|
possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; |
1205 |
|
/* This is correct regardless of common->capture_last_ptr. */ |
1206 |
|
capture_last_found = TRUE; |
1207 |
|
} |
1208 |
|
cc = next_opcode(common, cc); |
1209 |
} |
} |
1210 |
|
|
|
cc = next_opcode(common, cc); |
|
1211 |
SLJIT_ASSERT(cc != NULL); |
SLJIT_ASSERT(cc != NULL); |
1212 |
while (cc < ccend) |
while (cc < ccend) |
1213 |
switch(*cc) |
switch(*cc) |
1225 |
|
|
1226 |
case OP_MARK: |
case OP_MARK: |
1227 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
1228 |
|
case OP_THEN_ARG: |
1229 |
SLJIT_ASSERT(common->mark_ptr != 0); |
SLJIT_ASSERT(common->mark_ptr != 0); |
1230 |
stack_restore = TRUE; |
stack_restore = TRUE; |
1231 |
if (!setmark_found) |
if (!setmark_found) |
1233 |
length += 2; |
length += 2; |
1234 |
setmark_found = TRUE; |
setmark_found = TRUE; |
1235 |
} |
} |
1236 |
|
if (common->control_head_ptr != 0) |
1237 |
|
*needs_control_head = TRUE; |
1238 |
cc += 1 + 2 + cc[1]; |
cc += 1 + 2 + cc[1]; |
1239 |
break; |
break; |
1240 |
|
|
1354 |
return stack_restore ? no_frame : no_stack; |
return stack_restore ? no_frame : no_stack; |
1355 |
} |
} |
1356 |
|
|
1357 |
static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive) |
static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive) |
1358 |
{ |
{ |
1359 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
|
pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE); |
|
1360 |
BOOL setsom_found = recursive; |
BOOL setsom_found = recursive; |
1361 |
BOOL setmark_found = recursive; |
BOOL setmark_found = recursive; |
1362 |
/* The last capture is a local variable even for recursions. */ |
/* The last capture is a local variable even for recursions. */ |
1368 |
SLJIT_ASSERT(stackpos >= stacktop + 2); |
SLJIT_ASSERT(stackpos >= stacktop + 2); |
1369 |
|
|
1370 |
stackpos = STACK(stackpos); |
stackpos = STACK(stackpos); |
1371 |
if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) |
if (ccend == NULL) |
1372 |
cc = next_opcode(common, cc); |
{ |
1373 |
|
ccend = bracketend(cc) - (1 + LINK_SIZE); |
1374 |
|
if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) |
1375 |
|
cc = next_opcode(common, cc); |
1376 |
|
} |
1377 |
|
|
1378 |
SLJIT_ASSERT(cc != NULL); |
SLJIT_ASSERT(cc != NULL); |
1379 |
while (cc < ccend) |
while (cc < ccend) |
1380 |
switch(*cc) |
switch(*cc) |
1395 |
|
|
1396 |
case OP_MARK: |
case OP_MARK: |
1397 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
1398 |
|
case OP_THEN_ARG: |
1399 |
SLJIT_ASSERT(common->mark_ptr != 0); |
SLJIT_ASSERT(common->mark_ptr != 0); |
1400 |
if (!setmark_found) |
if (!setmark_found) |
1401 |
{ |
{ |
1476 |
SLJIT_ASSERT(stackpos == STACK(stacktop)); |
SLJIT_ASSERT(stackpos == STACK(stacktop)); |
1477 |
} |
} |
1478 |
|
|
1479 |
static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) |
static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head) |
1480 |
{ |
{ |
1481 |
int private_data_length = common->control_head_ptr ? 3 : 2; |
int private_data_length = needs_control_head ? 3 : 2; |
1482 |
int size; |
int size; |
1483 |
pcre_uchar *alternative; |
pcre_uchar *alternative; |
1484 |
/* Calculate the sum of the private machine words. */ |
/* Calculate the sum of the private machine words. */ |
1487 |
size = 0; |
size = 0; |
1488 |
switch(*cc) |
switch(*cc) |
1489 |
{ |
{ |
1490 |
|
case OP_KET: |
1491 |
|
if (PRIVATE_DATA(cc) != 0) |
1492 |
|
private_data_length++; |
1493 |
|
cc += 1 + LINK_SIZE; |
1494 |
|
break; |
1495 |
|
|
1496 |
case OP_ASSERT: |
case OP_ASSERT: |
1497 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
1498 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
1597 |
} |
} |
1598 |
|
|
1599 |
static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, |
static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, |
1600 |
BOOL save, int stackptr, int stacktop) |
BOOL save, int stackptr, int stacktop, BOOL needs_control_head) |
1601 |
{ |
{ |
1602 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
1603 |
int srcw[2]; |
int srcw[2]; |
1618 |
|
|
1619 |
if (!save) |
if (!save) |
1620 |
{ |
{ |
1621 |
stackptr += (common->control_head_ptr ? 2 : 1) * sizeof(sljit_sw); |
stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw); |
1622 |
if (stackptr < stacktop) |
if (stackptr < stacktop) |
1623 |
{ |
{ |
1624 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); |
1643 |
SLJIT_ASSERT(save && common->recursive_head_ptr != 0); |
SLJIT_ASSERT(save && common->recursive_head_ptr != 0); |
1644 |
count = 1; |
count = 1; |
1645 |
srcw[0] = common->recursive_head_ptr; |
srcw[0] = common->recursive_head_ptr; |
1646 |
if (common->control_head_ptr != 0) |
if (needs_control_head) |
1647 |
{ |
{ |
1648 |
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
1649 |
count = 2; |
count = 2; |
1650 |
srcw[1] = common->control_head_ptr; |
srcw[1] = common->control_head_ptr; |
1651 |
} |
} |
1661 |
|
|
1662 |
switch(*cc) |
switch(*cc) |
1663 |
{ |
{ |
1664 |
|
case OP_KET: |
1665 |
|
if (PRIVATE_DATA(cc) != 0) |
1666 |
|
{ |
1667 |
|
count = 1; |
1668 |
|
srcw[0] = PRIVATE_DATA(cc); |
1669 |
|
} |
1670 |
|
cc += 1 + LINK_SIZE; |
1671 |
|
break; |
1672 |
|
|
1673 |
case OP_ASSERT: |
case OP_ASSERT: |
1674 |
case OP_ASSERT_NOT: |
case OP_ASSERT_NOT: |
1675 |
case OP_ASSERTBACK: |
case OP_ASSERTBACK: |
1916 |
SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); |
SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); |
1917 |
} |
} |
1918 |
|
|
1919 |
|
static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset) |
1920 |
|
{ |
1921 |
|
pcre_uchar *end = bracketend(cc); |
1922 |
|
BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; |
1923 |
|
|
1924 |
|
/* Assert captures then. */ |
1925 |
|
if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) |
1926 |
|
current_offset = NULL; |
1927 |
|
/* Conditional block does not. */ |
1928 |
|
if (*cc == OP_COND || *cc == OP_SCOND) |
1929 |
|
has_alternatives = FALSE; |
1930 |
|
|
1931 |
|
cc = next_opcode(common, cc); |
1932 |
|
if (has_alternatives) |
1933 |
|
current_offset = common->then_offsets + (cc - common->start); |
1934 |
|
|
1935 |
|
while (cc < end) |
1936 |
|
{ |
1937 |
|
if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) |
1938 |
|
cc = set_then_offsets(common, cc, current_offset); |
1939 |
|
else |
1940 |
|
{ |
1941 |
|
if (*cc == OP_ALT && has_alternatives) |
1942 |
|
current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); |
1943 |
|
if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) |
1944 |
|
*current_offset = 1; |
1945 |
|
cc = next_opcode(common, cc); |
1946 |
|
} |
1947 |
|
} |
1948 |
|
|
1949 |
|
return end; |
1950 |
|
} |
1951 |
|
|
1952 |
#undef CASE_ITERATOR_PRIVATE_DATA_1 |
#undef CASE_ITERATOR_PRIVATE_DATA_1 |
1953 |
#undef CASE_ITERATOR_PRIVATE_DATA_2A |
#undef CASE_ITERATOR_PRIVATE_DATA_2A |
1954 |
#undef CASE_ITERATOR_PRIVATE_DATA_2B |
#undef CASE_ITERATOR_PRIVATE_DATA_2B |
2012 |
common->stubs = NULL; |
common->stubs = NULL; |
2013 |
} |
} |
2014 |
|
|
2015 |
static SLJIT_INLINE void decrease_call_count(compiler_common *common) |
static SLJIT_INLINE void count_match(compiler_common *common) |
2016 |
{ |
{ |
2017 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
2018 |
|
|
2019 |
OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); |
OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); |
2020 |
add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); |
add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); |
2021 |
} |
} |
2022 |
|
|
2096 |
OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); |
2097 |
if (common->mark_ptr != 0) |
if (common->mark_ptr != 0) |
2098 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0); |
2099 |
SLJIT_ASSERT(common->control_head_ptr != 0); |
if (common->control_head_ptr != 0) |
2100 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); |
2101 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); |
2102 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr); |
2103 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base)); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base)); |
2104 |
} |
} |
2105 |
|
|
2106 |
static sljit_sw do_check_control_chain(sljit_sw *current) |
static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg) |
2107 |
{ |
{ |
2108 |
sljit_sw return_value = 0; |
while (current != NULL) |
|
|
|
|
SLJIT_ASSERT(current != NULL); |
|
|
do |
|
2109 |
{ |
{ |
2110 |
switch (current[-2]) |
switch (current[-2]) |
2111 |
{ |
{ |
2112 |
case type_commit: |
case type_then_trap: |
|
/* Commit overwrites all. */ |
|
|
return -1; |
|
|
|
|
|
case type_prune: |
|
2113 |
break; |
break; |
2114 |
|
|
2115 |
case type_skip: |
case type_mark: |
2116 |
/* Overwrites prune, but not other skips. */ |
if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0) |
2117 |
if (return_value == 0) |
return current[-4]; |
|
return_value = current[-3]; |
|
2118 |
break; |
break; |
2119 |
|
|
2120 |
default: |
default: |
2123 |
} |
} |
2124 |
current = (sljit_sw*)current[-1]; |
current = (sljit_sw*)current[-1]; |
2125 |
} |
} |
2126 |
while (current != NULL); |
return -1; |
|
return return_value; |
|
2127 |
} |
} |
2128 |
|
|
2129 |
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) |
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) |
2195 |
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); |
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); |
2196 |
|
|
2197 |
jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3); |
jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3); |
2198 |
OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0); |
OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0); |
2199 |
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 |
2200 |
OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); |
OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); |
2201 |
#endif |
#endif |
2363 |
|
|
2364 |
static void check_partial(compiler_common *common, BOOL force) |
static void check_partial(compiler_common *common, BOOL force) |
2365 |
{ |
{ |
2366 |
/* Checks whether a partial matching is occured. Does not modify registers. */ |
/* Checks whether a partial matching is occurred. Does not modify registers. */ |
2367 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
2368 |
struct sljit_jump *jump = NULL; |
struct sljit_jump *jump = NULL; |
2369 |
|
|
4306 |
|
|
4307 |
case PT_SPACE: |
case PT_SPACE: |
4308 |
case PT_PXSPACE: |
case PT_PXSPACE: |
|
if (*cc == PT_SPACE) |
|
|
{ |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); |
|
|
jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset); |
|
|
} |
|
4309 |
SET_CHAR_OFFSET(9); |
SET_CHAR_OFFSET(9); |
4310 |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); |
4311 |
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); |
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); |
|
if (*cc == PT_SPACE) |
|
|
JUMPHERE(jump); |
|
4312 |
|
|
4313 |
SET_TYPE_OFFSET(ucp_Zl); |
SET_TYPE_OFFSET(ucp_Zl); |
4314 |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); |
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); |
5275 |
JUMPHERE(zerolength); |
JUMPHERE(zerolength); |
5276 |
BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); |
BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); |
5277 |
|
|
5278 |
decrease_call_count(common); |
count_match(common); |
5279 |
return cc; |
return cc; |
5280 |
} |
} |
5281 |
|
|
5314 |
JUMPHERE(jump); |
JUMPHERE(jump); |
5315 |
JUMPHERE(zerolength); |
JUMPHERE(zerolength); |
5316 |
|
|
5317 |
decrease_call_count(common); |
count_match(common); |
5318 |
return cc; |
return cc; |
5319 |
} |
} |
5320 |
|
|
5324 |
backtrack_common *backtrack; |
backtrack_common *backtrack; |
5325 |
recurse_entry *entry = common->entries; |
recurse_entry *entry = common->entries; |
5326 |
recurse_entry *prev = NULL; |
recurse_entry *prev = NULL; |
5327 |
int start = GET(cc, 1); |
sljit_sw start = GET(cc, 1); |
5328 |
pcre_uchar *start_cc; |
pcre_uchar *start_cc; |
5329 |
|
BOOL needs_control_head; |
5330 |
|
|
5331 |
PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); |
PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); |
5332 |
|
|
5333 |
/* Inlining simple patterns. */ |
/* Inlining simple patterns. */ |
5334 |
if (get_framesize(common, common->start + start, TRUE) == no_stack) |
if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack) |
5335 |
{ |
{ |
5336 |
start_cc = common->start + start; |
start_cc = common->start + start; |
5337 |
compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack); |
compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack); |
5491 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
5492 |
int framesize; |
int framesize; |
5493 |
int extrasize; |
int extrasize; |
5494 |
BOOL needs_control_head = common->control_head_ptr != 0; |
BOOL needs_control_head; |
5495 |
int private_data_ptr; |
int private_data_ptr; |
5496 |
backtrack_common altbacktrack; |
backtrack_common altbacktrack; |
5497 |
pcre_uchar *ccbegin; |
pcre_uchar *ccbegin; |
5501 |
jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; |
jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; |
5502 |
jump_list **found; |
jump_list **found; |
5503 |
/* Saving previous accept variables. */ |
/* Saving previous accept variables. */ |
5504 |
|
BOOL save_local_exit = common->local_exit; |
5505 |
|
BOOL save_positive_assert = common->positive_assert; |
5506 |
|
then_trap_backtrack *save_then_trap = common->then_trap; |
5507 |
struct sljit_label *save_quit_label = common->quit_label; |
struct sljit_label *save_quit_label = common->quit_label; |
5508 |
struct sljit_label *save_accept_label = common->accept_label; |
struct sljit_label *save_accept_label = common->accept_label; |
5509 |
jump_list *save_quit = common->quit; |
jump_list *save_quit = common->quit; |
5510 |
|
jump_list *save_positive_assert_quit = common->positive_assert_quit; |
5511 |
jump_list *save_accept = common->accept; |
jump_list *save_accept = common->accept; |
|
BOOL save_local_exit = common->local_exit; |
|
5512 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
5513 |
struct sljit_jump *brajump = NULL; |
struct sljit_jump *brajump = NULL; |
5514 |
|
|
5515 |
|
/* Assert captures then. */ |
5516 |
|
common->then_trap = NULL; |
5517 |
|
|
5518 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
5519 |
{ |
{ |
5520 |
SLJIT_ASSERT(!conditional); |
SLJIT_ASSERT(!conditional); |
5523 |
} |
} |
5524 |
private_data_ptr = PRIVATE_DATA(cc); |
private_data_ptr = PRIVATE_DATA(cc); |
5525 |
SLJIT_ASSERT(private_data_ptr != 0); |
SLJIT_ASSERT(private_data_ptr != 0); |
5526 |
framesize = get_framesize(common, cc, FALSE); |
framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); |
5527 |
backtrack->framesize = framesize; |
backtrack->framesize = framesize; |
5528 |
backtrack->private_data_ptr = private_data_ptr; |
backtrack->private_data_ptr = private_data_ptr; |
5529 |
opcode = *cc; |
opcode = *cc; |
5543 |
if (framesize < 0) |
if (framesize < 0) |
5544 |
{ |
{ |
5545 |
extrasize = needs_control_head ? 2 : 1; |
extrasize = needs_control_head ? 2 : 1; |
5546 |
if (framesize != no_stack) |
if (framesize == no_frame) |
5547 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
5548 |
allocate_stack(common, extrasize); |
allocate_stack(common, extrasize); |
5549 |
if (needs_control_head) |
if (needs_control_head) |
5573 |
} |
} |
5574 |
else |
else |
5575 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
5576 |
init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE); |
init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); |
5577 |
} |
} |
5578 |
|
|
5579 |
memset(&altbacktrack, 0, sizeof(backtrack_common)); |
memset(&altbacktrack, 0, sizeof(backtrack_common)); |
5580 |
common->local_exit = TRUE; |
if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) |
5581 |
common->quit_label = NULL; |
{ |
5582 |
common->quit = NULL; |
/* Negative assert is stronger than positive assert. */ |
5583 |
|
common->local_exit = TRUE; |
5584 |
|
common->quit_label = NULL; |
5585 |
|
common->quit = NULL; |
5586 |
|
common->positive_assert = FALSE; |
5587 |
|
} |
5588 |
|
else |
5589 |
|
common->positive_assert = TRUE; |
5590 |
|
common->positive_assert_quit = NULL; |
5591 |
|
|
5592 |
while (1) |
while (1) |
5593 |
{ |
{ |
5594 |
common->accept_label = NULL; |
common->accept_label = NULL; |
5603 |
compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); |
compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); |
5604 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
5605 |
{ |
{ |
5606 |
common->local_exit = save_local_exit; |
if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) |
5607 |
common->quit_label = save_quit_label; |
{ |
5608 |
|
common->local_exit = save_local_exit; |
5609 |
|
common->quit_label = save_quit_label; |
5610 |
|
common->quit = save_quit; |
5611 |
|
} |
5612 |
|
common->positive_assert = save_positive_assert; |
5613 |
|
common->then_trap = save_then_trap; |
5614 |
common->accept_label = save_accept_label; |
common->accept_label = save_accept_label; |
5615 |
common->quit = save_quit; |
common->positive_assert_quit = save_positive_assert_quit; |
5616 |
common->accept = save_accept; |
common->accept = save_accept; |
5617 |
return NULL; |
return NULL; |
5618 |
} |
} |
5623 |
/* Reset stack. */ |
/* Reset stack. */ |
5624 |
if (framesize < 0) |
if (framesize < 0) |
5625 |
{ |
{ |
5626 |
if (framesize != no_stack) |
if (framesize == no_frame) |
5627 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
5628 |
else |
else |
5629 |
free_stack(common, extrasize); |
free_stack(common, extrasize); |
5677 |
compile_backtrackingpath(common, altbacktrack.top); |
compile_backtrackingpath(common, altbacktrack.top); |
5678 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
5679 |
{ |
{ |
5680 |
common->local_exit = save_local_exit; |
if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) |
5681 |
common->quit_label = save_quit_label; |
{ |
5682 |
|
common->local_exit = save_local_exit; |
5683 |
|
common->quit_label = save_quit_label; |
5684 |
|
common->quit = save_quit; |
5685 |
|
} |
5686 |
|
common->positive_assert = save_positive_assert; |
5687 |
|
common->then_trap = save_then_trap; |
5688 |
common->accept_label = save_accept_label; |
common->accept_label = save_accept_label; |
5689 |
common->quit = save_quit; |
common->positive_assert_quit = save_positive_assert_quit; |
5690 |
common->accept = save_accept; |
common->accept = save_accept; |
5691 |
return NULL; |
return NULL; |
5692 |
} |
} |
5699 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
5700 |
} |
} |
5701 |
|
|
5702 |
|
if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) |
5703 |
|
{ |
5704 |
|
SLJIT_ASSERT(common->positive_assert_quit == NULL); |
5705 |
|
/* Makes the check less complicated below. */ |
5706 |
|
common->positive_assert_quit = common->quit; |
5707 |
|
} |
5708 |
|
|
5709 |
/* None of them matched. */ |
/* None of them matched. */ |
5710 |
if (common->quit != NULL) |
if (common->positive_assert_quit != NULL) |
5711 |
{ |
{ |
5712 |
jump = JUMP(SLJIT_JUMP); |
jump = JUMP(SLJIT_JUMP); |
5713 |
set_jumps(common->quit, LABEL()); |
set_jumps(common->positive_assert_quit, LABEL()); |
5714 |
SLJIT_ASSERT(framesize != no_stack); |
SLJIT_ASSERT(framesize != no_stack); |
5715 |
if (framesize < 0) |
if (framesize < 0) |
5716 |
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw)); |
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw)); |
5870 |
} |
} |
5871 |
} |
} |
5872 |
|
|
5873 |
common->local_exit = save_local_exit; |
if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT) |
5874 |
common->quit_label = save_quit_label; |
{ |
5875 |
|
common->local_exit = save_local_exit; |
5876 |
|
common->quit_label = save_quit_label; |
5877 |
|
common->quit = save_quit; |
5878 |
|
} |
5879 |
|
common->positive_assert = save_positive_assert; |
5880 |
|
common->then_trap = save_then_trap; |
5881 |
common->accept_label = save_accept_label; |
common->accept_label = save_accept_label; |
5882 |
common->quit = save_quit; |
common->positive_assert_quit = save_positive_assert_quit; |
5883 |
common->accept = save_accept; |
common->accept = save_accept; |
5884 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
5885 |
} |
} |
5886 |
|
|
5887 |
static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table) |
static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head) |
5888 |
{ |
{ |
5889 |
int condition = FALSE; |
DEFINE_COMPILER; |
5890 |
pcre_uchar *slotA = name_table; |
int stacksize; |
|
pcre_uchar *slotB; |
|
|
sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; |
|
|
sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; |
|
|
sljit_sw no_capture; |
|
|
int i; |
|
|
|
|
|
locals += refno & 0xff; |
|
|
refno >>= 8; |
|
|
no_capture = locals[1]; |
|
5891 |
|
|
5892 |
for (i = 0; i < name_count; i++) |
if (framesize < 0) |
5893 |
{ |
{ |
5894 |
if (GET2(slotA, 0) == refno) break; |
if (framesize == no_frame) |
5895 |
slotA += name_entry_size; |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
5896 |
} |
else |
5897 |
|
{ |
5898 |
|
stacksize = needs_control_head ? 1 : 0; |
5899 |
|
if (ket != OP_KET || has_alternatives) |
5900 |
|
stacksize++; |
5901 |
|
free_stack(common, stacksize); |
5902 |
|
} |
5903 |
|
|
5904 |
if (i < name_count) |
if (needs_control_head) |
5905 |
{ |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0); |
|
/* Found a name for the number - there can be only one; duplicate names |
|
|
for different numbers are allowed, but not vice versa. First scan down |
|
|
for duplicates. */ |
|
5906 |
|
|
5907 |
slotB = slotA; |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
5908 |
while (slotB > name_table) |
if (ket == OP_KETRMAX) |
5909 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); |
5910 |
|
else if (ket == OP_KETRMIN) |
5911 |
{ |
{ |
5912 |
slotB -= name_entry_size; |
/* Move the STR_PTR to the private_data_ptr. */ |
5913 |
if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); |
|
{ |
|
|
condition = locals[GET2(slotB, 0) << 1] != no_capture; |
|
|
if (condition) break; |
|
|
} |
|
|
else break; |
|
5914 |
} |
} |
5915 |
|
} |
5916 |
|
else |
5917 |
|
{ |
5918 |
|
stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1; |
5919 |
|
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw)); |
5920 |
|
if (needs_control_head) |
5921 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0); |
5922 |
|
|
5923 |
/* Scan up for duplicates */ |
if (ket == OP_KETRMAX) |
|
if (!condition) |
|
5924 |
{ |
{ |
5925 |
slotB = slotA; |
/* TMP2 which is set here used by OP_KETRMAX below. */ |
5926 |
for (i++; i < name_count; i++) |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
|
{ |
|
|
slotB += name_entry_size; |
|
|
if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
|
|
{ |
|
|
condition = locals[GET2(slotB, 0) << 1] != no_capture; |
|
|
if (condition) break; |
|
|
} |
|
|
else break; |
|
|
} |
|
5927 |
} |
} |
5928 |
} |
} |
5929 |
return condition; |
if (needs_control_head) |
5930 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0); |
5931 |
} |
} |
5932 |
|
|
5933 |
static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table) |
static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr) |
5934 |
{ |
{ |
5935 |
int condition = FALSE; |
DEFINE_COMPILER; |
|
pcre_uchar *slotA = name_table; |
|
|
pcre_uchar *slotB; |
|
|
sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; |
|
|
sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; |
|
|
sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)]; |
|
|
sljit_uw i; |
|
5936 |
|
|
5937 |
for (i = 0; i < name_count; i++) |
if (common->capture_last_ptr != 0) |
5938 |
{ |
{ |
5939 |
if (GET2(slotA, 0) == recno) break; |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); |
5940 |
slotA += name_entry_size; |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1); |
5941 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
5942 |
|
stacksize++; |
5943 |
} |
} |
5944 |
|
if (common->optimized_cbracket[offset >> 1] == 0) |
|
if (i < name_count) |
|
5945 |
{ |
{ |
5946 |
/* Found a name for the number - there can be only one; duplicate |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
5947 |
names for different numbers are allowed, but not vice versa. First |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
5948 |
scan down for duplicates. */ |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
5949 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
5950 |
slotB = slotA; |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); |
5951 |
while (slotB > name_table) |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); |
5952 |
{ |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); |
5953 |
slotB -= name_entry_size; |
stacksize += 2; |
|
if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
|
|
{ |
|
|
condition = GET2(slotB, 0) == group_num; |
|
|
if (condition) break; |
|
|
} |
|
|
else break; |
|
|
} |
|
|
|
|
|
/* Scan up for duplicates */ |
|
|
if (!condition) |
|
|
{ |
|
|
slotB = slotA; |
|
|
for (i++; i < name_count; i++) |
|
|
{ |
|
|
slotB += name_entry_size; |
|
|
if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0) |
|
|
{ |
|
|
condition = GET2(slotB, 0) == group_num; |
|
|
if (condition) break; |
|
|
} |
|
|
else break; |
|
|
} |
|
|
} |
|
5954 |
} |
} |
5955 |
return condition; |
return stacksize; |
5956 |
} |
} |
5957 |
|
|
5958 |
/* |
/* |
6016 |
pcre_uchar opcode; |
pcre_uchar opcode; |
6017 |
int private_data_ptr = 0; |
int private_data_ptr = 0; |
6018 |
int offset = 0; |
int offset = 0; |
6019 |
int stacksize; |
int i, stacksize; |
6020 |
|
int repeat_ptr = 0, repeat_length = 0; |
6021 |
|
int repeat_type = 0, repeat_count = 0; |
6022 |
pcre_uchar *ccbegin; |
pcre_uchar *ccbegin; |
6023 |
pcre_uchar *matchingpath; |
pcre_uchar *matchingpath; |
6024 |
|
pcre_uchar *slot; |
6025 |
pcre_uchar bra = OP_BRA; |
pcre_uchar bra = OP_BRA; |
6026 |
pcre_uchar ket; |
pcre_uchar ket; |
6027 |
assert_backtrack *assert; |
assert_backtrack *assert; |
6028 |
BOOL has_alternatives; |
BOOL has_alternatives; |
6029 |
|
BOOL needs_control_head = FALSE; |
6030 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
6031 |
struct sljit_jump *skip; |
struct sljit_jump *skip; |
6032 |
struct sljit_label *rmaxlabel = NULL; |
struct sljit_label *rmax_label = NULL; |
6033 |
struct sljit_jump *braminzerojump = NULL; |
struct sljit_jump *braminzero = NULL; |
6034 |
|
|
6035 |
PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); |
PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL); |
6036 |
|
|
6043 |
|
|
6044 |
opcode = *cc; |
opcode = *cc; |
6045 |
ccbegin = cc; |
ccbegin = cc; |
6046 |
matchingpath = ccbegin + 1 + LINK_SIZE; |
matchingpath = bracketend(cc) - 1 - LINK_SIZE; |
6047 |
|
ket = *matchingpath; |
6048 |
|
if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0) |
6049 |
|
{ |
6050 |
|
repeat_ptr = PRIVATE_DATA(matchingpath); |
6051 |
|
repeat_length = PRIVATE_DATA(matchingpath + 1); |
6052 |
|
repeat_type = PRIVATE_DATA(matchingpath + 2); |
6053 |
|
repeat_count = PRIVATE_DATA(matchingpath + 3); |
6054 |
|
SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0); |
6055 |
|
if (repeat_type == OP_UPTO) |
6056 |
|
ket = OP_KETRMAX; |
6057 |
|
if (repeat_type == OP_MINUPTO) |
6058 |
|
ket = OP_KETRMIN; |
6059 |
|
} |
6060 |
|
|
6061 |
if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) |
if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) |
6062 |
{ |
{ |
6063 |
/* Drop this bracket_backtrack. */ |
/* Drop this bracket_backtrack. */ |
6064 |
parent->top = backtrack->prev; |
parent->top = backtrack->prev; |
6065 |
return bracketend(cc); |
return matchingpath + 1 + LINK_SIZE + repeat_length; |
6066 |
} |
} |
6067 |
|
|
6068 |
ket = *(bracketend(cc) - 1 - LINK_SIZE); |
matchingpath = ccbegin + 1 + LINK_SIZE; |
6069 |
SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); |
SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN); |
6070 |
SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); |
SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX))); |
6071 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
6072 |
|
|
6073 |
has_alternatives = *cc == OP_ALT; |
has_alternatives = *cc == OP_ALT; |
6074 |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND)) |
6075 |
{ |
has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE; |
|
has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE; |
|
|
if (*matchingpath == OP_NRREF) |
|
|
{ |
|
|
stacksize = GET2(matchingpath, 1); |
|
|
if (common->currententry == NULL || stacksize == RREF_ANY) |
|
|
has_alternatives = FALSE; |
|
|
else if (common->currententry->start == 0) |
|
|
has_alternatives = stacksize != 0; |
|
|
else |
|
|
has_alternatives = stacksize != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); |
|
|
} |
|
|
} |
|
6076 |
|
|
6077 |
if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) |
if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN)) |
6078 |
opcode = OP_SCOND; |
opcode = OP_SCOND; |
6103 |
SLJIT_ASSERT(private_data_ptr != 0); |
SLJIT_ASSERT(private_data_ptr != 0); |
6104 |
BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; |
BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; |
6105 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
6106 |
BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); |
BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head); |
6107 |
} |
} |
6108 |
|
|
6109 |
/* Instructions before the first alternative. */ |
/* Instructions before the first alternative. */ |
6110 |
stacksize = 0; |
stacksize = 0; |
6111 |
if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) |
if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) |
6112 |
stacksize++; |
stacksize++; |
6113 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
6114 |
stacksize++; |
stacksize++; |
6117 |
allocate_stack(common, stacksize); |
allocate_stack(common, stacksize); |
6118 |
|
|
6119 |
stacksize = 0; |
stacksize = 0; |
6120 |
if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) |
if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO)) |
6121 |
{ |
{ |
6122 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); |
6123 |
stacksize++; |
stacksize++; |
6133 |
if (ket != OP_KETRMIN) |
if (ket != OP_KETRMIN) |
6134 |
{ |
{ |
6135 |
free_stack(common, 1); |
free_stack(common, 1); |
6136 |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); |
6137 |
} |
} |
6138 |
else |
else |
6139 |
{ |
{ |
6148 |
if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
6149 |
{ |
{ |
6150 |
/* When we come from outside, private_data_ptr contains the previous STR_PTR. */ |
/* When we come from outside, private_data_ptr contains the previous STR_PTR. */ |
6151 |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
6152 |
} |
} |
6153 |
else |
else |
6154 |
{ |
{ |
6155 |
/* Except when the whole stack frame must be saved. */ |
/* Except when the whole stack frame must be saved. */ |
6156 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
6157 |
braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); |
braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); |
6158 |
} |
} |
6159 |
JUMPHERE(skip); |
JUMPHERE(skip); |
6160 |
} |
} |
6167 |
} |
} |
6168 |
} |
} |
6169 |
|
|
6170 |
|
if (repeat_type != 0) |
6171 |
|
{ |
6172 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count); |
6173 |
|
if (repeat_type == OP_EXACT) |
6174 |
|
rmax_label = LABEL(); |
6175 |
|
} |
6176 |
|
|
6177 |
if (ket == OP_KETRMIN) |
if (ket == OP_KETRMIN) |
6178 |
BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); |
6179 |
|
|
6180 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
6181 |
{ |
{ |
6182 |
rmaxlabel = LABEL(); |
rmax_label = LABEL(); |
6183 |
if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) |
if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0) |
6184 |
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel; |
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label; |
6185 |
} |
} |
6186 |
|
|
6187 |
/* Handling capturing brackets and alternatives. */ |
/* Handling capturing brackets and alternatives. */ |
6188 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
6189 |
{ |
{ |
6190 |
|
stacksize = 0; |
6191 |
|
if (needs_control_head) |
6192 |
|
{ |
6193 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
6194 |
|
stacksize++; |
6195 |
|
} |
6196 |
|
|
6197 |
if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
6198 |
{ |
{ |
6199 |
/* Neither capturing brackets nor recursions are not found in the block. */ |
/* Neither capturing brackets nor recursions are found in the block. */ |
6200 |
if (ket == OP_KETRMIN) |
if (ket == OP_KETRMIN) |
6201 |
{ |
{ |
6202 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
stacksize += 2; |
6203 |
allocate_stack(common, 2); |
if (!needs_control_head) |
6204 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
|
|
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); |
|
6205 |
} |
} |
6206 |
else if (ket == OP_KETRMAX || has_alternatives) |
else |
6207 |
{ |
{ |
6208 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) |
6209 |
allocate_stack(common, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
6210 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
if (ket == OP_KETRMAX || has_alternatives) |
6211 |
|
stacksize++; |
6212 |
} |
} |
6213 |
else |
|
6214 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
if (stacksize > 0) |
6215 |
|
allocate_stack(common, stacksize); |
6216 |
|
|
6217 |
|
stacksize = 0; |
6218 |
|
if (needs_control_head) |
6219 |
|
{ |
6220 |
|
stacksize++; |
6221 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
6222 |
|
} |
6223 |
|
|
6224 |
|
if (ket == OP_KETRMIN) |
6225 |
|
{ |
6226 |
|
if (needs_control_head) |
6227 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
6228 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); |
6229 |
|
if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame) |
6230 |
|
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw)); |
6231 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0); |
6232 |
|
} |
6233 |
|
else if (ket == OP_KETRMAX || has_alternatives) |
6234 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); |
6235 |
} |
} |
6236 |
else |
else |
6237 |
{ |
{ |
6238 |
if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) |
if (ket != OP_KET || has_alternatives) |
6239 |
|
stacksize++; |
6240 |
|
|
6241 |
|
stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1; |
6242 |
|
allocate_stack(common, stacksize); |
6243 |
|
|
6244 |
|
if (needs_control_head) |
6245 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
6246 |
|
|
6247 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
6248 |
|
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); |
6249 |
|
|
6250 |
|
stacksize = needs_control_head ? 1 : 0; |
6251 |
|
if (ket != OP_KET || has_alternatives) |
6252 |
{ |
{ |
6253 |
allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0); |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
|
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1)); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
|
6254 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); |
6255 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
stacksize++; |
6256 |
init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
6257 |
} |
} |
6258 |
else |
else |
6259 |
{ |
{ |
|
allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
|
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize)); |
|
6260 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); |
6261 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
|
init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE); |
|
6262 |
} |
} |
6263 |
|
init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); |
6264 |
} |
} |
6265 |
} |
} |
6266 |
else if (opcode == OP_CBRA || opcode == OP_SCBRA) |
else if (opcode == OP_CBRA || opcode == OP_SCBRA) |
6309 |
CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); |
6310 |
matchingpath += 1 + IMM2_SIZE; |
matchingpath += 1 + IMM2_SIZE; |
6311 |
} |
} |
6312 |
else if (*matchingpath == OP_NCREF) |
else if (*matchingpath == OP_DNCREF) |
6313 |
{ |
{ |
6314 |
SLJIT_ASSERT(has_alternatives); |
SLJIT_ASSERT(has_alternatives); |
|
stacksize = GET2(matchingpath, 1); |
|
|
jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
|
|
|
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
|
|
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw))); |
|
|
GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table); |
|
|
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); |
|
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
|
|
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0)); |
|
6315 |
|
|
6316 |
JUMPHERE(jump); |
i = GET2(matchingpath, 1 + IMM2_SIZE); |
6317 |
matchingpath += 1 + IMM2_SIZE; |
slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; |
6318 |
|
OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); |
6319 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); |
6320 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); |
6321 |
|
slot += common->name_entry_size; |
6322 |
|
i--; |
6323 |
|
while (i-- > 0) |
6324 |
|
{ |
6325 |
|
OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0); |
6326 |
|
OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0); |
6327 |
|
slot += common->name_entry_size; |
6328 |
|
} |
6329 |
|
OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); |
6330 |
|
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO)); |
6331 |
|
matchingpath += 1 + 2 * IMM2_SIZE; |
6332 |
} |
} |
6333 |
else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF) |
else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) |
6334 |
{ |
{ |
6335 |
/* Never has other case. */ |
/* Never has other case. */ |
6336 |
BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; |
BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; |
6337 |
|
SLJIT_ASSERT(!has_alternatives); |
6338 |
|
|
6339 |
stacksize = GET2(matchingpath, 1); |
if (*matchingpath == OP_RREF) |
|
if (common->currententry == NULL) |
|
|
stacksize = 0; |
|
|
else if (stacksize == RREF_ANY) |
|
|
stacksize = 1; |
|
|
else if (common->currententry->start == 0) |
|
|
stacksize = stacksize == 0; |
|
|
else |
|
|
stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); |
|
|
|
|
|
if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL) |
|
6340 |
{ |
{ |
6341 |
SLJIT_ASSERT(!has_alternatives); |
stacksize = GET2(matchingpath, 1); |
6342 |
|
if (common->currententry == NULL) |
6343 |
|
stacksize = 0; |
6344 |
|
else if (stacksize == RREF_ANY) |
6345 |
|
stacksize = 1; |
6346 |
|
else if (common->currententry->start == 0) |
6347 |
|
stacksize = stacksize == 0; |
6348 |
|
else |
6349 |
|
stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); |
6350 |
|
|
6351 |
if (stacksize != 0) |
if (stacksize != 0) |
6352 |
matchingpath += 1 + IMM2_SIZE; |
matchingpath += 1 + IMM2_SIZE; |
6353 |
|
} |
6354 |
|
else |
6355 |
|
{ |
6356 |
|
if (common->currententry == NULL || common->currententry->start == 0) |
6357 |
|
stacksize = 0; |
6358 |
else |
else |
6359 |
{ |
{ |
6360 |
|
stacksize = GET2(matchingpath, 1 + IMM2_SIZE); |
6361 |
|
slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size; |
6362 |
|
i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); |
6363 |
|
while (stacksize > 0) |
6364 |
|
{ |
6365 |
|
if (GET2(slot, 0) == i) |
6366 |
|
break; |
6367 |
|
slot += common->name_entry_size; |
6368 |
|
stacksize--; |
6369 |
|
} |
6370 |
|
} |
6371 |
|
|
6372 |
|
if (stacksize != 0) |
6373 |
|
matchingpath += 1 + 2 * IMM2_SIZE; |
6374 |
|
} |
6375 |
|
|
6376 |
|
/* The stacksize == 0 is a common "else" case. */ |
6377 |
|
if (stacksize == 0) |
6378 |
|
{ |
6379 |
if (*cc == OP_ALT) |
if (*cc == OP_ALT) |
6380 |
{ |
{ |
6381 |
matchingpath = cc + 1 + LINK_SIZE; |
matchingpath = cc + 1 + LINK_SIZE; |
6384 |
else |
else |
6385 |
matchingpath = cc; |
matchingpath = cc; |
6386 |
} |
} |
|
} |
|
|
else |
|
|
{ |
|
|
SLJIT_ASSERT(has_alternatives); |
|
|
|
|
|
stacksize = GET2(matchingpath, 1); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); |
|
|
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize); |
|
|
GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table); |
|
|
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); |
|
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); |
|
|
add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0)); |
|
|
matchingpath += 1 + IMM2_SIZE; |
|
|
} |
|
6387 |
} |
} |
6388 |
else |
else |
6389 |
{ |
{ |
6404 |
return NULL; |
return NULL; |
6405 |
|
|
6406 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
6407 |
{ |
match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); |
|
if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) |
|
|
{ |
|
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
|
/* TMP2 which is set here used by OP_KETRMAX below. */ |
|
|
if (ket == OP_KETRMAX) |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); |
|
|
else if (ket == OP_KETRMIN) |
|
|
{ |
|
|
/* Move the STR_PTR to the private_data_ptr. */ |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); |
|
|
} |
|
|
} |
|
|
else |
|
|
{ |
|
|
stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; |
|
|
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw)); |
|
|
if (ket == OP_KETRMAX) |
|
|
{ |
|
|
/* TMP2 which is set here used by OP_KETRMAX below. */ |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
|
|
} |
|
|
} |
|
|
} |
|
6408 |
|
|
6409 |
stacksize = 0; |
stacksize = 0; |
6410 |
|
if (repeat_type == OP_MINUPTO) |
6411 |
|
{ |
6412 |
|
/* We need to preserve the counter. TMP2 will be used below. */ |
6413 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr); |
6414 |
|
stacksize++; |
6415 |
|
} |
6416 |
if (ket != OP_KET || bra != OP_BRA) |
if (ket != OP_KET || bra != OP_BRA) |
6417 |
stacksize++; |
stacksize++; |
6418 |
if (offset != 0) |
if (offset != 0) |
6429 |
allocate_stack(common, stacksize); |
allocate_stack(common, stacksize); |
6430 |
|
|
6431 |
stacksize = 0; |
stacksize = 0; |
6432 |
|
if (repeat_type == OP_MINUPTO) |
6433 |
|
{ |
6434 |
|
/* TMP2 was set above. */ |
6435 |
|
OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); |
6436 |
|
stacksize++; |
6437 |
|
} |
6438 |
|
|
6439 |
if (ket != OP_KET || bra != OP_BRA) |
if (ket != OP_KET || bra != OP_BRA) |
6440 |
{ |
{ |
6441 |
if (ket != OP_KET) |
if (ket != OP_KET) |
6446 |
} |
} |
6447 |
|
|
6448 |
if (offset != 0) |
if (offset != 0) |
6449 |
{ |
stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); |
|
if (common->capture_last_ptr != 0) |
|
|
{ |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0); |
|
|
stacksize++; |
|
|
} |
|
|
if (common->optimized_cbracket[offset >> 1] == 0) |
|
|
{ |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 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); |
|
|
stacksize += 2; |
|
|
} |
|
|
} |
|
6450 |
|
|
6451 |
if (has_alternatives) |
if (has_alternatives) |
6452 |
{ |
{ |
6465 |
|
|
6466 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
6467 |
{ |
{ |
6468 |
if (opcode == OP_ONCE || opcode >= OP_SBRA) |
if (repeat_type != 0) |
6469 |
|
{ |
6470 |
|
if (has_alternatives) |
6471 |
|
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); |
6472 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); |
6473 |
|
JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); |
6474 |
|
/* Drop STR_PTR for greedy plus quantifier. */ |
6475 |
|
if (opcode != OP_ONCE) |
6476 |
|
free_stack(common, 1); |
6477 |
|
} |
6478 |
|
else if (opcode == OP_ONCE || opcode >= OP_SBRA) |
6479 |
{ |
{ |
6480 |
if (has_alternatives) |
if (has_alternatives) |
6481 |
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); |
6482 |
/* Checking zero-length iteration. */ |
/* Checking zero-length iteration. */ |
6483 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
6484 |
{ |
{ |
6485 |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmax_label); |
6486 |
/* Drop STR_PTR for greedy plus quantifier. */ |
/* Drop STR_PTR for greedy plus quantifier. */ |
6487 |
if (bra != OP_BRAZERO) |
if (bra != OP_BRAZERO) |
6488 |
free_stack(common, 1); |
free_stack(common, 1); |
6489 |
} |
} |
6490 |
else |
else |
6491 |
/* TMP2 must contain the starting STR_PTR. */ |
/* TMP2 must contain the starting STR_PTR. */ |
6492 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label); |
6493 |
} |
} |
6494 |
else |
else |
6495 |
JUMPTO(SLJIT_JUMP, rmaxlabel); |
JUMPTO(SLJIT_JUMP, rmax_label); |
6496 |
BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); |
6497 |
} |
} |
6498 |
|
|
6499 |
|
if (repeat_type == OP_EXACT) |
6500 |
|
{ |
6501 |
|
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); |
6502 |
|
JUMPTO(SLJIT_C_NOT_ZERO, rmax_label); |
6503 |
|
} |
6504 |
|
else if (repeat_type == OP_UPTO) |
6505 |
|
{ |
6506 |
|
/* We need to preserve the counter. */ |
6507 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr); |
6508 |
|
allocate_stack(common, 1); |
6509 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
6510 |
|
} |
6511 |
|
|
6512 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
6513 |
BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); |
BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); |
6514 |
|
|
6516 |
{ |
{ |
6517 |
/* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ |
/* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ |
6518 |
JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); |
JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); |
6519 |
if (braminzerojump != NULL) |
if (braminzero != NULL) |
6520 |
{ |
{ |
6521 |
JUMPHERE(braminzerojump); |
JUMPHERE(braminzero); |
6522 |
/* We need to release the end pointer to perform the |
/* We need to release the end pointer to perform the |
6523 |
backtrack for the zero-length iteration. When |
backtrack for the zero-length iteration. When |
6524 |
framesize is < 0, OP_ONCE will do the release itself. */ |
framesize is < 0, OP_ONCE will do the release itself. */ |
6534 |
} |
} |
6535 |
|
|
6536 |
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) |
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) |
6537 |
decrease_call_count(common); |
count_match(common); |
6538 |
|
|
6539 |
/* Skip the other alternatives. */ |
/* Skip the other alternatives. */ |
6540 |
while (*cc == OP_ALT) |
while (*cc == OP_ALT) |
6541 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
6542 |
cc += 1 + LINK_SIZE; |
cc += 1 + LINK_SIZE; |
6543 |
return cc; |
|
6544 |
|
/* Temporarily encoding the needs_control_head in framesize. */ |
6545 |
|
if (opcode == OP_ONCE) |
6546 |
|
BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); |
6547 |
|
return cc + repeat_length; |
6548 |
} |
} |
6549 |
|
|
6550 |
static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
6554 |
pcre_uchar opcode; |
pcre_uchar opcode; |
6555 |
int private_data_ptr; |
int private_data_ptr; |
6556 |
int cbraprivptr = 0; |
int cbraprivptr = 0; |
6557 |
|
BOOL needs_control_head; |
6558 |
int framesize; |
int framesize; |
6559 |
int stacksize; |
int stacksize; |
6560 |
int offset = 0; |
int offset = 0; |
6561 |
BOOL zero = FALSE; |
BOOL zero = FALSE; |
6562 |
pcre_uchar *ccbegin = NULL; |
pcre_uchar *ccbegin = NULL; |
6563 |
int stack; |
int stack; /* Also contains the offset of control head. */ |
6564 |
struct sljit_label *loop = NULL; |
struct sljit_label *loop = NULL; |
6565 |
struct jump_list *emptymatch = NULL; |
struct jump_list *emptymatch = NULL; |
6566 |
|
|
6598 |
break; |
break; |
6599 |
} |
} |
6600 |
|
|
6601 |
framesize = get_framesize(common, cc, FALSE); |
framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); |
6602 |
BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; |
BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; |
6603 |
if (framesize < 0) |
if (framesize < 0) |
6604 |
{ |
{ |
6611 |
else |
else |
6612 |
stacksize = 1; |
stacksize = 1; |
6613 |
|
|
6614 |
|
if (needs_control_head) |
6615 |
|
stacksize++; |
6616 |
if (!zero) |
if (!zero) |
6617 |
stacksize++; |
stacksize++; |
6618 |
|
|
6621 |
if (framesize == no_frame) |
if (framesize == no_frame) |
6622 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); |
6623 |
|
|
6624 |
|
stack = 0; |
6625 |
if (offset != 0) |
if (offset != 0) |
6626 |
{ |
{ |
6627 |
|
stack = 2; |
6628 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
6629 |
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)); |
6630 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
6631 |
if (common->capture_last_ptr != 0) |
if (common->capture_last_ptr != 0) |
6632 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); |
6633 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); |
6634 |
|
if (needs_control_head) |
6635 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
6636 |
if (common->capture_last_ptr != 0) |
if (common->capture_last_ptr != 0) |
6637 |
|
{ |
6638 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); |
6639 |
|
stack = 3; |
6640 |
|
} |
6641 |
} |
} |
6642 |
else |
else |
6643 |
|
{ |
6644 |
|
if (needs_control_head) |
6645 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
6646 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
6647 |
|
stack = 1; |
6648 |
|
} |
6649 |
|
|
6650 |
|
if (needs_control_head) |
6651 |
|
stack++; |
6652 |
if (!zero) |
if (!zero) |
6653 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1); |
6654 |
|
if (needs_control_head) |
6655 |
|
{ |
6656 |
|
stack--; |
6657 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); |
6658 |
|
} |
6659 |
} |
} |
6660 |
else |
else |
6661 |
{ |
{ |
6662 |
stacksize = framesize + 1; |
stacksize = framesize + 1; |
6663 |
if (!zero) |
if (!zero) |
6664 |
stacksize++; |
stacksize++; |
6665 |
if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) |
if (needs_control_head) |
6666 |
|
stacksize++; |
6667 |
|
if (offset == 0) |
6668 |
stacksize++; |
stacksize++; |
6669 |
BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; |
BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; |
6670 |
|
|
6671 |
allocate_stack(common, stacksize); |
allocate_stack(common, stacksize); |
6672 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
6673 |
OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); |
if (needs_control_head) |
6674 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
6675 |
|
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); |
6676 |
|
|
6677 |
stack = 0; |
stack = 0; |
6678 |
if (!zero) |
if (!zero) |
6679 |
{ |
{ |
6680 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1); |
6681 |
|
stack = 1; |
6682 |
|
} |
6683 |
|
if (needs_control_head) |
6684 |
|
{ |
6685 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0); |
6686 |
stack++; |
stack++; |
6687 |
} |
} |
6688 |
if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS) |
if (offset == 0) |
6689 |
{ |
{ |
6690 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0); |
6691 |
stack++; |
stack++; |
6692 |
} |
} |
6693 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); |
6694 |
init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE); |
init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE); |
6695 |
|
stack -= 1 + (offset == 0); |
6696 |
} |
} |
6697 |
|
|
6698 |
if (offset != 0) |
if (offset != 0) |
6768 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); |
6769 |
} |
} |
6770 |
} |
} |
6771 |
|
|
6772 |
|
if (needs_control_head) |
6773 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack)); |
6774 |
|
|
6775 |
JUMPTO(SLJIT_JUMP, loop); |
JUMPTO(SLJIT_JUMP, loop); |
6776 |
flush_stubs(common); |
flush_stubs(common); |
6777 |
|
|
6808 |
ccbegin = cc + 1 + LINK_SIZE; |
ccbegin = cc + 1 + LINK_SIZE; |
6809 |
} |
} |
6810 |
|
|
6811 |
|
/* We don't have to restore the control head in case of a failed match. */ |
6812 |
|
|
6813 |
backtrack->topbacktracks = NULL; |
backtrack->topbacktracks = NULL; |
6814 |
if (!zero) |
if (!zero) |
6815 |
{ |
{ |
6821 |
|
|
6822 |
/* None of them matched. */ |
/* None of them matched. */ |
6823 |
set_jumps(emptymatch, LABEL()); |
set_jumps(emptymatch, LABEL()); |
6824 |
decrease_call_count(common); |
count_match(common); |
6825 |
return cc + 1 + LINK_SIZE; |
return cc + 1 + LINK_SIZE; |
6826 |
} |
} |
6827 |
|
|
7131 |
break; |
break; |
7132 |
} |
} |
7133 |
|
|
7134 |
decrease_call_count(common); |
count_match(common); |
7135 |
return end; |
return end; |
7136 |
} |
} |
7137 |
|
|
7198 |
return cc + 1 + IMM2_SIZE; |
return cc + 1 + IMM2_SIZE; |
7199 |
} |
} |
7200 |
|
|
7201 |
|
static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
7202 |
|
{ |
7203 |
|
DEFINE_COMPILER; |
7204 |
|
backtrack_common *backtrack; |
7205 |
|
pcre_uchar opcode = *cc; |
7206 |
|
pcre_uchar *ccend = cc + 1; |
7207 |
|
|
7208 |
|
if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) |
7209 |
|
ccend += 2 + cc[1]; |
7210 |
|
|
7211 |
|
PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); |
7212 |
|
|
7213 |
|
if (opcode == OP_SKIP) |
7214 |
|
{ |
7215 |
|
allocate_stack(common, 1); |
7216 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
7217 |
|
return ccend; |
7218 |
|
} |
7219 |
|
|
7220 |
|
if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) |
7221 |
|
{ |
7222 |
|
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
7223 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); |
7224 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
7225 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
7226 |
|
} |
7227 |
|
|
7228 |
|
return ccend; |
7229 |
|
} |
7230 |
|
|
7231 |
|
static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP }; |
7232 |
|
|
7233 |
|
static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) |
7234 |
|
{ |
7235 |
|
DEFINE_COMPILER; |
7236 |
|
backtrack_common *backtrack; |
7237 |
|
BOOL needs_control_head; |
7238 |
|
int size; |
7239 |
|
|
7240 |
|
PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); |
7241 |
|
common->then_trap = BACKTRACK_AS(then_trap_backtrack); |
7242 |
|
BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; |
7243 |
|
BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start); |
7244 |
|
BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head); |
7245 |
|
|
7246 |
|
size = BACKTRACK_AS(then_trap_backtrack)->framesize; |
7247 |
|
size = 3 + (size < 0 ? 0 : size); |
7248 |
|
|
7249 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
7250 |
|
allocate_stack(common, size); |
7251 |
|
if (size > 3) |
7252 |
|
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw)); |
7253 |
|
else |
7254 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
7255 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start); |
7256 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap); |
7257 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0); |
7258 |
|
|
7259 |
|
size = BACKTRACK_AS(then_trap_backtrack)->framesize; |
7260 |
|
if (size >= 0) |
7261 |
|
init_frame(common, cc, ccend, size - 1, 0, FALSE); |
7262 |
|
} |
7263 |
|
|
7264 |
static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) |
static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) |
7265 |
{ |
{ |
7266 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7267 |
backtrack_common *backtrack; |
backtrack_common *backtrack; |
7268 |
|
BOOL has_then_trap = FALSE; |
7269 |
|
then_trap_backtrack *save_then_trap = NULL; |
7270 |
|
|
7271 |
|
SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); |
7272 |
|
|
7273 |
|
if (common->has_then && common->then_offsets[cc - common->start] != 0) |
7274 |
|
{ |
7275 |
|
SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0); |
7276 |
|
has_then_trap = TRUE; |
7277 |
|
save_then_trap = common->then_trap; |
7278 |
|
/* Tail item on backtrack. */ |
7279 |
|
compile_then_trap_matchingpath(common, cc, ccend, parent); |
7280 |
|
} |
7281 |
|
|
7282 |
while (cc < ccend) |
while (cc < ccend) |
7283 |
{ |
{ |
7458 |
} |
} |
7459 |
BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); |
BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); |
7460 |
if (cc[1] > OP_ASSERTBACK_NOT) |
if (cc[1] > OP_ASSERTBACK_NOT) |
7461 |
decrease_call_count(common); |
count_match(common); |
7462 |
break; |
break; |
7463 |
|
|
7464 |
case OP_ONCE: |
case OP_ONCE: |
7494 |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
7495 |
SLJIT_ASSERT(common->mark_ptr != 0); |
SLJIT_ASSERT(common->mark_ptr != 0); |
7496 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); |
7497 |
allocate_stack(common, 1); |
allocate_stack(common, common->has_skip_arg ? 5 : 1); |
7498 |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
7499 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0); |
7500 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); |
7501 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
7502 |
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
7503 |
|
if (common->has_skip_arg) |
7504 |
|
{ |
7505 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
7506 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
7507 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark); |
7508 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2)); |
7509 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); |
7510 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); |
7511 |
|
} |
7512 |
cc += 1 + 2 + cc[1]; |
cc += 1 + 2 + cc[1]; |
7513 |
break; |
break; |
7514 |
|
|
|
case OP_PRUNE_ARG: |
|
|
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
|
|
/* Fall through. */ |
|
|
|
|
7515 |
case OP_PRUNE: |
case OP_PRUNE: |
7516 |
case OP_COMMIT: |
case OP_PRUNE_ARG: |
|
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
|
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
|
|
allocate_stack(common, 2); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
|
|
cc += (*cc == OP_PRUNE_ARG) ? (1 + 2 + cc[1]) : 1; |
|
|
break; |
|
|
|
|
7517 |
case OP_SKIP: |
case OP_SKIP: |
7518 |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
case OP_SKIP_ARG: |
7519 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
case OP_THEN: |
7520 |
allocate_stack(common, 3); |
case OP_THEN_ARG: |
7521 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
case OP_COMMIT: |
7522 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_skip); |
cc = compile_control_verb_matchingpath(common, cc, parent); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
|
|
cc += 1; |
|
7523 |
break; |
break; |
7524 |
|
|
7525 |
case OP_FAIL: |
case OP_FAIL: |
7543 |
if (cc == NULL) |
if (cc == NULL) |
7544 |
return; |
return; |
7545 |
} |
} |
7546 |
|
|
7547 |
|
if (has_then_trap) |
7548 |
|
{ |
7549 |
|
/* Head item on backtrack. */ |
7550 |
|
PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); |
7551 |
|
BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; |
7552 |
|
BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap; |
7553 |
|
common->then_trap = save_then_trap; |
7554 |
|
} |
7555 |
SLJIT_ASSERT(cc == ccend); |
SLJIT_ASSERT(cc == ccend); |
7556 |
} |
} |
7557 |
|
|
7713 |
} |
} |
7714 |
} |
} |
7715 |
|
|
7716 |
static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
7717 |
{ |
{ |
7718 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7719 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
7735 |
free_stack(common, 2); |
free_stack(common, 2); |
7736 |
} |
} |
7737 |
|
|
7738 |
static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
7739 |
{ |
{ |
7740 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7741 |
|
|
7831 |
static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
7832 |
{ |
{ |
7833 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7834 |
int opcode; |
int opcode, stacksize, count; |
7835 |
int offset = 0; |
int offset = 0; |
7836 |
int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; |
int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; |
7837 |
int stacksize; |
int repeat_ptr = 0, repeat_type = 0, repeat_count = 0; |
|
int count; |
|
7838 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
7839 |
pcre_uchar *ccbegin; |
pcre_uchar *ccbegin; |
7840 |
pcre_uchar *ccprev; |
pcre_uchar *ccprev; |
7844 |
pcre_uchar ket; |
pcre_uchar ket; |
7845 |
assert_backtrack *assert; |
assert_backtrack *assert; |
7846 |
BOOL has_alternatives; |
BOOL has_alternatives; |
7847 |
|
BOOL needs_control_head = FALSE; |
7848 |
struct sljit_jump *brazero = NULL; |
struct sljit_jump *brazero = NULL; |
7849 |
struct sljit_jump *once = NULL; |
struct sljit_jump *once = NULL; |
7850 |
struct sljit_jump *cond = NULL; |
struct sljit_jump *cond = NULL; |
7851 |
struct sljit_label *rminlabel = NULL; |
struct sljit_label *rmin_label = NULL; |
7852 |
|
struct sljit_label *exact_label = NULL; |
7853 |
|
|
7854 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
7855 |
{ |
{ |
7858 |
} |
} |
7859 |
|
|
7860 |
opcode = *cc; |
opcode = *cc; |
7861 |
|
ccbegin = bracketend(cc) - 1 - LINK_SIZE; |
7862 |
|
ket = *ccbegin; |
7863 |
|
if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0) |
7864 |
|
{ |
7865 |
|
repeat_ptr = PRIVATE_DATA(ccbegin); |
7866 |
|
repeat_type = PRIVATE_DATA(ccbegin + 2); |
7867 |
|
repeat_count = PRIVATE_DATA(ccbegin + 3); |
7868 |
|
SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0); |
7869 |
|
if (repeat_type == OP_UPTO) |
7870 |
|
ket = OP_KETRMAX; |
7871 |
|
if (repeat_type == OP_MINUPTO) |
7872 |
|
ket = OP_KETRMIN; |
7873 |
|
} |
7874 |
ccbegin = cc; |
ccbegin = cc; |
|
ket = *(bracketend(ccbegin) - 1 - LINK_SIZE); |
|
7875 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
7876 |
has_alternatives = *cc == OP_ALT; |
has_alternatives = *cc == OP_ALT; |
7877 |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) |
7883 |
if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) |
if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)) |
7884 |
opcode = OP_ONCE; |
opcode = OP_ONCE; |
7885 |
|
|
7886 |
|
/* Decoding the needs_control_head in framesize. */ |
7887 |
|
if (opcode == OP_ONCE) |
7888 |
|
{ |
7889 |
|
needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0; |
7890 |
|
CURRENT_AS(bracket_backtrack)->u.framesize >>= 1; |
7891 |
|
} |
7892 |
|
|
7893 |
|
if (ket != OP_KET && repeat_type != 0) |
7894 |
|
{ |
7895 |
|
/* TMP1 is used in OP_KETRMIN below. */ |
7896 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
7897 |
|
free_stack(common, 1); |
7898 |
|
if (repeat_type == OP_UPTO) |
7899 |
|
OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1); |
7900 |
|
else |
7901 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0); |
7902 |
|
} |
7903 |
|
|
7904 |
if (ket == OP_KETRMAX) |
if (ket == OP_KETRMAX) |
7905 |
{ |
{ |
7906 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
7915 |
if (bra != OP_BRAMINZERO) |
if (bra != OP_BRAMINZERO) |
7916 |
{ |
{ |
7917 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
7918 |
if (opcode >= OP_SBRA || opcode == OP_ONCE) |
if (repeat_type != 0) |
7919 |
|
{ |
7920 |
|
/* TMP1 was set a few lines above. */ |
7921 |
|
CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
7922 |
|
/* Drop STR_PTR for non-greedy plus quantifier. */ |
7923 |
|
if (opcode != OP_ONCE) |
7924 |
|
free_stack(common, 1); |
7925 |
|
} |
7926 |
|
else if (opcode >= OP_SBRA || opcode == OP_ONCE) |
7927 |
{ |
{ |
7928 |
/* Checking zero-length iteration. */ |
/* Checking zero-length iteration. */ |
7929 |
if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) |
if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) |
7933 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
7934 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
7935 |
} |
} |
7936 |
|
/* Drop STR_PTR for non-greedy plus quantifier. */ |
7937 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
7938 |
free_stack(common, 1); |
free_stack(common, 1); |
7939 |
} |
} |
7940 |
else |
else |
7941 |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
7942 |
} |
} |
7943 |
rminlabel = LABEL(); |
rmin_label = LABEL(); |
7944 |
|
if (repeat_type != 0) |
7945 |
|
OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); |
7946 |
} |
} |
7947 |
else if (bra == OP_BRAZERO) |
else if (bra == OP_BRAZERO) |
7948 |
{ |
{ |
7950 |
free_stack(common, 1); |
free_stack(common, 1); |
7951 |
brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); |
brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); |
7952 |
} |
} |
7953 |
|
else if (repeat_type == OP_EXACT) |
7954 |
|
{ |
7955 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); |
7956 |
|
exact_label = LABEL(); |
7957 |
|
} |
7958 |
|
|
7959 |
if (offset != 0) |
if (offset != 0) |
7960 |
{ |
{ |
8074 |
current->top = NULL; |
current->top = NULL; |
8075 |
current->topbacktracks = NULL; |
current->topbacktracks = NULL; |
8076 |
current->nextbacktracks = NULL; |
current->nextbacktracks = NULL; |
8077 |
|
/* Conditional blocks always have an additional alternative, even if it is empty. */ |
8078 |
if (*cc == OP_ALT) |
if (*cc == OP_ALT) |
8079 |
{ |
{ |
8080 |
ccprev = cc + 1 + LINK_SIZE; |
ccprev = cc + 1 + LINK_SIZE; |
8081 |
cc += GET(cc, 1); |
cc += GET(cc, 1); |
8082 |
if (opcode != OP_COND && opcode != OP_SCOND) |
if (opcode != OP_COND && opcode != OP_SCOND) |
8083 |
{ |
{ |
8084 |
if (private_data_ptr != 0 && opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
8085 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
{ |
8086 |
|
if (private_data_ptr != 0) |
8087 |
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
8088 |
|
else |
8089 |
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8090 |
|
} |
8091 |
else |
else |
8092 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); |
8093 |
} |
} |
8094 |
compile_matchingpath(common, ccprev, cc, current); |
compile_matchingpath(common, ccprev, cc, current); |
8095 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
8096 |
return; |
return; |
8097 |
} |
} |
8098 |
|
|
8099 |
/* Instructions after the current alternative is succesfully matched. */ |
/* Instructions after the current alternative is successfully matched. */ |
8100 |
/* There is a similar code in compile_bracket_matchingpath. */ |
/* There is a similar code in compile_bracket_matchingpath. */ |
8101 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
8102 |
{ |
match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); |
|
if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) |
|
|
{ |
|
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
|
/* TMP2 which is set here used by OP_KETRMAX below. */ |
|
|
if (ket == OP_KETRMAX) |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); |
|
|
else if (ket == OP_KETRMIN) |
|
|
{ |
|
|
/* Move the STR_PTR to the private_data_ptr. */ |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); |
|
|
} |
|
|
} |
|
|
else |
|
|
{ |
|
|
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw)); |
|
|
if (ket == OP_KETRMAX) |
|
|
{ |
|
|
/* TMP2 which is set here used by OP_KETRMAX below. */ |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
|
|
} |
|
|
} |
|
|
} |
|
8103 |
|
|
8104 |
stacksize = 0; |
stacksize = 0; |
8105 |
|
if (repeat_type == OP_MINUPTO) |
8106 |
|
{ |
8107 |
|
/* We need to preserve the counter. TMP2 will be used below. */ |
8108 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr); |
8109 |
|
stacksize++; |
8110 |
|
} |
8111 |
if (ket != OP_KET || bra != OP_BRA) |
if (ket != OP_KET || bra != OP_BRA) |
8112 |
stacksize++; |
stacksize++; |
8113 |
if (offset != 0) |
if (offset != 0) |
8120 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
8121 |
stacksize++; |
stacksize++; |
8122 |
|
|
8123 |
if (stacksize > 0) { |
if (stacksize > 0) |
8124 |
if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
allocate_stack(common, stacksize); |
|
allocate_stack(common, stacksize); |
|
|
else |
|
|
{ |
|
|
/* We know we have place at least for one item on the top of the stack. */ |
|
|
SLJIT_ASSERT(stacksize == 1); |
|
|
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); |
|
|
} |
|
|
} |
|
8125 |
|
|
8126 |
stacksize = 0; |
stacksize = 0; |
8127 |
|
if (repeat_type == OP_MINUPTO) |
8128 |
|
{ |
8129 |
|
/* TMP2 was set above. */ |
8130 |
|
OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1); |
8131 |
|
stacksize++; |
8132 |
|
} |
8133 |
|
|
8134 |
if (ket != OP_KET || bra != OP_BRA) |
if (ket != OP_KET || bra != OP_BRA) |
8135 |
{ |
{ |
8136 |
if (ket != OP_KET) |
if (ket != OP_KET) |
8141 |
} |
} |
8142 |
|
|
8143 |
if (offset != 0) |
if (offset != 0) |
8144 |
{ |
stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); |
|
if (common->capture_last_ptr != 0) |
|
|
{ |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
|
|
stacksize++; |
|
|
} |
|
|
if (common->optimized_cbracket[offset >> 1] == 0) |
|
|
{ |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); |
|
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 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); |
|
|
stacksize += 2; |
|
|
} |
|
|
} |
|
8145 |
|
|
8146 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
8147 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++); |
8214 |
else if (opcode == OP_ONCE) |
else if (opcode == OP_ONCE) |
8215 |
{ |
{ |
8216 |
cc = ccbegin + GET(ccbegin, 1); |
cc = ccbegin + GET(ccbegin, 1); |
8217 |
|
stacksize = needs_control_head ? 1 : 0; |
8218 |
|
|
8219 |
if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) |
8220 |
{ |
{ |
8221 |
/* Reset head and drop saved frame. */ |
/* Reset head and drop saved frame. */ |
8222 |
stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1; |
stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1); |
|
free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize); |
|
8223 |
} |
} |
8224 |
else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) |
else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN)) |
8225 |
{ |
{ |
8226 |
/* The STR_PTR must be released. */ |
/* The STR_PTR must be released. */ |
8227 |
free_stack(common, 1); |
stacksize++; |
8228 |
} |
} |
8229 |
|
free_stack(common, stacksize); |
8230 |
|
|
8231 |
JUMPHERE(once); |
JUMPHERE(once); |
8232 |
/* Restore previous private_data_ptr */ |
/* Restore previous private_data_ptr */ |
8241 |
} |
} |
8242 |
} |
} |
8243 |
|
|
8244 |
if (ket == OP_KETRMAX) |
if (repeat_type == OP_EXACT) |
8245 |
|
{ |
8246 |
|
OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1); |
8247 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0); |
8248 |
|
CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label); |
8249 |
|
} |
8250 |
|
else if (ket == OP_KETRMAX) |
8251 |
{ |
{ |
8252 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8253 |
if (bra != OP_BRAZERO) |
if (bra != OP_BRAZERO) |
8254 |
free_stack(common, 1); |
free_stack(common, 1); |
8255 |
|
|
8256 |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); |
8257 |
if (bra == OP_BRAZERO) |
if (bra == OP_BRAZERO) |
8258 |
{ |
{ |
8271 |
affect badly the free_stack(2) above. */ |
affect badly the free_stack(2) above. */ |
8272 |
if (opcode != OP_ONCE) |
if (opcode != OP_ONCE) |
8273 |
free_stack(common, 1); |
free_stack(common, 1); |
8274 |
CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel); |
CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label); |
8275 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
8276 |
free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); |
free_stack(common, bra == OP_BRAMINZERO ? 2 : 1); |
8277 |
else if (bra == OP_BRAMINZERO) |
else if (bra == OP_BRAMINZERO) |
8285 |
} |
} |
8286 |
} |
} |
8287 |
|
|
8288 |
static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8289 |
{ |
{ |
8290 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
8291 |
int offset; |
int offset; |
8324 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); |
8325 |
} |
} |
8326 |
|
|
8327 |
static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8328 |
{ |
{ |
8329 |
assert_backtrack backtrack; |
assert_backtrack backtrack; |
8330 |
|
|
8348 |
SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); |
SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); |
8349 |
} |
} |
8350 |
|
|
8351 |
|
static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8352 |
|
{ |
8353 |
|
DEFINE_COMPILER; |
8354 |
|
pcre_uchar opcode = *current->cc; |
8355 |
|
struct sljit_label *loop; |
8356 |
|
struct sljit_jump *jump; |
8357 |
|
|
8358 |
|
if (opcode == OP_THEN || opcode == OP_THEN_ARG) |
8359 |
|
{ |
8360 |
|
if (common->then_trap != NULL) |
8361 |
|
{ |
8362 |
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
8363 |
|
|
8364 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
8365 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap); |
8366 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start); |
8367 |
|
jump = JUMP(SLJIT_JUMP); |
8368 |
|
|
8369 |
|
loop = LABEL(); |
8370 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw)); |
8371 |
|
JUMPHERE(jump); |
8372 |
|
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop); |
8373 |
|
CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop); |
8374 |
|
add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP)); |
8375 |
|
return; |
8376 |
|
} |
8377 |
|
else if (common->positive_assert) |
8378 |
|
{ |
8379 |
|
add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP)); |
8380 |
|
return; |
8381 |
|
} |
8382 |
|
} |
8383 |
|
|
8384 |
|
if (common->local_exit) |
8385 |
|
{ |
8386 |
|
if (common->quit_label == NULL) |
8387 |
|
add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); |
8388 |
|
else |
8389 |
|
JUMPTO(SLJIT_JUMP, common->quit_label); |
8390 |
|
return; |
8391 |
|
} |
8392 |
|
|
8393 |
|
if (opcode == OP_SKIP_ARG) |
8394 |
|
{ |
8395 |
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
8396 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
8397 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
8398 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2)); |
8399 |
|
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark)); |
8400 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
8401 |
|
|
8402 |
|
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); |
8403 |
|
add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); |
8404 |
|
return; |
8405 |
|
} |
8406 |
|
|
8407 |
|
if (opcode == OP_SKIP) |
8408 |
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8409 |
|
else |
8410 |
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0); |
8411 |
|
add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); |
8412 |
|
} |
8413 |
|
|
8414 |
|
static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8415 |
|
{ |
8416 |
|
DEFINE_COMPILER; |
8417 |
|
struct sljit_jump *jump; |
8418 |
|
int size; |
8419 |
|
|
8420 |
|
if (CURRENT_AS(then_trap_backtrack)->then_trap) |
8421 |
|
{ |
8422 |
|
common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap; |
8423 |
|
return; |
8424 |
|
} |
8425 |
|
|
8426 |
|
size = CURRENT_AS(then_trap_backtrack)->framesize; |
8427 |
|
size = 3 + (size < 0 ? 0 : size); |
8428 |
|
|
8429 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3)); |
8430 |
|
free_stack(common, size); |
8431 |
|
jump = JUMP(SLJIT_JUMP); |
8432 |
|
|
8433 |
|
set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); |
8434 |
|
/* STACK_TOP is set by THEN. */ |
8435 |
|
if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) |
8436 |
|
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
8437 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8438 |
|
free_stack(common, 3); |
8439 |
|
|
8440 |
|
JUMPHERE(jump); |
8441 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0); |
8442 |
|
} |
8443 |
|
|
8444 |
static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8445 |
{ |
{ |
8446 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
8447 |
|
then_trap_backtrack *save_then_trap = common->then_trap; |
8448 |
|
|
8449 |
while (current) |
while (current) |
8450 |
{ |
{ |
8578 |
break; |
break; |
8579 |
|
|
8580 |
case OP_MARK: |
case OP_MARK: |
8581 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0)); |
8582 |
free_stack(common, 1); |
if (common->has_skip_arg) |
8583 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8584 |
|
free_stack(common, common->has_skip_arg ? 5 : 1); |
8585 |
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); |
8586 |
|
if (common->has_skip_arg) |
8587 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0); |
8588 |
break; |
break; |
8589 |
|
|
8590 |
|
case OP_THEN: |
8591 |
|
case OP_THEN_ARG: |
8592 |
case OP_PRUNE: |
case OP_PRUNE: |
8593 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
8594 |
case OP_SKIP: |
case OP_SKIP: |
8595 |
if (!common->local_exit) |
case OP_SKIP_ARG: |
8596 |
{ |
compile_control_verb_backtrackingpath(common, current); |
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
|
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
|
|
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain)); |
|
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
|
|
|
|
|
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); |
|
|
add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); |
|
|
|
|
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
|
|
} |
|
|
|
|
|
/* Commit or in recurse or accept. */ |
|
|
if (common->quit_label == NULL) |
|
|
add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); |
|
|
else |
|
|
JUMPTO(SLJIT_JUMP, common->quit_label); |
|
8597 |
break; |
break; |
8598 |
|
|
8599 |
case OP_COMMIT: |
case OP_COMMIT: |
8612 |
set_jumps(current->topbacktracks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
8613 |
break; |
break; |
8614 |
|
|
8615 |
|
case OP_THEN_TRAP: |
8616 |
|
/* A virtual opcode for then traps. */ |
8617 |
|
compile_then_trap_backtrackingpath(common, current); |
8618 |
|
break; |
8619 |
|
|
8620 |
default: |
default: |
8621 |
SLJIT_ASSERT_STOP(); |
SLJIT_ASSERT_STOP(); |
8622 |
break; |
break; |
8623 |
} |
} |
8624 |
current = current->prev; |
current = current->prev; |
8625 |
} |
} |
8626 |
|
common->then_trap = save_then_trap; |
8627 |
} |
} |
8628 |
|
|
8629 |
static SLJIT_INLINE void compile_recurse(compiler_common *common) |
static SLJIT_INLINE void compile_recurse(compiler_common *common) |
8632 |
pcre_uchar *cc = common->start + common->currententry->start; |
pcre_uchar *cc = common->start + common->currententry->start; |
8633 |
pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); |
pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); |
8634 |
pcre_uchar *ccend = bracketend(cc); |
pcre_uchar *ccend = bracketend(cc); |
8635 |
int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend); |
BOOL needs_control_head; |
8636 |
int framesize = get_framesize(common, cc, TRUE); |
int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); |
8637 |
|
int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); |
8638 |
int alternativesize; |
int alternativesize; |
8639 |
BOOL needs_frame; |
BOOL needs_frame; |
8640 |
backtrack_common altbacktrack; |
backtrack_common altbacktrack; |
8641 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
8642 |
|
|
8643 |
|
/* Recurse captures then. */ |
8644 |
|
common->then_trap = NULL; |
8645 |
|
|
8646 |
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); |
8647 |
needs_frame = framesize >= 0; |
needs_frame = framesize >= 0; |
8648 |
if (!needs_frame) |
if (!needs_frame) |
8656 |
sljit_emit_fast_enter(compiler, TMP2, 0); |
sljit_emit_fast_enter(compiler, TMP2, 0); |
8657 |
allocate_stack(common, private_data_size + framesize + alternativesize); |
allocate_stack(common, private_data_size + framesize + alternativesize); |
8658 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); |
8659 |
copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize); |
copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); |
8660 |
if (common->control_head_ptr != 0) |
if (needs_control_head) |
8661 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0); |
8662 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0); |
8663 |
if (needs_frame) |
if (needs_frame) |
8664 |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); |
init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE); |
8665 |
|
|
8666 |
if (alternativesize > 0) |
if (alternativesize > 0) |
8667 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
8731 |
JUMPHERE(jump); |
JUMPHERE(jump); |
8732 |
if (common->quit != NULL) |
if (common->quit != NULL) |
8733 |
set_jumps(common->quit, LABEL()); |
set_jumps(common->quit, LABEL()); |
8734 |
copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize); |
copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); |
8735 |
free_stack(common, private_data_size + framesize + alternativesize); |
free_stack(common, private_data_size + framesize + alternativesize); |
8736 |
if (common->control_head_ptr != 0) |
if (needs_control_head) |
8737 |
{ |
{ |
8738 |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw)); |
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw)); |
8739 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); |
8827 |
common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; |
common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; |
8828 |
common->ctypes = (sljit_sw)(tables + ctypes_offset); |
common->ctypes = (sljit_sw)(tables + ctypes_offset); |
8829 |
common->digits[0] = -2; |
common->digits[0] = -2; |
8830 |
common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset); |
common->name_table = ((pcre_uchar *)re) + re->name_table_offset; |
8831 |
common->name_count = re->name_count; |
common->name_count = re->name_count; |
8832 |
common->name_entry_size = re->name_entry_size; |
common->name_entry_size = re->name_entry_size; |
8833 |
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; |
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; |
8841 |
ccend = bracketend(rootbacktrack.cc); |
ccend = bracketend(rootbacktrack.cc); |
8842 |
|
|
8843 |
/* Calculate the local space size on the stack. */ |
/* Calculate the local space size on the stack. */ |
8844 |
common->ovector_start = CALL_LIMIT + sizeof(sljit_sw); |
common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); |
8845 |
common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); |
common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); |
8846 |
if (!common->optimized_cbracket) |
if (!common->optimized_cbracket) |
8847 |
return; |
return; |
8856 |
common->capture_last_ptr = common->ovector_start; |
common->capture_last_ptr = common->ovector_start; |
8857 |
common->ovector_start += sizeof(sljit_sw); |
common->ovector_start += sizeof(sljit_sw); |
8858 |
#endif |
#endif |
8859 |
private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend); |
if (!check_opcode_types(common, rootbacktrack.cc, ccend)) |
|
if (private_data_size < 0) |
|
8860 |
{ |
{ |
8861 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
8862 |
return; |
return; |
8918 |
|
|
8919 |
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); |
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); |
8920 |
common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); |
common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); |
8921 |
private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); |
|
8922 |
if (private_data_size > SLJIT_MAX_LOCAL_SIZE) |
common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si)); |
8923 |
|
if (!common->private_data_ptrs) |
8924 |
{ |
{ |
8925 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
8926 |
return; |
return; |
8927 |
} |
} |
8928 |
common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); |
memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); |
8929 |
if (!common->private_data_ptrs) |
|
8930 |
|
private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); |
8931 |
|
set_private_data_ptrs(common, &private_data_size, ccend); |
8932 |
|
if (private_data_size > SLJIT_MAX_LOCAL_SIZE) |
8933 |
{ |
{ |
8934 |
|
SLJIT_FREE(common->private_data_ptrs); |
8935 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
8936 |
return; |
return; |
8937 |
} |
} |
8938 |
memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); |
|
8939 |
set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend); |
if (common->has_then) |
8940 |
|
{ |
8941 |
|
common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc); |
8942 |
|
if (!common->then_offsets) |
8943 |
|
{ |
8944 |
|
SLJIT_FREE(common->optimized_cbracket); |
8945 |
|
SLJIT_FREE(common->private_data_ptrs); |
8946 |
|
return; |
8947 |
|
} |
8948 |
|
memset(common->then_offsets, 0, ccend - rootbacktrack.cc); |
8949 |
|
set_then_offsets(common, rootbacktrack.cc, NULL); |
8950 |
|
} |
8951 |
|
|
8952 |
compiler = sljit_create_compiler(); |
compiler = sljit_create_compiler(); |
8953 |
if (!compiler) |
if (!compiler) |
8954 |
{ |
{ |
8955 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
8956 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
8957 |
|
if (common->has_then) |
8958 |
|
SLJIT_FREE(common->then_offsets); |
8959 |
return; |
return; |
8960 |
} |
} |
8961 |
common->compiler = compiler; |
common->compiler = compiler; |
8973 |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); |
8974 |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); |
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); |
8975 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); |
8976 |
OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit)); |
OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); |
8977 |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); |
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); |
8978 |
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)); |
8979 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0); |
8980 |
|
|
8981 |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
if (mode == JIT_PARTIAL_SOFT_COMPILE) |
8982 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); |
9018 |
/* Store the current STR_PTR in OVECTOR(0). */ |
/* Store the current STR_PTR in OVECTOR(0). */ |
9019 |
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); |
9020 |
/* Copy the limit of allowed recursions. */ |
/* Copy the limit of allowed recursions. */ |
9021 |
OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); |
OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH); |
9022 |
if (common->capture_last_ptr != 0) |
if (common->capture_last_ptr != 0) |
9023 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1); |
9024 |
|
|
9047 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9048 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9049 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9050 |
|
if (common->has_then) |
9051 |
|
SLJIT_FREE(common->then_offsets); |
9052 |
return; |
return; |
9053 |
} |
} |
9054 |
|
|
9084 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9085 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9086 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9087 |
|
if (common->has_then) |
9088 |
|
SLJIT_FREE(common->then_offsets); |
9089 |
return; |
return; |
9090 |
} |
} |
9091 |
|
|
9153 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9154 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9155 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9156 |
|
if (common->has_then) |
9157 |
|
SLJIT_FREE(common->then_offsets); |
9158 |
return; |
return; |
9159 |
} |
} |
9160 |
flush_stubs(common); |
flush_stubs(common); |
9263 |
|
|
9264 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9265 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9266 |
|
if (common->has_then) |
9267 |
|
SLJIT_FREE(common->then_offsets); |
9268 |
|
|
9269 |
executable_func = sljit_generate_code(compiler); |
executable_func = sljit_generate_code(compiler); |
9270 |
executable_size = sljit_get_generated_code_size(compiler); |
executable_size = sljit_get_generated_code_size(compiler); |
9271 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9296 |
} |
} |
9297 |
memset(functions, 0, sizeof(executable_functions)); |
memset(functions, 0, sizeof(executable_functions)); |
9298 |
functions->top_bracket = (re->top_bracket + 1) * 2; |
functions->top_bracket = (re->top_bracket + 1) * 2; |
9299 |
|
functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0; |
9300 |
extra->executable_jit = functions; |
extra->executable_jit = functions; |
9301 |
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; |
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; |
9302 |
} |
} |
9351 |
arguments.end = subject + length; |
arguments.end = subject + length; |
9352 |
arguments.mark_ptr = NULL; |
arguments.mark_ptr = NULL; |
9353 |
/* JIT decreases this value less frequently than the interpreter. */ |
/* JIT decreases this value less frequently than the interpreter. */ |
9354 |
arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; |
arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); |
9355 |
|
if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) |
9356 |
|
arguments.limit_match = functions->limit_match; |
9357 |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
9358 |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
9359 |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
9444 |
arguments.end = subject_ptr + length; |
arguments.end = subject_ptr + length; |
9445 |
arguments.mark_ptr = NULL; |
arguments.mark_ptr = NULL; |
9446 |
/* JIT decreases this value less frequently than the interpreter. */ |
/* JIT decreases this value less frequently than the interpreter. */ |
9447 |
arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; |
arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); |
9448 |
|
if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) |
9449 |
|
arguments.limit_match = functions->limit_match; |
9450 |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
arguments.notbol = (options & PCRE_NOTBOL) != 0; |
9451 |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
arguments.noteol = (options & PCRE_NOTEOL) != 0; |
9452 |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |
9565 |
} |
} |
9566 |
} |
} |
9567 |
|
|
9568 |
|
#if defined COMPILE_PCRE8 |
9569 |
|
PCRE_EXP_DECL void |
9570 |
|
pcre_jit_free_unused_memory(void) |
9571 |
|
#elif defined COMPILE_PCRE16 |
9572 |
|
PCRE_EXP_DECL void |
9573 |
|
pcre16_jit_free_unused_memory(void) |
9574 |
|
#elif defined COMPILE_PCRE32 |
9575 |
|
PCRE_EXP_DECL void |
9576 |
|
pcre32_jit_free_unused_memory(void) |
9577 |
|
#endif |
9578 |
|
{ |
9579 |
|
sljit_free_unused_memory_exec(); |
9580 |
|
} |
9581 |
|
|
9582 |
#else /* SUPPORT_JIT */ |
#else /* SUPPORT_JIT */ |
9583 |
|
|
9584 |
/* 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 |
9630 |
(void)userdata; |
(void)userdata; |
9631 |
} |
} |
9632 |
|
|
9633 |
|
#if defined COMPILE_PCRE8 |
9634 |
|
PCRE_EXP_DECL void |
9635 |
|
pcre_jit_free_unused_memory(void) |
9636 |
|
#elif defined COMPILE_PCRE16 |
9637 |
|
PCRE_EXP_DECL void |
9638 |
|
pcre16_jit_free_unused_memory(void) |
9639 |
|
#elif defined COMPILE_PCRE32 |
9640 |
|
PCRE_EXP_DECL void |
9641 |
|
pcre32_jit_free_unused_memory(void) |
9642 |
|
#endif |
9643 |
|
{ |
9644 |
|
} |
9645 |
|
|
9646 |
#endif |
#endif |
9647 |
|
|
9648 |
/* End of pcre_jit_compile.c */ |
/* End of pcre_jit_compile.c */ |