Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: eef70034791ac18f0fc680b79f56eda5eae6a2aa
https://github.com/WebKit/WebKit/commit/eef70034791ac18f0fc680b79f56eda5eae6a2aa
Author: Yusuke Suzuki <[email protected]>
Date: 2026-02-03 (Tue, 03 Feb 2026)
Changed paths:
A JSTests/stress/regexp-fixedcount-multi-alt-backtracking.js
M Source/JavaScriptCore/yarr/YarrJIT.cpp
M Source/JavaScriptCore/yarr/YarrJIT.h
Log Message:
-----------
[JSC] Yarr JIT should support fixed-count parentheses with capture
https://bugs.webkit.org/show_bug.cgi?id=306798
rdar://169474168
Reviewed by Yijia Huang.
This patch extends ParenContext so that we can support FixedCount (w/
backtracking) in ParenthesesSubpatternBegin / ParenthesesSubpatternEnd.
The key is fixed-count subpattern needs to save the state of the end of
the iteration, to perform backtracking later.
This is a big step towards supporting all RegExp in JIT. Given that
ParenContext can hold all frame slots, captures, index, and jump target
address, this means that ParenContext is saving entire execution
context, this can represent any backtracking in RegExp.
For FixedCount ParenContext, we save it at ParenthesesSubpatternEnd. And
we also save both begin and end index. The reason is that both index is
necessary: If we backtrack /(a+){2}b/'s (a+)'s iteration, we need the
end index, and decrese it by backtracking path of a+. But if we have
/(a|aaa){2}b/, then we need the begin index to use the different
alternative. So both index needs to be kept at the end to prepare for
the future backtracking.
Let's have /(a+){2}b/ with "aaab".
1. 1st iteration of (a+){2} will consume "aaa".
2. 2nd iteration of (a+){2} fails because it only sees "b".
3. Then we need to backtrack to the 1st iteration, and 1st
iteration's (a+) content starts backtracking. In this case,
it reduces a's greedy count from "aaa" to "aa".
4. Then 2nd iteration happens again with "ab", and pass with "a".
5. b passes.
So, the key thing is,
1. We need to save the state snapshot of the end of the iteration. This
is necessary to do a backtracking inside the previous iteration.
2. We need to save where to jump when the iteration needs backtracking.
In the above case (3) will backtrack in `a+` part. So the state
should save a program address of backtracking code of `a+`, which is
the start of the content of the parentheses.
Test: JSTests/stress/regexp-fixedcount-multi-alt-backtracking.js
* JSTests/stress/regexp-fixedcount-multi-alt-backtracking.js: Added.
(shouldBe):
(re):
(re.a.b):
(re.a):
(x):
(re.letter):
(re.outer):
(re.a.b.c):
(re.aa.a):
* Source/JavaScriptCore/yarr/YarrJIT.cpp:
(JSC::Yarr::dumpCompileFailure):
* Source/JavaScriptCore/yarr/YarrJIT.h:
Canonical link: https://commits.webkit.org/306744@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications