mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 11:41:13 +08:00
feat: 补齐动态函数构造器族与原型对象
This commit is contained in:
@@ -930,22 +930,35 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
|
||||
// 槽在下方 P 槽换入后重指新原型),不再每轮新建对象。
|
||||
let agf_ctor_label = sf.intern("AsyncGeneratorFunctionCtor").0;
|
||||
let agf_reuse_key = oxide_kernel::builtin::FnWrapperKey::new(0, agf_ctor_label, 0, 0);
|
||||
// SAFETY: async_generator_function_stub 是 NativeFn 函数项。
|
||||
let agf_stub_ptr = unsafe { NativeFnPtr::from_raw(async_generator_function_stub as *const ()) };
|
||||
let (agf_ctor_ptr, agf_ctor_is_new) = match world.find_fn_wrapper(agf_reuse_key, agf_stub_ptr, 1) {
|
||||
// SAFETY: async_generator_function_constructor 是 NativeFn 函数项。
|
||||
let agf_ctor_fn_ptr = unsafe {
|
||||
NativeFnPtr::from_raw(
|
||||
oxide_builtins::function::async_generator_function_constructor::<Vm> as *const (),
|
||||
)
|
||||
};
|
||||
let (agf_ctor_ptr, agf_ctor_is_new) = match world.find_fn_wrapper(agf_reuse_key, agf_ctor_fn_ptr, 1) {
|
||||
Some(ptr) => (ptr, false),
|
||||
None => {
|
||||
let mut agf_ctor = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, fn_proto_val));
|
||||
agf_ctor.set_function(true);
|
||||
agf_ctor.set_native_arg_count(1);
|
||||
agf_ctor.set_native_fn(Some(agf_stub_ptr));
|
||||
// prototype/name 属性(构造器形状 [prototype, name])。
|
||||
let proto_si = sf.intern("prototype").0;
|
||||
let ctor_shape = sh.make_shape(EMPTY_SHAPE_ID, proto_si);
|
||||
agf_ctor.set_shape_id(ctor_shape);
|
||||
agf_ctor.set_native_fn(Some(agf_ctor_fn_ptr));
|
||||
// 构造器 tag:IsConstructor 判定与 new 表达式派发据此放行。
|
||||
agf_ctor.type_tag = JsObject::OBJ_TYPE_CONSTRUCTOR;
|
||||
// 自身属性序:length、name、prototype、@@toStringTag(CreateBuiltinFunction 序)。
|
||||
let length_si = sf.intern("length").0;
|
||||
let length_shape = sh.make_shape(EMPTY_SHAPE_ID, length_si);
|
||||
agf_ctor.set_shape_id(length_shape);
|
||||
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 proto_si = sf.intern("prototype").0;
|
||||
let proto_shape = sh.make_shape(agf_ctor.shape_id(), proto_si);
|
||||
agf_ctor.set_shape_id(proto_shape);
|
||||
let tag_key =
|
||||
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
|
||||
let tag_shape = sh.make_shape(agf_ctor.shape_id(), tag_key);
|
||||
agf_ctor.set_shape_id(tag_shape);
|
||||
let agf_ctor_ptr = Box::into_raw(agf_ctor);
|
||||
// 登记进 world 释放表(带复用键):session 收尾统一释放构造器本体与属性区。
|
||||
world.track_fn_wrapper(agf_ctor_ptr, agf_reuse_key);
|
||||
@@ -964,7 +977,7 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
|
||||
let proto2_shape = sh.make_shape(agf_proto.shape_id(), proto2_si);
|
||||
agf_proto.set_shape_id(proto2_shape);
|
||||
let ppos2 = agf_proto.push_prop(JsValue::from_js_object(vm.async_generator_proto.as_ptr() as *mut JsObject));
|
||||
agf_proto.set_data_meta(ppos2, PropAttributes::new(false, false, false));
|
||||
agf_proto.set_data_meta(ppos2, PropAttributes::new(false, false, true));
|
||||
// agf_proto[Symbol.toStringTag] = "AsyncGeneratorFunction"(数据属性,w/e/c = false/false/true)。
|
||||
let tag2_key =
|
||||
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG);
|
||||
@@ -974,7 +987,7 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
|
||||
agf_proto.set_data_meta(tag2_pos, PropAttributes::new(false, false, true));
|
||||
|
||||
// proto 本体只存在于 P 槽(Arc 副本,原 Box 随函数结束释放):装入 P 槽后再写
|
||||
// 构造器 prototype/name 属性(按模板序 prototype 在前),prototype 指向 P 槽实例,
|
||||
// 构造器 length/name/prototype/@@toStringTag 属性(按形状序),prototype 指向 P 槽实例,
|
||||
// 使其与动态异步生成器函数使用的 [[Prototype]] 同一对象。复用构造器槽位已填充,
|
||||
// prototype 原位改指新 P 原型(旧原型已随 P 换出释放)。
|
||||
Vm::swap_intrinsic_proto(&mut vm.async_generator_function_proto, *agf_proto);
|
||||
@@ -984,10 +997,15 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
|
||||
let proto_val = JsValue::from_js_object(vm.async_generator_function_proto.as_ptr() as *mut JsObject);
|
||||
let name_val = JsValue::perm_string(sf.string_ptr(sf.intern("AsyncGeneratorFunction").0));
|
||||
if agf_ctor_is_new {
|
||||
let ppos = ctor_mut.push_prop(proto_val);
|
||||
ctor_mut.set_data_meta(ppos, PropAttributes::new(false, false, false));
|
||||
let lpos = ctor_mut.push_prop(JsValue::int(1));
|
||||
ctor_mut.set_data_meta(lpos, PropAttributes::new(false, false, true));
|
||||
let npos = ctor_mut.push_prop(name_val);
|
||||
ctor_mut.set_data_meta(npos, PropAttributes::new(false, false, true));
|
||||
let ppos = ctor_mut.push_prop(proto_val);
|
||||
ctor_mut.set_data_meta(ppos, PropAttributes::new(false, false, false));
|
||||
let tag_val = JsValue::perm_string(sf.string_ptr(sf.intern("Function").0));
|
||||
let tpos = ctor_mut.push_prop(tag_val);
|
||||
ctor_mut.set_data_meta(tpos, PropAttributes::new(false, false, true));
|
||||
} else {
|
||||
let si_prototype = sf.intern("prototype").0;
|
||||
if let Some(pos) = sh.lookup_position(ctor_mut.shape_id(), si_prototype) {
|
||||
@@ -999,14 +1017,25 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `%AsyncGeneratorFunction%` 占位:动态异步生成器函数创建未实现,调用抛错。
|
||||
fn async_generator_function_stub(vm: &mut Vm, _args: &[u8]) -> NativeResult {
|
||||
NativeResult::Err(oxide_builtins::error::create_type_error(
|
||||
vm,
|
||||
"AsyncGeneratorFunction constructor is not supported",
|
||||
))
|
||||
// 绑定 global:AsyncGeneratorFunction 槽已存在则原位更新(full_reset 未重建
|
||||
// global 时旧槽指向已弃 ctor),不存在则开新槽。
|
||||
let global_ptr = vm.session.global_object().as_ptr() as *mut JsObject;
|
||||
// SAFETY: global 由 session 持有存活整个 session;本函数内只改其 shape/属性区,
|
||||
// 期间无 reset 或对象搬移。
|
||||
let global = unsafe { &mut *global_ptr };
|
||||
let si = sf.intern("AsyncGeneratorFunction").0;
|
||||
let ctor_val = JsValue::from_js_object(agf_ctor_ptr);
|
||||
if let Some(pos) = sh.lookup_position(global.shape_id(), si) {
|
||||
global.set_prop_at(pos, ctor_val);
|
||||
} else {
|
||||
let shape = sh.make_shape(global.shape_id(), si);
|
||||
global.set_shape_id(shape);
|
||||
let pos = global.push_prop(ctor_val);
|
||||
// global 数据属性:writable:true、enumerable:false、configurable:true。
|
||||
global.set_data_meta(pos, PropAttributes::new(true, false, true));
|
||||
global.bump_generation();
|
||||
}
|
||||
}
|
||||
|
||||
// ── session GC 支撑:状态快照中的 JsValues 作为异步生成器对象边追踪 ──
|
||||
|
||||
Reference in New Issue
Block a user