Extract shared resolve_relative_index helper for slice/copyWithin/fill clamping#188
Open
pmatos wants to merge 1 commit into
Open
Extract shared resolve_relative_index helper for slice/copyWithin/fill clamping#188pmatos wants to merge 1 commit into
pmatos wants to merge 1 commit into
Conversation
…l clamping The "if n < 0, clamp to max(0, len+n), else min(len, n)" relative-index algorithm used by Array.prototype.slice/splice/toSpliced/fill/copyWithin, String.prototype.slice, and the %TypedArray%.prototype equivalents was hand-rolled independently at 9 call sites across array.rs, string.rs, and typedarray.rs, with typedarray.rs alone reimplementing it 4 different ways (including one inconsistency between `<` and `<=` at the lower boundary that happened to still produce the same result). Consolidated into one pure, directly unit-tested `resolve_relative_index` helper in helpers.rs. Added via TDD: 8 unit tests pin the boundary/infinity/zero-length behavior directly against the Rust function, with no JS parsing/interpreter involved, before sweeping the call sites over to it. 🤖 Generated with Claude Code Claude-Session: https://claude.ai/code/session_019oiTHXtesxw6uvcF31MU1p
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is a targeted architecture refactor from a codebase audit (using the
codebase-design/improve-codebase-architecturedeep-module vocabulary), aimed at eliminating duplicated, drift-prone logic rather than adding new features.The audit surfaced several duplication hotspots (receiver-validation boilerplate in
collections.rs, repeated Date getter wrappers, RegExp Symbol.match/replace/split loop duplication, a fragmented property-access interface ineval.rs/mod.rs). This PR tackles the highest-payoff, lowest-risk candidate: the relative-index clamping algorithm — "ifn < 0, clamp tomax(0, len+n), elsemin(len, n)" — used by the spec algorithms behindArray.prototype.slice/splice/toSpliced/fill/copyWithin,String.prototype.slice, and the%TypedArray%.prototypeequivalents.This algorithm was hand-rolled independently at 9 call sites across
array.rs,string.rs, andtypedarray.rs.typedarray.rsalone reimplemented it 4 different ways, including one genuine inconsistency between<and<=at the lower boundary (copyWithinvs.slice/subarray) that happened to still produce the same clamped result — a latent correctness risk that would only need one future edit to diverge for real.Deletion test: deleting all 9 inline implementations and factoring them into one helper makes 9 call sites shrink to one-liners; the arithmetic (a real correctness risk given NaN/Infinity/overflow edge cases) collapses into one place instead of drifting independently in 3 files.
Changes
resolve_relative_index(n: f64, len: usize) -> usizetosrc/interpreter/helpers.rs, a pure function with no interpreter/JS dependency, directly unit-testable in Rust.array.rs(slice,splice,toSpliced,fill,copyWithin),string.rs(slice), andtypedarray.rs(subarray,slice,copyWithin,fill) over to the shared helper.Tests
Built test-first (TDD): 8 unit tests in
src/interpreter/helpers.rspin the helper's boundary behavior directly against the Rust function — no JS parsing or interpreter execution involved — added one vertical slice at a time before the call-site sweep:<vs<=boundary that previously diverged between implementations (both landed on 0; now pinned to prevent regression)+Infinity/-Infinityclamp correctlyTest plan
cargo build --release— clean, no warningscargo test --bin jsse --release— 172/172 passing (including the 8 new unit tests)./scripts/lint.sh— clippy cleanuv run python scripts/run-custom-tests.py— 3/3 passinguv run python scripts/run-test262.py— not run: this sandboxed environment's network access is scoped to thepmatos/jsserepo only, so thetest262/specgit submodules (hosted attc39/*) could not be fetched (git submodule updatereturns 403). Since this is a pure refactor preserving the exact clamping semantics (verified by the unit tests above, including the boundary case where prior implementations disagreed), a full test262 run on this branch is recommended before merge to confirm no regressions inbuilt-ins/Array,built-ins/String, andbuilt-ins/TypedArray*.https://claude.ai/code/session_019oiTHXtesxw6uvcF31MU1p
Generated by Claude Code