blob: 77535e4ad6038bc24916a44c93c60fe921dbe34b [file] [edit]
//@ runDefault("--useConcurrentJIT=0")
// Test for YarrJIT's allocateParenContext m_abortExecution path.
// This path is taken when:
// 1. Stack is exhausted due to repeatedly allocated ParenContext
// 2. ParenContext is not freed before exhausting the stack
//
// ParenContext is allocated for quantified capturing groups. To exhaust
// the stack without freeing, we create deeply nested quantified capturing
// groups that all match, causing allocation of many ParenContexts on the
// stack before any can be freed through backtracking.
function createDeeplyNestedPattern(depth) {
let pattern = "a";
for (let i = 0; i < depth; i++) {
pattern = "(" + pattern + ")*";
}
return pattern;
}
function test(depth, inputLength) {
let pattern = createDeeplyNestedPattern(depth);
let input = "a".repeat(inputLength);
let regex = new RegExp(pattern);
// When stack is exhausted, the match should return null
// (the JIT aborts execution and falls back to interpreter,
// which may also fail or return null)
try {
let result = regex.exec(input);
// If we get here, the test didn't exhaust the stack
// Print for debugging but don't fail - stack limits vary by platform
if (result !== null) {
// print("Match succeeded (stack not exhausted): depth=" + depth + ", inputLength=" + inputLength);
}
} catch (e) {
// Some platforms might throw instead of returning null
// This is acceptable behavior for stack exhaustion
// print("Exception (expected for stack exhaustion): " + e);
}
}
// Test with deep nesting but very short input to avoid catastrophic backtracking
// The key is to have many nested levels that each allocate a ParenContext,
// but keep the input short enough to avoid exponential backtracking time
// These should be fast (no backtracking explosion) but allocate many ParenContexts
test(100, 1);
test(200, 1);
test(300, 1);
test(500, 1);
// With 2-character input, each level can match 0, 1, or 2 chars,
// but with deep nesting this still triggers stack allocation
test(100, 2);
test(200, 2);
// print("Test completed - stack exhaustion path exercised");