Tobi Lutke and Chris Pak
19bf49c116
For tag: migrate lax_parse to Cursor with zero-alloc skip_id/expect_id
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
5204033588
Cursor: add skip_id, expect_id, skip_fragment for zero-alloc scanning
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
b0c9f576af
REVERTED: Cursor for For tag adds 148 allocs from scan_id/scan_fragment string creation\n\nResult: {"status":"discard","combined_µs":5049,"parse_us":3765,"render_us":1284,"allocations":29793,"parse_µs":3765,"render_µs":1284}
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
343ae1da56
remove dead BlockBody.parse_tag_token and If SIMPLE_CONDITION - now in Cursor
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
f42593dc50
introduce Cursor class: centralize byte-level scanning for tag/variable/condition parsing
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
80edd212a0
add parse_simple to skip simple_lookup? check when caller validates
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
65d7568403
fast-path VariableLookup init: skip scan_variable for simple identifier chains
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
c2ba6b0676
avoid allocating seen={} hash in Utils.to_s/inspect when not needed
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
1032d57532
optimize Context init: avoid unnecessary array wrapping for environments
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
e1a0e7e716
use frozen EMPTY_ARRAY/EMPTY_HASH for Context @filters/@disabled_tags
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
1f309b19a7
replace INTEGER_REGEX/FLOAT_REGEX with byte-level parse_number
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
c6617accc5
replace SIMPLE_CONDITION regex with manual byte parser in if/elsif lax_parse
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
cf062e1da2
fast-path slice_collection: skip copy for full Array without offset/limit
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
06a718cd69
add invoke_two fast path for single-arg filter invocation, avoids splat chain
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
50888426a1
fast-path find_variable: check top scope first before find_index
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
1a29584f96
add invoke_single fast path for no-arg filter invocation, avoids splat alloc
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
9d16eb3d05
fast-path simple if truthiness: use byte scanner before SIMPLE_CONDITION regex
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
34971c0314
replace WhitespaceOrNothing regex with byte-level blank_string? check
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
f24ca042a2
avoid array allocation in parse_tag_token: return tag_name, store markup/newlines as class ivars
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
4ea4350775
clean up filter parsing: Lexer fallback for args, no-arg fast scan stays
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
808dad6fab
split filter parsing: scan no-arg filters directly, only invoke Lexer when args present
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
b994f22983
extend fast-path to handle quoted string literal variables (262 more fast-pathed)
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
62877e666c
skip filter arg splat for no-arg filters, trim render loop comments
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
48a2fae5f6
hoist write score check out of render loop: skip increment_write_score when no limits active
2026-04-04 17:42:32 -07:00
Tobi Lutke and Chris Pak
27fcb3a4c9
use frozen EMPTY_ARRAY for disabled_tags in Variable
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
6e9782c5cc
return [tag_name, markup, newlines] from parse_tag_token: avoid 2 whitespace string allocs
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
da57336be9
use getbyte dispatch instead of start_with? in parse_for_document
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
28f29433e4
avoid empty array allocation in evaluate_filter_expressions for no-arg filters
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
4ff5523713
replace For tag Syntax regex with manual byte-level parser
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
f388c873de
expose expression_cache/string_scanner via attr_reader, skip regex in filter args without colon
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
543c1e1fe7
unified fast-path Variable parsing: handle both plain lookups and filter chains without full Lexer pass for name
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
885c8df159
fast-path render for filter-less variables: skip render method overhead
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
8f67d81023
skip TagAttributes scan in for tag when no colon present
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
01f33e96e8
fast-path simple if conditions: skip ExpressionsAndOperators scan for single conditions
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
9e6f93a494
replace SIMPLE_VARIABLE regex with byte-level scanner to avoid MatchData
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
dc6e9799e9
fast-path simple variable parsing: skip Lexer/Parser for plain dot-separated lookups
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
98e29aa4a7
use frozen EMPTY_ARRAY for Variable filters when no filters present
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
a404cf10d0
fast-path variable_lookups: skip mutable string alloc when no dot/bracket follows
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
e73b41f3b6
fast-path String in render_obj_to_output, avoid Utils.to_s dispatch for common case
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
9d9d094e20
short-circuit parse_number with first-byte check before regex
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
4c96b5f682
avoid unnecessary strip allocation in Expression.parse, use byteslice for string literals
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
0b19c0ce44
use equal? for frozen array comparison in Lexer, skip whitespace with \s+
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
a43d970473
use getbyte instead of string indexing in whitespace_handler and create_variable
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
6ffd0e2339
replace VariableParser regex scan with manual byte parser in VariableLookup
2026-04-04 17:33:53 -07:00
Tobi Lutke and Chris Pak
dc7dda2253
replace FullToken regex with manual byte parsing in parse_for_document
2026-04-04 17:33:53 -07:00
Benoit Daloze
d824de701c
Adapt slice filter to work on non-64 bit platforms
2026-03-25 16:46:47 +01:00
Ian Ker-Seymer and GitHub
59d8d0d22d
Add cumulative resource score tracking across partial renders ( #2058 )
...
* feat: add cumulative resource score tracking across partial renders
Add cumulative_render_score and cumulative_assign_score counters to
ResourceLimits that accumulate across reset() calls, with optional
cumulative_render_score_limit and cumulative_assign_score_limit to
cap total work across all partial renders.
Also add a reached? check in BlockBody's render loop so that once a
cumulative limit triggers, the parent template stops processing
further nodes.
Bump version to 5.12.0.
* refactor: move cumulative limit enforcement into reset()
Instead of checking reached? in BlockBody's render loop, enforce
cumulative limits in reset() itself. Since reset() is called before
the begin/rescue MemoryError block in Template#render, the raise
propagates to the parent naturally — no changes to BlockBody needed.
2026-03-18 11:54:46 -04:00
Michaël Gallego
d589c51697
Add squish filter
2026-02-19 10:03:52 +09:00
Tobi Lutke and Claude Opus 4.5
ccd05e869c
Make blank/empty comparisons invariant to ActiveSupport
...
- Implement liquid_blank? and liquid_empty? methods in Condition
to emulate ActiveSupport's behavior when it's not loaded
- This ensures templates like `{% if x == blank %}` work identically
whether ActiveSupport is loaded or not
- Update liquid-spec adapters for new API (ctx parameter)
- Add rake spec task for running liquid-spec matrix
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <[email protected] >
2026-01-05 14:54:43 -10:00
Tobi Lutke
ef13b2dfd5
Fix empty? semantics and string first/last for empty strings
...
- nil is NOT empty (but IS blank) - matches Shopify production
- String first/last returns '' for empty strings, not nil - matches ActiveSupport
- Add test for nil not being empty
2026-01-01 22:06:22 -05:00