fix: intrinsic ctor prototype 属性指向 P 槽唯一实例——消除 Box 释放悬垂与实例 [[Prototype]] identity 分裂

This commit is contained in:
2026-09-11 02:02:41 +00:00
parent 81f05b49a2
commit a5258f2739
3 changed files with 37 additions and 13 deletions
+11 -3
View File
@@ -420,13 +420,12 @@ pub(crate) fn init_async_intrinsics(vm: &mut Vm) {
let proto_si = sf.intern("prototype").0;
let ctor_shape2 = sh.make_shape(af_ctor.shape_id(), proto_si);
af_ctor.set_shape_id(ctor_shape2);
let ppos = af_ctor.push_prop(JsValue::from_js_object(af_proto.as_mut() as *mut JsObject));
af_ctor.set_data_meta(ppos, PropAttributes::new(false, false, false));
// af_proto.constructor = %AsyncFunction%(构造器对象泄漏持有,与 builtin 方法 wrapper 同生命周期)。
let ctor_si = sf.intern("constructor").0;
let pshape = sh.make_shape(af_proto.shape_id(), ctor_si);
af_proto.set_shape_id(pshape);
let cpos = af_proto.push_prop(JsValue::from_js_object(Box::into_raw(af_ctor)));
let af_ctor_ptr = Box::into_raw(af_ctor);
let cpos = af_proto.push_prop(JsValue::from_js_object(af_ctor_ptr));
af_proto.set_data_meta(cpos, PropAttributes::new(false, false, true));
// af_proto[Symbol.toStringTag] = "AsyncFunction"(数据属性,w/e/c = false/false/true)。
let tag_si = sf.intern("@@toStringTag").0;
@@ -435,7 +434,16 @@ pub(crate) fn init_async_intrinsics(vm: &mut Vm) {
let tag_pos = af_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncFunction").0)));
af_proto.set_data_meta(tag_pos, PropAttributes::new(false, false, true));
// proto 本体只存在于 P 槽(Arc 副本,原 Box 随函数结束释放):装入 P 槽后再把
// 构造器 prototype 属性指向 P 槽实例,使其与动态异步函数使用的 [[Prototype]]
// 同一对象,保证 `AsyncFunction.prototype === (async () => {}).__proto__`。
vm.async_function_proto = P::new(*af_proto);
// SAFETY: af_ctor_ptr 为 Box 原分配(泄漏持有、生命周期覆盖 session),对象已建满、本 Vm 独占。
unsafe {
let ctor_mut = &mut *af_ctor_ptr;
let ppos = ctor_mut.push_prop(JsValue::from_js_object(vm.async_function_proto.as_mut_ptr()));
ctor_mut.set_data_meta(ppos, PropAttributes::new(false, false, false));
}
}
/// `%AsyncFunction%` 占位:动态异步函数创建未实现,调用抛错。
+13 -5
View File
@@ -778,18 +778,15 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
let proto_si = sf.intern("prototype").0;
let ctor_shape = sh.make_shape(agf_ctor.shape_id(), proto_si);
agf_ctor.set_shape_id(ctor_shape);
let ppos = agf_ctor.push_prop(JsValue::from_js_object(agf_proto.as_mut() as *mut JsObject));
agf_ctor.set_data_meta(ppos, PropAttributes::new(false, false, false));
let name_si = sf.intern("name").0;
let name_shape = sh.make_shape(agf_ctor.shape_id(), name_si);
agf_ctor.set_shape_id(name_shape);
let npos = agf_ctor.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncGeneratorFunction").0)));
agf_ctor.set_data_meta(npos, PropAttributes::new(false, false, true));
// agf_proto.constructor = %AsyncGeneratorFunction%(构造器对象泄漏持有,与 builtin 方法 wrapper 同生命周期)。
let ctor_si = sf.intern("constructor").0;
let ctor2_shape = sh.make_shape(agf_proto.shape_id(), ctor_si);
agf_proto.set_shape_id(ctor2_shape);
let cpos = agf_proto.push_prop(JsValue::from_js_object(Box::into_raw(agf_ctor)));
let agf_ctor_ptr = Box::into_raw(agf_ctor);
let cpos = agf_proto.push_prop(JsValue::from_js_object(agf_ctor_ptr));
agf_proto.set_data_meta(cpos, PropAttributes::new(false, false, true));
// agf_proto.prototype = %AsyncGeneratorPrototype%。
let proto2_si = sf.intern("prototype").0;
@@ -804,7 +801,18 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
let tag2_pos = agf_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncGeneratorFunction").0)));
agf_proto.set_data_meta(tag2_pos, PropAttributes::new(false, false, true));
// proto 本体只存在于 P 槽(Arc 副本,原 Box 随函数结束释放):装入 P 槽后再写
// 构造器 prototype/name 属性(按模板序 prototype 在前),prototype 指向 P 槽实例,
// 使其与动态异步生成器函数使用的 [[Prototype]] 同一对象。
vm.async_generator_function_proto = P::new(*agf_proto);
// SAFETY: agf_ctor_ptr 为 Box 原分配(泄漏持有、生命周期覆盖 session),对象已建满、本 Vm 独占。
unsafe {
let ctor_mut = &mut *agf_ctor_ptr;
let ppos = ctor_mut.push_prop(JsValue::from_js_object(vm.async_generator_function_proto.as_mut_ptr()));
ctor_mut.set_data_meta(ppos, PropAttributes::new(false, false, false));
let npos = ctor_mut.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("AsyncGeneratorFunction").0)));
ctor_mut.set_data_meta(npos, PropAttributes::new(false, false, true));
}
}
/// `%AsyncGeneratorFunction%` 占位:动态异步生成器函数创建未实现,调用抛错。
+13 -5
View File
@@ -773,18 +773,15 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) {
let proto_si = sf.intern("prototype").0;
let ctor_shape = sh.make_shape(gf_ctor.shape_id(), proto_si);
gf_ctor.set_shape_id(ctor_shape);
let ppos = gf_ctor.push_prop(JsValue::from_js_object(gf_proto.as_mut() as *mut JsObject));
gf_ctor.set_data_meta(ppos, oxide_types::object::PropAttributes::new(false, false, false));
let name_si = sf.intern("name").0;
let name_shape = sh.make_shape(gf_ctor.shape_id(), name_si);
gf_ctor.set_shape_id(name_shape);
let npos = gf_ctor.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("GeneratorFunction").0)));
gf_ctor.set_data_meta(npos, oxide_types::object::PropAttributes::new(false, false, true));
// gf_proto.constructor = gf_ctor(构造器对象泄漏持有,与 builtin 方法 wrapper 同生命周期)。
let ctor_si = sf.intern("constructor").0;
let ctor2_shape = sh.make_shape(gf_proto.shape_id(), ctor_si);
gf_proto.set_shape_id(ctor2_shape);
let cpos = gf_proto.push_prop(JsValue::from_js_object(Box::into_raw(gf_ctor)));
let gf_ctor_ptr = Box::into_raw(gf_ctor);
let cpos = gf_proto.push_prop(JsValue::from_js_object(gf_ctor_ptr));
gf_proto.set_data_meta(cpos, oxide_types::object::PropAttributes::new(false, false, true));
// gf_proto.prototype = %GeneratorPrototype%(默认原型,default-proto 测试读取)。
let proto2_si = sf.intern("prototype").0;
@@ -799,7 +796,18 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) {
let tag2_pos = gf_proto.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("GeneratorFunction").0)));
gf_proto.set_data_meta(tag2_pos, oxide_types::object::PropAttributes::new(false, false, true));
// proto 本体只存在于 P 槽(Arc 副本,原 Box 随函数结束释放):装入 P 槽后再写
// 构造器 prototype/name 属性(按模板序 prototype 在前),prototype 指向 P 槽实例,
// 使其与动态生成器函数使用的 [[Prototype]] 同一对象。
vm.generator_function_proto = P::new(*gf_proto);
// SAFETY: gf_ctor_ptr 为 Box 原分配(泄漏持有、生命周期覆盖 session),对象已建满、本 Vm 独占。
unsafe {
let ctor_mut = &mut *gf_ctor_ptr;
let ppos = ctor_mut.push_prop(JsValue::from_js_object(vm.generator_function_proto.as_mut_ptr()));
ctor_mut.set_data_meta(ppos, oxide_types::object::PropAttributes::new(false, false, false));
let npos = ctor_mut.push_prop(JsValue::perm_string(sf.string_ptr(sf.intern("GeneratorFunction").0)));
ctor_mut.set_data_meta(npos, oxide_types::object::PropAttributes::new(false, false, true));
}
}
/// `%GeneratorFunction%` 占位:动态生成器函数创建未实现,调用抛错。