From a5258f2739231c84b8bd65da0ba10ffa107e58cd Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 11 Sep 2026 02:02:41 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20intrinsic=20ctor=20prototype=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=8C=87=E5=90=91=20P=20=E6=A7=BD=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E2=80=94=E2=80=94=E6=B6=88=E9=99=A4=20Box=20?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E6=82=AC=E5=9E=82=E4=B8=8E=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=20[[Prototype]]=20identity=20=E5=88=86=E8=A3=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/async_func.rs | 14 +++++++++++--- crates/oxide_vm/src/async_generator.rs | 18 +++++++++++++----- crates/oxide_vm/src/generator.rs | 18 +++++++++++++----- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/crates/oxide_vm/src/async_func.rs b/crates/oxide_vm/src/async_func.rs index f2b1b2ba..968fd4c8 100644 --- a/crates/oxide_vm/src/async_func.rs +++ b/crates/oxide_vm/src/async_func.rs @@ -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%` 占位:动态异步函数创建未实现,调用抛错。 diff --git a/crates/oxide_vm/src/async_generator.rs b/crates/oxide_vm/src/async_generator.rs index 67a777da..5fcad811 100644 --- a/crates/oxide_vm/src/async_generator.rs +++ b/crates/oxide_vm/src/async_generator.rs @@ -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%` 占位:动态异步生成器函数创建未实现,调用抛错。 diff --git a/crates/oxide_vm/src/generator.rs b/crates/oxide_vm/src/generator.rs index 304a23ef..87618b4a 100644 --- a/crates/oxide_vm/src/generator.rs +++ b/crates/oxide_vm/src/generator.rs @@ -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%` 占位:动态生成器函数创建未实现,调用抛错。