Skip to content

fix(runtime): finish string coercion operand rooting - #7950

Merged
proggeramlug merged 2 commits into
mainfrom
fix/6949-string-coerce-rooting-tail
Aug 12, 2026
Merged

fix(runtime): finish string coercion operand rooting#7950
proggeramlug merged 2 commits into
mainfrom
fix/6949-string-coerce-rooting-tail

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Finish the four primary operand-rooting sites left open by #6949 after #7811 and #7815:

  • root the String split receiver and separator across limit/separator coercion, and refresh the source around result allocations
  • root the RegExp.prototype.compile receiver and arguments across source/flags coercion and string allocation
  • root the rebound RegExp pattern (and pending flags value) across the second constructor coercion
  • root the typed-array view and user-patched toLocaleString closure across prototype lookup and every loop allocation/callback

The separate raw-JSValues-in-Rust-containers shape is now tracked by #7949, so it remains visible without keeping this coercion-specific issue open.

No version bump is included.

Validation

  • cargo check -p perry-runtime --lib
  • cargo test -p perry-runtime --lib string::tests:: (33 passed)
  • cargo test -p perry-runtime --lib regex::tests:: (27 passed)
  • full cargo test -p perry-runtime --lib: 2,152 passed; the two existing Windows-only failures remained (global_sink_isolation::every_covered_clear_helper_is_still_called_by_the_guards, path::value_args::tests::both_operands_survive_the_materialisation_window)
  • scripts/check_file_size.sh
  • no added bare get_raw_{mut,const}_ptr reads

Closes #6949

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of string splitting, regular expression handling, and typed-array toLocaleString() operations during memory cleanup.
    • Prevented potential data corruption or crashes when values are converted or objects are relocated internally.
    • Preserved existing validation, error behavior, and output while improving runtime stability.
  • Documentation

    • Added a changelog entry documenting these runtime reliability improvements.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The runtime now roots receivers and operands during ToString coercions, allocations, callbacks, and RegExp updates. String splitting, RegExp construction and compilation, and patched typed-array toLocaleString paths refresh pointers after possible garbage collection.

Changes

GC-safe runtime operations

Layer / File(s) Summary
RegExp rooting and coercion
crates/perry-runtime/src/object/class_registry/construct.rs, crates/perry-runtime/src/regex/compile.rs
RegExp construction and compilation root receivers, patterns, and flags across coercion and allocation. RegExp properties and lastIndex updates use refreshed handles.
Typed-array locale conversion
crates/perry-runtime/src/object/native_call_method/typed_array.rs
toLocaleString roots the typed-array receiver and patched callback while reading elements, invoking the callback, and coercing results.
String split allocation safety
crates/perry-runtime/src/string/split.rs, changelog.d/7950-string-coerce-rooting-tail.md
String splitting roots source, separator, and result arrays across delimiter, limit, regex, substring, and result allocations. The changelog records the rooting audit.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • PerryTS/perry#6695: Previously modified RegExp compilation semantics in the same function.
  • PerryTS/perry#6941: Applies similar runtime rooting and relocated-pointer refreshes to other coercion paths.
  • PerryTS/perry#7240: Extends related GC-rooting fixes across RegExp, string splitting, and typed-array coercion paths.

Suggested reviewers: thehypnoo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary runtime change: completing string coercion operand rooting.
Description check ✅ Passed The description covers the rooting changes, linked issue, validation results, known failures, and version policy; it is sufficiently complete.
Linked Issues check ✅ Passed The changes implement the four stated operand-rooting objectives for split, RegExp compile and construction, and typed-array toLocaleString in [#6949].
Out of Scope Changes check ✅ Passed The runtime changes and changelog entry directly support the operand-rooting objectives, with no unrelated code changes identified.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/6949-string-coerce-rooting-tail

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
crates/perry-runtime/src/string/split.rs (1)

483-496: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider invalidating the stale str_data and s bindings after the array allocation.

str_data borrows the source payload from Line 369. Line 493 allocates the result array, which can move the source. After Line 495 both str_data and the raw s parameter name from-space, yet both remain in scope for the rest of the function. The current code is correct because the loop reads only s_now from s_handle and part_ranges holds offsets. The risk is a later edit that reads str_data again inside the loop; that is the #5062 dangling-source class this file has hit before.

Shadowing the stale bindings makes the invalidation explicit at compile time.

♻️ Proposed guard against a future stale read
     let n = part_ranges.len();
 
     let (arr, _) = s_handle.across_const::<StringHeader, _>(|| {
         crate::array::js_array_alloc_pointer_elements(n as u32)
     });
     let arr_handle = scope.root_raw_mut_ptr(arr);
+    // `str_data` and `s` name pre-allocation addresses from here on. Every
+    // later read must come from `s_handle`.
+    #[allow(unused_variables)]
+    let (str_data, s) = ((), ());
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/perry-runtime/src/string/split.rs` around lines 483 - 496, After the
result array allocation in the split implementation, explicitly invalidate or
shadow the stale str_data and raw s bindings before the loop. Preserve the
existing offset-based part_ranges and s_handle/s_now reads, while making any
later use of the pre-allocation source bindings fail at compile time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/perry-runtime/src/string/split.rs`:
- Around line 483-496: After the result array allocation in the split
implementation, explicitly invalidate or shadow the stale str_data and raw s
bindings before the loop. Preserve the existing offset-based part_ranges and
s_handle/s_now reads, while making any later use of the pre-allocation source
bindings fail at compile time.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7867d243-be3b-4e50-893a-c31989f76835

📥 Commits

Reviewing files that changed from the base of the PR and between 2dc1874 and fb5f31f.

📒 Files selected for processing (5)
  • changelog.d/7950-string-coerce-rooting-tail.md
  • crates/perry-runtime/src/object/class_registry/construct.rs
  • crates/perry-runtime/src/object/native_call_method/typed_array.rs
  • crates/perry-runtime/src/regex/compile.rs
  • crates/perry-runtime/src/string/split.rs

@proggeramlug
proggeramlug merged commit 388b2ad into main Aug 12, 2026
1 of 19 checks passed
@proggeramlug
proggeramlug deleted the fix/6949-string-coerce-rooting-tail branch August 12, 2026 11:22
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.

runtime: a fourth unrooted-operand family — js_string_coerce as a plain ToString argument coercion (string built-ins, constructors)

1 participant