Fix large stack allocation
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index 4785425..a7f0a66 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c
@@ -101,7 +101,7 @@ /* Growth rate for stack allocated by the OS. Should be the multiply of page size. */ -#define STACK_GROWTH_RATE 8192 +#define STACK_GROWTH_RATE (sljit_sw)8192 /* Enable to check that the allocation could destroy temporaries. */ #if defined SLJIT_DEBUG && SLJIT_DEBUG @@ -472,6 +472,8 @@ BOOL local_quit_available; /* Currently in a positive assertion. */ BOOL in_positive_assertion; + /* More than STACK_GROWTH_RATE / 2 stack memory is allocated. */ + BOOL large_stack_allocation; /* Newline control. */ int nltype; sljit_u32 nlmax; @@ -3643,6 +3645,8 @@ DEFINE_COMPILER; SLJIT_ASSERT(size > 0); + if (size > (STACK_GROWTH_RATE / 2)) + common->large_stack_allocation = TRUE; OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * SSIZE_OF(sw)); #ifdef DESTROY_REGISTERS OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); @@ -15006,7 +15010,15 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); - OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE); + if (common->large_stack_allocation) + { + SLJIT_COMPILE_ASSERT((STACK_GROWTH_RATE & (STACK_GROWTH_RATE - 1)) == 0, stack_growth_must_be_poser_of_2); + OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, STACK_GROWTH_RATE / 2); + OP2(SLJIT_AND, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, ~(STACK_GROWTH_RATE - 1)); + } + else + OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE); + OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack)); OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);