summaryrefslogtreecommitdiff
path: root/thirdparty/pcre2/src/pcre2_jit_compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/pcre2/src/pcre2_jit_compile.c')
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_compile.c89
1 files changed, 47 insertions, 42 deletions
diff --git a/thirdparty/pcre2/src/pcre2_jit_compile.c b/thirdparty/pcre2/src/pcre2_jit_compile.c
index 1977d28aa5..db2ce65598 100644
--- a/thirdparty/pcre2/src/pcre2_jit_compile.c
+++ b/thirdparty/pcre2/src/pcre2_jit_compile.c
@@ -1226,7 +1226,7 @@ while (cc < ccend)
return TRUE;
}
-#define EARLY_FAIL_ENHANCE_MAX (1 + 1)
+#define EARLY_FAIL_ENHANCE_MAX (1 + 3)
/*
start:
@@ -1236,23 +1236,28 @@ start:
return: current number of iterators enhanced with fast fail
*/
-static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, sljit_s32 depth, int start)
+static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start,
+ sljit_s32 depth, int start, BOOL fast_forward_allowed)
{
+PCRE2_SPTR begin = cc;
PCRE2_SPTR next_alt;
PCRE2_SPTR end;
PCRE2_SPTR accelerated_start;
+BOOL prev_fast_forward_allowed;
int result = 0;
int count;
-BOOL fast_forward_allowed = TRUE;
SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA);
SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0);
SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX);
+next_alt = cc + GET(cc, 1);
+if (*next_alt == OP_ALT)
+ fast_forward_allowed = FALSE;
+
do
{
count = start;
- next_alt = cc + GET(cc, 1);
cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
while (TRUE)
@@ -1475,31 +1480,20 @@ do
case OP_CBRA:
end = cc + GET(cc, 1);
- if (*end == OP_KET && PRIVATE_DATA(end) == 0)
- {
- if (*cc == OP_CBRA)
- {
- if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
- break;
- cc += IMM2_SIZE;
- }
-
- cc += 1 + LINK_SIZE;
- continue;
- }
-
+ prev_fast_forward_allowed = fast_forward_allowed;
fast_forward_allowed = FALSE;
if (depth >= 4)
break;
end = bracketend(cc) - (1 + LINK_SIZE);
- if (*end != OP_KET || PRIVATE_DATA(end) != 0)
+ if (*end != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0))
break;
- if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
- break;
+ count = detect_early_fail(common, cc, private_data_start, depth + 1, count, prev_fast_forward_allowed);
+
+ if (PRIVATE_DATA(cc) != 0)
+ common->private_data_ptrs[begin - common->start] = 1;
- count = detect_early_fail(common, cc, private_data_start, depth + 1, count);
if (count < EARLY_FAIL_ENHANCE_MAX)
{
cc = end + (1 + LINK_SIZE);
@@ -1521,7 +1515,7 @@ do
{
count++;
- if (fast_forward_allowed && *next_alt == OP_KET)
+ if (fast_forward_allowed)
{
common->fast_forward_bc_ptr = accelerated_start;
common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip;
@@ -1555,6 +1549,8 @@ do
return EARLY_FAIL_ENHANCE_MAX;
}
+ /* Cannot be part of a repeat. */
+ common->private_data_ptrs[begin - common->start] = 1;
count++;
if (count < EARLY_FAIL_ENHANCE_MAX)
@@ -1569,8 +1565,8 @@ do
else if (result < count)
result = count;
- fast_forward_allowed = FALSE;
cc = next_alt;
+ next_alt = cc + GET(cc, 1);
}
while (*cc == OP_ALT);
@@ -1620,11 +1616,12 @@ sljit_sw length = end - begin;
sljit_s32 min, max, i;
/* Detect fixed iterations first. */
-if (end[-(1 + LINK_SIZE)] != OP_KET)
+if (end[-(1 + LINK_SIZE)] != OP_KET || PRIVATE_DATA(begin) != 0)
return FALSE;
-/* Already detected repeat. */
-if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
+/* /(?:AB){4,6}/ is currently converted to /(?:AB){3}(?AB){1,3}/
+ * Skip the check of the second part. */
+if (PRIVATE_DATA(end - LINK_SIZE) == 0)
return TRUE;
next = end;
@@ -1763,6 +1760,7 @@ while (cc < ccend)
if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
break;
+ /* When the bracket is prefixed by a zero iteration, skip the repeat check (at this point). */
if (repeat_check && (*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
{
if (detect_repeat(common, cc))
@@ -1813,6 +1811,7 @@ while (cc < ccend)
case OP_COND:
/* Might be a hidden SCOND. */
+ common->private_data_ptrs[cc - common->start] = 0;
alternative = cc + GET(cc, 1);
if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
{
@@ -4203,9 +4202,6 @@ TMP2 is not used. Otherwise TMP2 must contain the start of the subject buffer,
and it is destroyed. Does not modify STR_PTR for invalid character sequences. */
DEFINE_COMPILER;
-SLJIT_UNUSED_ARG(backtracks);
-SLJIT_UNUSED_ARG(must_be_valid);
-
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
struct sljit_jump *jump;
#endif
@@ -4279,6 +4275,10 @@ if (common->invalid_utf && !must_be_valid)
}
#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
#endif /* SUPPORT_UNICODE */
+
+SLJIT_UNUSED_ARG(backtracks);
+SLJIT_UNUSED_ARG(must_be_valid);
+
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
}
@@ -8141,7 +8141,7 @@ switch(type)
}
else
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
if (!common->endonly)
compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
@@ -8161,7 +8161,7 @@ switch(type)
}
else
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
check_partial(common, FALSE);
jump[0] = JUMP(SLJIT_JUMP);
JUMPHERE(jump[1]);
@@ -8201,14 +8201,14 @@ switch(type)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
}
else
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
}
return cc;
@@ -8227,7 +8227,7 @@ switch(type)
jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
}
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO));
jump[0] = JUMP(SLJIT_JUMP);
JUMPHERE(jump[1]);
@@ -9581,11 +9581,11 @@ free_stack(common, callout_arg_size);
/* Check return value. */
OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
if (common->abort_label == NULL)
- add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
+ add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
else
- JUMPTO(SLJIT_NOT_EQUAL32 /* SIG_LESS */, common->abort_label);
+ JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->abort_label);
return cc + callout_length;
}
@@ -11232,7 +11232,7 @@ early_fail_type = (early_fail_ptr & 0x7);
early_fail_ptr >>= 3;
/* During recursion, these optimizations are disabled. */
-if (common->early_fail_start_ptr == 0)
+if (common->early_fail_start_ptr == 0 && common->fast_forward_bc_ptr == NULL)
{
early_fail_ptr = 0;
early_fail_type = type_skip;
@@ -13661,9 +13661,11 @@ if (!common->private_data_ptrs)
memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32));
private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
-set_private_data_ptrs(common, &private_data_size, ccend);
+
if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back)
- detect_early_fail(common, common->start, &private_data_size, 0, 0);
+ detect_early_fail(common, common->start, &private_data_size, 0, 0, TRUE);
+
+set_private_data_ptrs(common, &private_data_size, ccend);
SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr);
@@ -14130,6 +14132,10 @@ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_jit_compile(pcre2_code *code, uint32_t options)
{
pcre2_real_code *re = (pcre2_real_code *)code;
+#ifdef SUPPORT_JIT
+executable_functions *functions;
+static int executable_allocator_is_working = 0;
+#endif
if (code == NULL)
return PCRE2_ERROR_NULL;
@@ -14164,8 +14170,7 @@ actions are needed:
*/
#ifdef SUPPORT_JIT
-executable_functions *functions = (executable_functions *)re->executable_jit;
-static int executable_allocator_is_working = 0;
+functions = (executable_functions *)re->executable_jit;
#endif
if ((options & PCRE2_JIT_INVALID_UTF) != 0)