mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-27 04:01:11 +08:00
fix: 同键 wrapper 函数指针变更时清旧槽复用键
This commit is contained in:
@@ -234,11 +234,34 @@ impl BuiltinWorld {
|
|||||||
/// 登记一个可复用 native 函数 wrapper(带复用键),随登记表在 session
|
/// 登记一个可复用 native 函数 wrapper(带复用键),随登记表在 session
|
||||||
/// 收尾统一释放。
|
/// 收尾统一释放。
|
||||||
///
|
///
|
||||||
|
/// # 边界与前提
|
||||||
|
/// 登记表已有同键旧槽且其 native 函数指针与新 wrapper 不同时,视为
|
||||||
|
/// wrapper 函数指针变更(如构造器由占位实现换为真身):旧 wrapper
|
||||||
|
/// 不可再复用,清其复用键。
|
||||||
|
///
|
||||||
|
/// # 副作用
|
||||||
|
/// - 登记表追加新条目。
|
||||||
|
/// - 同键旧槽函数指针不同时,清空其复用键。
|
||||||
|
///
|
||||||
/// # 注意事项
|
/// # 注意事项
|
||||||
/// 同键重复登记意味着复用键设计缺陷(同家族槽位对应两个不同 wrapper
|
/// 同键且同函数指针的重复登记意味着复用键设计缺陷(同家族槽位对应
|
||||||
/// 对象)——debug 断言立即失败。
|
/// 两个不同 wrapper 对象)——debug 断言立即失败。
|
||||||
#[expect(clippy::not_unsafe_ptr_arg_deref)] // 指针由绑定层保证存活,此函数仅读世代、不转移所有权
|
#[expect(clippy::not_unsafe_ptr_arg_deref)] // 指针由绑定层保证存活,此函数仅读世代、不转移所有权
|
||||||
pub fn track_fn_wrapper(&self, obj_ptr: *mut JsObject, key: FnWrapperKey) {
|
pub fn track_fn_wrapper(&self, obj_ptr: *mut JsObject, key: FnWrapperKey) {
|
||||||
|
// SAFETY: obj_ptr 是刚装好 length/name 的存活 wrapper,读取其 native 函数指针。
|
||||||
|
let new_fn_ptr = unsafe { (*obj_ptr).native_fn().map(|p| p.0) };
|
||||||
|
// 同键旧槽函数指针不同:wrapper 函数指针已变更,旧 wrapper 不再
|
||||||
|
// 参与复用,清键后本体滞留至 session 收尾统一释放(与失效语义一致)。
|
||||||
|
for slot in self.leaked_objects.borrow_mut().iter_mut() {
|
||||||
|
if slot.key != Some(key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// SAFETY: 登记表指针 session 存活期内有效。
|
||||||
|
let old_fn_ptr = unsafe { (*slot.ptr).native_fn().map(|p| p.0) };
|
||||||
|
if old_fn_ptr != new_fn_ptr {
|
||||||
|
slot.key = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
!self.leaked_objects.borrow().iter().any(|s| s.key == Some(key)),
|
!self.leaked_objects.borrow().iter().any(|s| s.key == Some(key)),
|
||||||
"同键 native 函数 wrapper 重复登记"
|
"同键 native 函数 wrapper 重复登记"
|
||||||
|
|||||||
Reference in New Issue
Block a user