diff --git a/changelog.d/7458-clean-three-modules.md b/changelog.d/7458-clean-three-modules.md new file mode 100644 index 0000000000..c4147acdeb --- /dev/null +++ b/changelog.d/7458-clean-three-modules.md @@ -0,0 +1 @@ +- **Three runtime modules are now permanently free of raw-handle debt.** `array/from_concat.rs` (`js_array_grow`), `object/array_object_ops.rs` (`js_string_coerce`) and `symbol.rs` (`gc_malloc`) each had one bare read directly below an allocating call — the canonical shape — and now use `RuntimeHandle::across_{mut,const}`. First use of #7457's per-module ceilings, and rule 3 fired as designed: the gate stayed red until each cleaned module's line was deleted, so the cleanup cannot be undone. 110 → 107 modules, 1002 → 999 sites; those three now fall under rule 1 and are held at zero rather than being three below a drifting total. (#7458) diff --git a/crates/perry-runtime/src/array/from_concat.rs b/crates/perry-runtime/src/array/from_concat.rs index d936f6011d..d33f9dd720 100644 --- a/crates/perry-runtime/src/array/from_concat.rs +++ b/crates/perry-runtime/src/array/from_concat.rs @@ -1029,11 +1029,11 @@ unsafe fn try_append_spread_array_dense( // e.g. from `array_subclass_dense_snapshot`) and re-resolve both. let scope = crate::gc::RuntimeHandleScope::new(); let src_handle = scope.root_raw_const_ptr(src); - let grown = crate::array::js_array_grow(result, new_len); - ( - grown, - clean_arr_ptr(src_handle.get_raw_const_ptr::()), - ) + // `js_array_grow` allocates and can move `src`; `across_const` runs it + // and hands back the post-collection address (#7341). + let (grown, src_after) = src_handle + .across_const::(|| crate::array::js_array_grow(result, new_len)); + (grown, clean_arr_ptr(src_after)) } else { (result, src) }; diff --git a/crates/perry-runtime/src/object/array_object_ops.rs b/crates/perry-runtime/src/object/array_object_ops.rs index 20cf549141..bd383ff220 100644 --- a/crates/perry-runtime/src/object/array_object_ops.rs +++ b/crates/perry-runtime/src/object/array_object_ops.rs @@ -271,8 +271,11 @@ pub(crate) unsafe fn array_length_reflect_define( let scope = crate::gc::RuntimeHandleScope::new(); let obj_handle = scope.root_raw_mut_ptr(obj); let desc_handle = scope.root_nanbox_f64(descriptor_value); - let key_str = crate::builtins::js_string_coerce(key_value); - let obj = obj_handle.get_raw_mut_ptr::(); + // `js_string_coerce` allocates (and can run a user `toString`), so the + // receiver's address is only valid after it. `across_mut` is that pair as + // one combinator (#7341). + let (key_str, obj) = + obj_handle.across_mut::(|| crate::builtins::js_string_coerce(key_value)); let descriptor_value = desc_handle.get_nanbox_f64(); if key_str.is_null() { return None; diff --git a/crates/perry-runtime/src/symbol.rs b/crates/perry-runtime/src/symbol.rs index 51a1566ac8..51ba67ba76 100644 --- a/crates/perry-runtime/src/symbol.rs +++ b/crates/perry-runtime/src/symbol.rs @@ -393,11 +393,14 @@ pub(crate) unsafe fn alloc_symbol( // fix, tracked in #7341. let scope = crate::gc::RuntimeHandleScope::new(); let desc_root = scope.root_string_ptr(description); - let raw = crate::gc::gc_malloc( - std::mem::size_of::(), - crate::gc::GC_TYPE_STRING, - ); - let description = desc_root.get_raw_mut_ptr::(); + // `gc_malloc` can collect, so the description's address is only valid + // after it; `across_mut` binds the two together (#7341). + let (raw, description) = desc_root.across_mut::(|| { + crate::gc::gc_malloc( + std::mem::size_of::(), + crate::gc::GC_TYPE_STRING, + ) + }); let ptr = raw as *mut SymbolHeader; (*ptr).magic = SYMBOL_MAGIC; (*ptr).registered = if registered { 1 } else { 0 }; diff --git a/scripts/raw_handle_debt_baseline.txt b/scripts/raw_handle_debt_baseline.txt index 7d802a3e71..a6905f8ba4 100644 --- a/scripts/raw_handle_debt_baseline.txt +++ b/scripts/raw_handle_debt_baseline.txt @@ -1 +1 @@ -1002 +999 diff --git a/scripts/raw_handle_debt_files.txt b/scripts/raw_handle_debt_files.txt index 8d3b007721..b16a9e2f4c 100644 --- a/scripts/raw_handle_debt_files.txt +++ b/scripts/raw_handle_debt_files.txt @@ -23,7 +23,6 @@ # rule above covers 84% of the crate on day one. # # Format: -1 crates/perry-runtime/src/array/from_concat.rs 5 crates/perry-runtime/src/array/header.rs 6 crates/perry-runtime/src/array/indexing.rs 2 crates/perry-runtime/src/array/iter_methods.rs @@ -63,7 +62,6 @@ 4 crates/perry-runtime/src/node_submodules/mod.rs 4 crates/perry-runtime/src/node_submodules/test.rs 33 crates/perry-runtime/src/object/alloc.rs -1 crates/perry-runtime/src/object/array_object_ops.rs 2 crates/perry-runtime/src/object/bigint_dispatch.rs 5 crates/perry-runtime/src/object/class_registry/construct.rs 2 crates/perry-runtime/src/object/delete_rest.rs @@ -79,9 +77,9 @@ 1 crates/perry-runtime/src/object/native_call_method/object_proto.rs 4 crates/perry-runtime/src/object/native_call_method/primitive_methods.rs 10 crates/perry-runtime/src/object/native_call_method/string_methods.rs +4 crates/perry-runtime/src/object/native_module.rs 19 crates/perry-runtime/src/object/native_module/async_hooks_exports.rs 26 crates/perry-runtime/src/object/native_module/callable_exports.rs -4 crates/perry-runtime/src/object/native_module.rs 6 crates/perry-runtime/src/object/object_literal_ops.rs 3 crates/perry-runtime/src/object/object_ops/define_property.rs 3 crates/perry-runtime/src/object/object_ops/descriptor_helpers.rs @@ -100,22 +98,21 @@ 1 crates/perry-runtime/src/promise/native_async.rs 3 crates/perry-runtime/src/promise/rejection.rs 8 crates/perry-runtime/src/promise/then.rs -1 crates/perry-runtime/src/proxy/put_value.rs 8 crates/perry-runtime/src/proxy.rs +1 crates/perry-runtime/src/proxy/put_value.rs +9 crates/perry-runtime/src/regex.rs 17 crates/perry-runtime/src/regex/exec.rs 30 crates/perry-runtime/src/regex/exec_array.rs 14 crates/perry-runtime/src/regex/match_all.rs 24 crates/perry-runtime/src/regex/match_string.rs 7 crates/perry-runtime/src/regex/replace_expand.rs 3 crates/perry-runtime/src/regex/replace_fn.rs -9 crates/perry-runtime/src/regex.rs 41 crates/perry-runtime/src/set.rs 2 crates/perry-runtime/src/string/append.rs 7 crates/perry-runtime/src/string/concat.rs 1 crates/perry-runtime/src/string/mod.rs 10 crates/perry-runtime/src/string/split.rs 2 crates/perry-runtime/src/symbol/iterator.rs -1 crates/perry-runtime/src/symbol.rs 27 crates/perry-runtime/src/thread.rs 7 crates/perry-runtime/src/timer.rs 1 crates/perry-runtime/src/typed_feedback.rs