196 |
struct stub_list *next; |
struct stub_list *next; |
197 |
} stub_list; |
} stub_list; |
198 |
|
|
199 |
|
enum bytecode_flag_types { |
200 |
|
flag_optimized_cbracket = 1, |
201 |
|
flag_then_start = 2, |
202 |
|
}; |
203 |
|
|
204 |
enum frame_types { |
enum frame_types { |
205 |
no_frame = -1, |
no_frame = -1, |
206 |
no_stack = -2 |
no_stack = -2 |
211 |
type_prune = 1, |
type_prune = 1, |
212 |
type_skip = 2, |
type_skip = 2, |
213 |
type_skip_arg = 3, |
type_skip_arg = 3, |
214 |
type_mark = 4 |
type_mark = 4, |
215 |
|
type_then_trap = 5 |
216 |
}; |
}; |
217 |
|
|
218 |
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); |
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args); |
299 |
BOOL inlined_pattern; |
BOOL inlined_pattern; |
300 |
} recurse_backtrack; |
} recurse_backtrack; |
301 |
|
|
302 |
|
typedef struct then_trap_backtrack { |
303 |
|
backtrack_common common; |
304 |
|
struct then_trap_backtrack *then_trap; |
305 |
|
jump_list *quit; |
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 { |
317 |
int *private_data_ptrs; |
int *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 in the pattern. */ |
/* (*SKIP:arg) is found in the pattern. */ |
355 |
BOOL has_skip_arg; |
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 assert. */ |
620 |
case OP_BRAPOSZERO: |
case OP_BRAPOSZERO: |
621 |
case OP_PRUNE: |
case OP_PRUNE: |
622 |
case OP_SKIP: |
case OP_SKIP: |
623 |
|
case OP_THEN: |
624 |
case OP_COMMIT: |
case OP_COMMIT: |
625 |
case OP_FAIL: |
case OP_FAIL: |
626 |
case OP_ACCEPT: |
case OP_ACCEPT: |
721 |
case OP_MARK: |
case OP_MARK: |
722 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
723 |
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
724 |
|
case OP_THEN_ARG: |
725 |
return cc + 1 + 2 + cc[1]; |
return cc + 1 + 2 + cc[1]; |
726 |
|
|
727 |
default: |
default: |
973 |
cc += 2 + 2 * LINK_SIZE; |
cc += 2 + 2 * LINK_SIZE; |
974 |
break; |
break; |
975 |
|
|
976 |
|
case OP_THEN_ARG: |
977 |
|
common->has_then = TRUE; |
978 |
|
/* Fall through. */ |
979 |
|
|
980 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
981 |
common->needs_start_ptr = TRUE; |
common->needs_start_ptr = TRUE; |
982 |
common->control_head_ptr = 1; |
common->control_head_ptr = 1; |
991 |
cc += 1 + 2 + cc[1]; |
cc += 1 + 2 + cc[1]; |
992 |
break; |
break; |
993 |
|
|
994 |
|
case OP_THEN: |
995 |
|
common->has_then = TRUE; |
996 |
|
/* Fall through. */ |
997 |
|
|
998 |
case OP_PRUNE: |
case OP_PRUNE: |
999 |
case OP_SKIP: |
case OP_SKIP: |
1000 |
common->needs_start_ptr = TRUE; |
common->needs_start_ptr = TRUE; |
1185 |
} |
} |
1186 |
|
|
1187 |
/* Returns with a frame_types (always < 0) if no need for frame. */ |
/* Returns with a frame_types (always < 0) if no need for frame. */ |
1188 |
static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive, BOOL* needs_control_head) |
static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head) |
1189 |
{ |
{ |
|
pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE); |
|
1190 |
int length = 0; |
int length = 0; |
1191 |
int possessive = 0; |
int possessive = 0; |
1192 |
BOOL stack_restore = FALSE; |
BOOL stack_restore = FALSE; |
1202 |
*needs_control_head = FALSE; |
*needs_control_head = FALSE; |
1203 |
#endif |
#endif |
1204 |
|
|
1205 |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
if (ccend == NULL) |
1206 |
{ |
{ |
1207 |
possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; |
ccend = bracketend(cc) - (1 + LINK_SIZE); |
1208 |
/* This is correct regardless of common->capture_last_ptr. */ |
if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS)) |
1209 |
capture_last_found = TRUE; |
{ |
1210 |
|
possessive = length = (common->capture_last_ptr != 0) ? 5 : 3; |
1211 |
|
/* This is correct regardless of common->capture_last_ptr. */ |
1212 |
|
capture_last_found = TRUE; |
1213 |
|
} |
1214 |
|
cc = next_opcode(common, cc); |
1215 |
} |
} |
1216 |
|
|
|
cc = next_opcode(common, cc); |
|
1217 |
SLJIT_ASSERT(cc != NULL); |
SLJIT_ASSERT(cc != NULL); |
1218 |
while (cc < ccend) |
while (cc < ccend) |
1219 |
switch(*cc) |
switch(*cc) |
1231 |
|
|
1232 |
case OP_MARK: |
case OP_MARK: |
1233 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
1234 |
|
case OP_THEN_ARG: |
1235 |
SLJIT_ASSERT(common->mark_ptr != 0); |
SLJIT_ASSERT(common->mark_ptr != 0); |
1236 |
stack_restore = TRUE; |
stack_restore = TRUE; |
1237 |
if (!setmark_found) |
if (!setmark_found) |
1368 |
return stack_restore ? no_frame : no_stack; |
return stack_restore ? no_frame : no_stack; |
1369 |
} |
} |
1370 |
|
|
1371 |
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) |
1372 |
{ |
{ |
1373 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
|
pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE); |
|
1374 |
BOOL setsom_found = recursive; |
BOOL setsom_found = recursive; |
1375 |
BOOL setmark_found = recursive; |
BOOL setmark_found = recursive; |
1376 |
/* The last capture is a local variable even for recursions. */ |
/* The last capture is a local variable even for recursions. */ |
1382 |
SLJIT_ASSERT(stackpos >= stacktop + 2); |
SLJIT_ASSERT(stackpos >= stacktop + 2); |
1383 |
|
|
1384 |
stackpos = STACK(stackpos); |
stackpos = STACK(stackpos); |
1385 |
if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) |
if (ccend == NULL) |
1386 |
cc = next_opcode(common, cc); |
{ |
1387 |
|
ccend = bracketend(cc) - (1 + LINK_SIZE); |
1388 |
|
if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS)) |
1389 |
|
cc = next_opcode(common, cc); |
1390 |
|
} |
1391 |
|
|
1392 |
SLJIT_ASSERT(cc != NULL); |
SLJIT_ASSERT(cc != NULL); |
1393 |
while (cc < ccend) |
while (cc < ccend) |
1394 |
switch(*cc) |
switch(*cc) |
1409 |
|
|
1410 |
case OP_MARK: |
case OP_MARK: |
1411 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
1412 |
|
case OP_THEN_ARG: |
1413 |
SLJIT_ASSERT(common->mark_ptr != 0); |
SLJIT_ASSERT(common->mark_ptr != 0); |
1414 |
if (!setmark_found) |
if (!setmark_found) |
1415 |
{ |
{ |
1915 |
SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); |
SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); |
1916 |
} |
} |
1917 |
|
|
1918 |
|
static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset) |
1919 |
|
{ |
1920 |
|
pcre_uchar *end = bracketend(cc); |
1921 |
|
BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; |
1922 |
|
|
1923 |
|
/* Assert captures then. */ |
1924 |
|
if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) |
1925 |
|
current_offset = NULL; |
1926 |
|
/* Conditional block does not. */ |
1927 |
|
if (*cc == OP_COND || *cc == OP_SCOND) |
1928 |
|
has_alternatives = FALSE; |
1929 |
|
|
1930 |
|
cc = next_opcode(common, cc); |
1931 |
|
if (has_alternatives) |
1932 |
|
current_offset = common->then_offsets + (cc - common->start); |
1933 |
|
|
1934 |
|
while (cc < end) |
1935 |
|
{ |
1936 |
|
if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND)) |
1937 |
|
cc = set_then_offsets(common, cc, current_offset); |
1938 |
|
else |
1939 |
|
{ |
1940 |
|
if (*cc == OP_ALT && has_alternatives) |
1941 |
|
current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); |
1942 |
|
if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) |
1943 |
|
*current_offset = 1; |
1944 |
|
cc = next_opcode(common, cc); |
1945 |
|
} |
1946 |
|
} |
1947 |
|
|
1948 |
|
return end; |
1949 |
|
} |
1950 |
|
|
1951 |
#undef CASE_ITERATOR_PRIVATE_DATA_1 |
#undef CASE_ITERATOR_PRIVATE_DATA_1 |
1952 |
#undef CASE_ITERATOR_PRIVATE_DATA_2A |
#undef CASE_ITERATOR_PRIVATE_DATA_2A |
1953 |
#undef CASE_ITERATOR_PRIVATE_DATA_2B |
#undef CASE_ITERATOR_PRIVATE_DATA_2B |
2117 |
return -1; |
return -1; |
2118 |
|
|
2119 |
case type_prune: |
case type_prune: |
2120 |
|
case type_then_trap: |
2121 |
break; |
break; |
2122 |
|
|
2123 |
case type_skip: |
case type_skip: |
2147 |
return (return_value != 0 || skip_arg == NULL) ? return_value : -2; |
return (return_value != 0 || skip_arg == NULL) ? return_value : -2; |
2148 |
} |
} |
2149 |
|
|
2150 |
|
static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current) |
2151 |
|
{ |
2152 |
|
do |
2153 |
|
{ |
2154 |
|
switch (current[-2]) |
2155 |
|
{ |
2156 |
|
case type_commit: |
2157 |
|
/* Commit overwrites all. */ |
2158 |
|
return 0; |
2159 |
|
|
2160 |
|
case type_then_trap: |
2161 |
|
return (sljit_sw)current; |
2162 |
|
|
2163 |
|
case type_prune: |
2164 |
|
case type_skip: |
2165 |
|
case type_skip_arg: |
2166 |
|
case type_mark: |
2167 |
|
break; |
2168 |
|
|
2169 |
|
default: |
2170 |
|
SLJIT_ASSERT_STOP(); |
2171 |
|
break; |
2172 |
|
} |
2173 |
|
current = (sljit_sw*)current[-1]; |
2174 |
|
SLJIT_ASSERT(current != NULL); |
2175 |
|
} |
2176 |
|
while (TRUE); |
2177 |
|
} |
2178 |
|
|
2179 |
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) |
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket) |
2180 |
{ |
{ |
2181 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
5388 |
PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); |
PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL); |
5389 |
|
|
5390 |
/* Inlining simple patterns. */ |
/* Inlining simple patterns. */ |
5391 |
if (get_framesize(common, common->start + start, TRUE, &needs_control_head) == no_stack) |
if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack) |
5392 |
{ |
{ |
5393 |
start_cc = common->start + start; |
start_cc = common->start + start; |
5394 |
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); |
5558 |
jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; |
jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; |
5559 |
jump_list **found; |
jump_list **found; |
5560 |
/* Saving previous accept variables. */ |
/* Saving previous accept variables. */ |
5561 |
|
BOOL save_local_exit = common->local_exit; |
5562 |
|
then_trap_backtrack *save_then_trap = common->then_trap; |
5563 |
struct sljit_label *save_quit_label = common->quit_label; |
struct sljit_label *save_quit_label = common->quit_label; |
5564 |
struct sljit_label *save_accept_label = common->accept_label; |
struct sljit_label *save_accept_label = common->accept_label; |
5565 |
jump_list *save_quit = common->quit; |
jump_list *save_quit = common->quit; |
5566 |
jump_list *save_accept = common->accept; |
jump_list *save_accept = common->accept; |
|
BOOL save_local_exit = common->local_exit; |
|
5567 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
5568 |
struct sljit_jump *brajump = NULL; |
struct sljit_jump *brajump = NULL; |
5569 |
|
|
5570 |
|
/* Assert captures then. */ |
5571 |
|
common->then_trap = NULL; |
5572 |
|
|
5573 |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) |
5574 |
{ |
{ |
5575 |
SLJIT_ASSERT(!conditional); |
SLJIT_ASSERT(!conditional); |
5578 |
} |
} |
5579 |
private_data_ptr = PRIVATE_DATA(cc); |
private_data_ptr = PRIVATE_DATA(cc); |
5580 |
SLJIT_ASSERT(private_data_ptr != 0); |
SLJIT_ASSERT(private_data_ptr != 0); |
5581 |
framesize = get_framesize(common, cc, FALSE, &needs_control_head); |
framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); |
5582 |
backtrack->framesize = framesize; |
backtrack->framesize = framesize; |
5583 |
backtrack->private_data_ptr = private_data_ptr; |
backtrack->private_data_ptr = private_data_ptr; |
5584 |
opcode = *cc; |
opcode = *cc; |
5628 |
} |
} |
5629 |
else |
else |
5630 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); |
5631 |
init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE); |
init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); |
5632 |
} |
} |
5633 |
|
|
5634 |
memset(&altbacktrack, 0, sizeof(backtrack_common)); |
memset(&altbacktrack, 0, sizeof(backtrack_common)); |
5650 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
5651 |
{ |
{ |
5652 |
common->local_exit = save_local_exit; |
common->local_exit = save_local_exit; |
5653 |
|
common->then_trap = save_then_trap; |
5654 |
common->quit_label = save_quit_label; |
common->quit_label = save_quit_label; |
5655 |
common->accept_label = save_accept_label; |
common->accept_label = save_accept_label; |
5656 |
common->quit = save_quit; |
common->quit = save_quit; |
5719 |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) |
5720 |
{ |
{ |
5721 |
common->local_exit = save_local_exit; |
common->local_exit = save_local_exit; |
5722 |
|
common->then_trap = save_then_trap; |
5723 |
common->quit_label = save_quit_label; |
common->quit_label = save_quit_label; |
5724 |
common->accept_label = save_accept_label; |
common->accept_label = save_accept_label; |
5725 |
common->quit = save_quit; |
common->quit = save_quit; |
5900 |
} |
} |
5901 |
|
|
5902 |
common->local_exit = save_local_exit; |
common->local_exit = save_local_exit; |
5903 |
|
common->then_trap = save_then_trap; |
5904 |
common->quit_label = save_quit_label; |
common->quit_label = save_quit_label; |
5905 |
common->accept_label = save_accept_label; |
common->accept_label = save_accept_label; |
5906 |
common->quit = save_quit; |
common->quit = save_quit; |
6233 |
SLJIT_ASSERT(private_data_ptr != 0); |
SLJIT_ASSERT(private_data_ptr != 0); |
6234 |
BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; |
BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; |
6235 |
if (opcode == OP_ONCE) |
if (opcode == OP_ONCE) |
6236 |
BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE, &needs_control_head); |
BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head); |
6237 |
} |
} |
6238 |
|
|
6239 |
/* Instructions before the first alternative. */ |
/* Instructions before the first alternative. */ |
6383 |
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); |
6384 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0); |
6385 |
} |
} |
6386 |
init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); |
init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE); |
6387 |
} |
} |
6388 |
} |
} |
6389 |
else if (opcode == OP_CBRA || opcode == OP_SCBRA) |
else if (opcode == OP_CBRA || opcode == OP_SCBRA) |
6677 |
break; |
break; |
6678 |
} |
} |
6679 |
|
|
6680 |
framesize = get_framesize(common, cc, FALSE, &needs_control_head); |
framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); |
6681 |
BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; |
BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize; |
6682 |
if (framesize < 0) |
if (framesize < 0) |
6683 |
{ |
{ |
6770 |
stack++; |
stack++; |
6771 |
} |
} |
6772 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0); |
6773 |
init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE); |
init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE); |
6774 |
stack -= 1 + (offset == 0); |
stack -= 1 + (offset == 0); |
6775 |
} |
} |
6776 |
|
|
7277 |
return cc + 1 + IMM2_SIZE; |
return cc + 1 + IMM2_SIZE; |
7278 |
} |
} |
7279 |
|
|
7280 |
|
static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) |
7281 |
|
{ |
7282 |
|
DEFINE_COMPILER; |
7283 |
|
backtrack_common *backtrack; |
7284 |
|
pcre_uchar opcode = *cc; |
7285 |
|
pcre_uchar *ccend = cc + 1; |
7286 |
|
|
7287 |
|
SLJIT_ASSERT(common->control_head_ptr != 0 || *cc == OP_COMMIT); |
7288 |
|
|
7289 |
|
if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) |
7290 |
|
ccend += 2 + cc[1]; |
7291 |
|
|
7292 |
|
PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); |
7293 |
|
|
7294 |
|
if (opcode == OP_SKIP || opcode == OP_SKIP_ARG) |
7295 |
|
{ |
7296 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
7297 |
|
allocate_stack(common, 3); |
7298 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
7299 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg); |
7300 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), (opcode == OP_SKIP) ? STR_PTR : SLJIT_IMM, (opcode == OP_SKIP) ? 0 : (sljit_sw)(cc + 2)); |
7301 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
7302 |
|
return ccend; |
7303 |
|
} |
7304 |
|
|
7305 |
|
if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) |
7306 |
|
{ |
7307 |
|
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); |
7308 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); |
7309 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); |
7310 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); |
7311 |
|
} |
7312 |
|
|
7313 |
|
if (common->control_head_ptr != 0 && ((opcode != OP_THEN && opcode != OP_THEN_ARG) || common->then_trap == NULL)) |
7314 |
|
{ |
7315 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
7316 |
|
allocate_stack(common, 2); |
7317 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
7318 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune); |
7319 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
7320 |
|
} |
7321 |
|
|
7322 |
|
return ccend; |
7323 |
|
} |
7324 |
|
|
7325 |
|
static pcre_uchar then_trap_opcode[1] = { OP_TABLE_LENGTH }; |
7326 |
|
|
7327 |
|
static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) |
7328 |
|
{ |
7329 |
|
DEFINE_COMPILER; |
7330 |
|
backtrack_common *backtrack; |
7331 |
|
BOOL needs_control_head; |
7332 |
|
int size; |
7333 |
|
|
7334 |
|
PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); |
7335 |
|
common->then_trap = BACKTRACK_AS(then_trap_backtrack); |
7336 |
|
BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; |
7337 |
|
BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head); |
7338 |
|
|
7339 |
|
size = BACKTRACK_AS(then_trap_backtrack)->framesize; |
7340 |
|
size = 2 + (size < 0 ? 0 : size); |
7341 |
|
|
7342 |
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
7343 |
|
allocate_stack(common, size); |
7344 |
|
if (size > 2) |
7345 |
|
OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 2) * sizeof(sljit_sw)); |
7346 |
|
else |
7347 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
7348 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, type_then_trap); |
7349 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), TMP2, 0); |
7350 |
|
|
7351 |
|
size = BACKTRACK_AS(then_trap_backtrack)->framesize; |
7352 |
|
if (size >= 0) |
7353 |
|
init_frame(common, cc, ccend, size - 1, 0, FALSE); |
7354 |
|
} |
7355 |
|
|
7356 |
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) |
7357 |
{ |
{ |
7358 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7359 |
backtrack_common *backtrack; |
backtrack_common *backtrack; |
7360 |
|
BOOL has_then_trap = FALSE; |
7361 |
|
then_trap_backtrack *save_then_trap = NULL; |
7362 |
|
|
7363 |
|
SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS)); |
7364 |
|
|
7365 |
|
if (common->has_then && common->then_offsets[cc - common->start] != 0) |
7366 |
|
{ |
7367 |
|
SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0); |
7368 |
|
has_then_trap = TRUE; |
7369 |
|
save_then_trap = common->then_trap; |
7370 |
|
/* Tail item on backtrack. */ |
7371 |
|
compile_then_trap_matchingpath(common, cc, ccend, parent); |
7372 |
|
} |
7373 |
|
|
7374 |
while (cc < ccend) |
while (cc < ccend) |
7375 |
{ |
{ |
7604 |
cc += 1 + 2 + cc[1]; |
cc += 1 + 2 + cc[1]; |
7605 |
break; |
break; |
7606 |
|
|
|
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. */ |
|
|
|
|
7607 |
case OP_PRUNE: |
case OP_PRUNE: |
7608 |
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; |
|
|
|
|
7609 |
case OP_SKIP: |
case OP_SKIP: |
7610 |
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
7611 |
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc); |
case OP_THEN: |
7612 |
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
case OP_THEN_ARG: |
7613 |
allocate_stack(common, 3); |
case OP_COMMIT: |
7614 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0); |
cc = compile_control_verb_matchingpath(common, cc, parent); |
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), *cc == OP_SKIP ? STR_PTR : SLJIT_IMM, *cc == OP_SKIP ? 0 : (sljit_sw)(cc + 2)); |
|
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); |
|
|
cc += (*cc == OP_SKIP_ARG) ? (1 + 2 + cc[1]) : 1; |
|
7615 |
break; |
break; |
7616 |
|
|
7617 |
case OP_FAIL: |
case OP_FAIL: |
7635 |
if (cc == NULL) |
if (cc == NULL) |
7636 |
return; |
return; |
7637 |
} |
} |
7638 |
|
|
7639 |
|
if (has_then_trap) |
7640 |
|
{ |
7641 |
|
/* Head item on backtrack. */ |
7642 |
|
PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc); |
7643 |
|
BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode; |
7644 |
|
BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap; |
7645 |
|
common->then_trap = save_then_trap; |
7646 |
|
} |
7647 |
SLJIT_ASSERT(cc == ccend); |
SLJIT_ASSERT(cc == ccend); |
7648 |
} |
} |
7649 |
|
|
7805 |
} |
} |
7806 |
} |
} |
7807 |
|
|
7808 |
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) |
7809 |
{ |
{ |
7810 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7811 |
pcre_uchar *cc = current->cc; |
pcre_uchar *cc = current->cc; |
7827 |
free_stack(common, 2); |
free_stack(common, 2); |
7828 |
} |
} |
7829 |
|
|
7830 |
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) |
7831 |
{ |
{ |
7832 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
7833 |
|
|
8327 |
} |
} |
8328 |
} |
} |
8329 |
|
|
8330 |
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) |
8331 |
{ |
{ |
8332 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
8333 |
int offset; |
int offset; |
8366 |
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)); |
8367 |
} |
} |
8368 |
|
|
8369 |
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) |
8370 |
{ |
{ |
8371 |
assert_backtrack backtrack; |
assert_backtrack backtrack; |
8372 |
|
|
8390 |
SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); |
SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); |
8391 |
} |
} |
8392 |
|
|
8393 |
|
static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8394 |
|
{ |
8395 |
|
DEFINE_COMPILER; |
8396 |
|
pcre_uchar opcode = *current->cc; |
8397 |
|
|
8398 |
|
SLJIT_ASSERT(common->control_head_ptr != 0); |
8399 |
|
|
8400 |
|
if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL) |
8401 |
|
{ |
8402 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
8403 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
8404 |
|
sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_then_trap)); |
8405 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
8406 |
|
|
8407 |
|
if (common->quit_label == NULL) |
8408 |
|
add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0)); |
8409 |
|
else |
8410 |
|
CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0, common->quit_label); |
8411 |
|
|
8412 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, TMP1, 0); |
8413 |
|
add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP)); |
8414 |
|
return; |
8415 |
|
} |
8416 |
|
|
8417 |
|
if (!common->local_exit) |
8418 |
|
{ |
8419 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr); |
8420 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); |
8421 |
|
sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain)); |
8422 |
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); |
8423 |
|
|
8424 |
|
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); |
8425 |
|
add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1)); |
8426 |
|
|
8427 |
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); |
8428 |
|
} |
8429 |
|
|
8430 |
|
/* Commit or in recurse or accept. */ |
8431 |
|
if (common->quit_label == NULL) |
8432 |
|
add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); |
8433 |
|
else |
8434 |
|
JUMPTO(SLJIT_JUMP, common->quit_label); |
8435 |
|
} |
8436 |
|
|
8437 |
|
static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8438 |
|
{ |
8439 |
|
DEFINE_COMPILER; |
8440 |
|
struct sljit_jump *jump; |
8441 |
|
int size; |
8442 |
|
|
8443 |
|
if (CURRENT_AS(then_trap_backtrack)->then_trap) |
8444 |
|
{ |
8445 |
|
common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap; |
8446 |
|
return; |
8447 |
|
} |
8448 |
|
|
8449 |
|
size = CURRENT_AS(then_trap_backtrack)->framesize; |
8450 |
|
size = 2 + (size < 0 ? 0 : size); |
8451 |
|
|
8452 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 2)); |
8453 |
|
free_stack(common, size); |
8454 |
|
jump = JUMP(SLJIT_JUMP); |
8455 |
|
|
8456 |
|
set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL()); |
8457 |
|
/* STACK_TOP is set by THEN. */ |
8458 |
|
if (CURRENT_AS(then_trap_backtrack)->framesize >= 0) |
8459 |
|
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); |
8460 |
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); |
8461 |
|
free_stack(common, 2); |
8462 |
|
|
8463 |
|
JUMPHERE(jump); |
8464 |
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0); |
8465 |
|
} |
8466 |
|
|
8467 |
static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) |
8468 |
{ |
{ |
8469 |
DEFINE_COMPILER; |
DEFINE_COMPILER; |
8470 |
|
then_trap_backtrack *save_then_trap = common->then_trap; |
8471 |
|
|
8472 |
while (current) |
while (current) |
8473 |
{ |
{ |
8610 |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0); |
8611 |
break; |
break; |
8612 |
|
|
8613 |
|
case OP_THEN: |
8614 |
|
case OP_THEN_ARG: |
8615 |
case OP_PRUNE: |
case OP_PRUNE: |
8616 |
case OP_PRUNE_ARG: |
case OP_PRUNE_ARG: |
8617 |
case OP_SKIP: |
case OP_SKIP: |
8618 |
if (!common->local_exit) |
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_CALL1, 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); |
|
8619 |
break; |
break; |
8620 |
|
|
8621 |
case OP_SKIP_ARG: |
case OP_SKIP_ARG: |
8667 |
set_jumps(current->topbacktracks, LABEL()); |
set_jumps(current->topbacktracks, LABEL()); |
8668 |
break; |
break; |
8669 |
|
|
8670 |
|
case OP_TABLE_LENGTH: |
8671 |
|
/* A virtual opcode for then traps. */ |
8672 |
|
compile_then_trap_backtrackingpath(common, current); |
8673 |
|
break; |
8674 |
|
|
8675 |
default: |
default: |
8676 |
SLJIT_ASSERT_STOP(); |
SLJIT_ASSERT_STOP(); |
8677 |
break; |
break; |
8678 |
} |
} |
8679 |
current = current->prev; |
current = current->prev; |
8680 |
} |
} |
8681 |
|
common->then_trap = save_then_trap; |
8682 |
} |
} |
8683 |
|
|
8684 |
static SLJIT_INLINE void compile_recurse(compiler_common *common) |
static SLJIT_INLINE void compile_recurse(compiler_common *common) |
8688 |
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); |
8689 |
pcre_uchar *ccend = bracketend(cc); |
pcre_uchar *ccend = bracketend(cc); |
8690 |
BOOL needs_control_head; |
BOOL needs_control_head; |
8691 |
int framesize = get_framesize(common, cc, TRUE, &needs_control_head); |
int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); |
8692 |
int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); |
int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); |
8693 |
int alternativesize; |
int alternativesize; |
8694 |
BOOL needs_frame; |
BOOL needs_frame; |
8695 |
backtrack_common altbacktrack; |
backtrack_common altbacktrack; |
8696 |
struct sljit_jump *jump; |
struct sljit_jump *jump; |
8697 |
|
|
8698 |
|
/* Recurse captures then. */ |
8699 |
|
common->then_trap = NULL; |
8700 |
|
|
8701 |
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); |
8702 |
needs_frame = framesize >= 0; |
needs_frame = framesize >= 0; |
8703 |
if (!needs_frame) |
if (!needs_frame) |
8716 |
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); |
8717 |
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); |
8718 |
if (needs_frame) |
if (needs_frame) |
8719 |
init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); |
init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE); |
8720 |
|
|
8721 |
if (alternativesize > 0) |
if (alternativesize > 0) |
8722 |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); |
8980 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
8981 |
return; |
return; |
8982 |
} |
} |
8983 |
|
|
8984 |
common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); |
common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); |
8985 |
if (!common->private_data_ptrs) |
if (!common->private_data_ptrs) |
8986 |
{ |
{ |
8990 |
memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); |
memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); |
8991 |
set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend); |
set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend); |
8992 |
|
|
8993 |
|
if (common->has_then) |
8994 |
|
{ |
8995 |
|
common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc); |
8996 |
|
if (!common->then_offsets) |
8997 |
|
{ |
8998 |
|
SLJIT_FREE(common->optimized_cbracket); |
8999 |
|
SLJIT_FREE(common->private_data_ptrs); |
9000 |
|
return; |
9001 |
|
} |
9002 |
|
memset(common->then_offsets, 0, ccend - rootbacktrack.cc); |
9003 |
|
set_then_offsets(common, rootbacktrack.cc, NULL); |
9004 |
|
} |
9005 |
|
|
9006 |
compiler = sljit_create_compiler(); |
compiler = sljit_create_compiler(); |
9007 |
if (!compiler) |
if (!compiler) |
9008 |
{ |
{ |
9009 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9010 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9011 |
|
if (common->has_then) |
9012 |
|
SLJIT_FREE(common->then_offsets); |
9013 |
return; |
return; |
9014 |
} |
} |
9015 |
common->compiler = compiler; |
common->compiler = compiler; |
9101 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9102 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9103 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9104 |
|
if (common->has_then) |
9105 |
|
SLJIT_FREE(common->then_offsets); |
9106 |
return; |
return; |
9107 |
} |
} |
9108 |
|
|
9138 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9139 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9140 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9141 |
|
if (common->has_then) |
9142 |
|
SLJIT_FREE(common->then_offsets); |
9143 |
return; |
return; |
9144 |
} |
} |
9145 |
|
|
9207 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |
9208 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9209 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9210 |
|
if (common->has_then) |
9211 |
|
SLJIT_FREE(common->then_offsets); |
9212 |
return; |
return; |
9213 |
} |
} |
9214 |
flush_stubs(common); |
flush_stubs(common); |
9317 |
|
|
9318 |
SLJIT_FREE(common->optimized_cbracket); |
SLJIT_FREE(common->optimized_cbracket); |
9319 |
SLJIT_FREE(common->private_data_ptrs); |
SLJIT_FREE(common->private_data_ptrs); |
9320 |
|
if (common->has_then) |
9321 |
|
SLJIT_FREE(common->then_offsets); |
9322 |
|
|
9323 |
executable_func = sljit_generate_code(compiler); |
executable_func = sljit_generate_code(compiler); |
9324 |
executable_size = sljit_get_generated_code_size(compiler); |
executable_size = sljit_get_generated_code_size(compiler); |
9325 |
sljit_free_compiler(compiler); |
sljit_free_compiler(compiler); |