Skip to content

JIT: honour offset limits when FIRSTLINE is enabled - #1030

Open
NWilson wants to merge 3 commits into
mainfrom
user/niwilson/jit-firstline
Open

NWilson wants to merge 3 commits into
mainfrom
user/niwilson/jit-firstline

Conversation

@NWilson

@NWilson NWilson commented Oct 4, 2026

Copy link
Copy Markdown
Member

The JIT treated FIRSTLINE and USE_OFFSET_LIMIT as mutually exclusive, so enabling FIRSTLINE caused an explicit offset limit to be ignored. This allowed matches beyond the requested starting-offset limit, unlike the interpreter.

Note that the documentation explicitly says both are supported together, and if so, whichever limit is earlier applies.

Generate both checks and use the earlier of the FIRSTLINE boundary and the offset-limit boundary. Preserve the FIRSTLINE boundary when the offset limit is unset.

Add shared interpreter/JIT regression tests covering inclusive limits, nonzero starting offsets, LF/CRLF, and start optimizations. Without the fix, 11 new cases fail under JIT at each code-unit width; with it, test 2 passes under both engines at all widths.

Comment thread src/pcre2_jit_compile.c Outdated
OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
if ((overall_options & PCRE2_FIRSTLINE) != 0)
{
OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use TMP1 here. TMP3 is memory on x86-32.

@zherczeg

zherczeg commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

Thinking about it the offset limit could limit the newline search. Hence, if start+offset_limit<str_end it is better to search until that point. The str_end could be saved temporariliy, and restored afterwards.

The JIT treated FIRSTLINE and USE_OFFSET_LIMIT as mutually
exclusive, so enabling FIRSTLINE caused an explicit offset
limit to be ignored. This allowed matches beyond the
requested starting-offset limit, unlike the interpreter.

Generate both checks and use the earlier of the FIRSTLINE
boundary and the offset-limit boundary. Preserve the
FIRSTLINE boundary when the offset limit is unset.

Add shared interpreter/JIT regression tests covering inclusive
limits, nonzero starting offsets, LF/CRLF, and start
optimizations. Without the fix, 11 new cases fail under
JIT at each code-unit width; with it, test 2 passes under
both engines at all widths.
The offset in TMP1 has been used and can now be clobbered.
@NWilson
NWilson force-pushed the user/niwilson/jit-firstline branch from 60b8b68 to 32966b2 Compare October 19, 2026 12:19
@NWilson

NWilson commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Thinking about it the offset limit could limit the newline search. Hence, if start+offset_limit<str_end it is better to search until that point. The str_end could be saved temporariliy, and restored afterwards.

Thanks Zoltan. I have kept the existing structure of the code unchanged, but added in an extra block of code for the newline checking, which activates when the offset_limit is also set.

I have temporarily reduced STR_END for the newline scan, and restored it from LOCAL0.

I opted to keep the existing structure, but add an offset_limit
optimisation as a special case to the newline lookup. I am keeping the
existing newline lookup, but with a temporarily-reduced STR_END value.

The saved value goes in a blank LOCAL0 slot.
@NWilson
NWilson force-pushed the user/niwilson/jit-firstline branch from 32966b2 to 595ec76 Compare October 19, 2026 13:36

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants