fix: native 构造器可构造性标志(OBJ_TYPE_CONSTRUCTOR)+ Reflect.construct/new 校验
This commit is contained in:
@@ -42,6 +42,11 @@ pub fn reflect_construct<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
if new_target_ptr.is_null() || !unsafe { &*new_target_ptr }.is_function() {
|
||||
return type_error(vm, "Reflect.construct newTarget is not a constructor");
|
||||
}
|
||||
// 不可构造:箭头函数、native 方法(非构造器,OBJ_TYPE_CONSTRUCTOR 标记的除外)。
|
||||
let nt = unsafe { &*new_target_ptr };
|
||||
if nt.is_arrow() || (nt.native_fn().is_some() && nt.type_tag != oxide_types::object::JsObject::OBJ_TYPE_CONSTRUCTOR) {
|
||||
return type_error(vm, "Reflect.construct newTarget is not a constructor");
|
||||
}
|
||||
|
||||
let proto_si = vm.kernel_core().perm_interner().intern("prototype").0;
|
||||
let proto_val = match vm.resolve_property(unsafe { &*new_target_ptr }, proto_si) {
|
||||
|
||||
@@ -357,6 +357,8 @@ impl JsObject {
|
||||
pub const OBJ_TYPE_DATA_VIEW: u8 = 7;
|
||||
/// TypedArray 对象类型标签。
|
||||
pub const OBJ_TYPE_TYPED_ARRAY: u8 = 8;
|
||||
/// native 构造器(Set/Array/Object 等,可 [[Construct]]);区别于不可构造的 native 方法。
|
||||
pub const OBJ_TYPE_CONSTRUCTOR: u8 = 9;
|
||||
/// `is_session_epoch` 字段中的 session 标记位。
|
||||
pub const SESSION_EPOCH_BIT: u8 = 0x01;
|
||||
/// `is_session_epoch` 字段中的 GC 标记位。
|
||||
|
||||
@@ -74,6 +74,7 @@ macro_rules! bind_constructor {
|
||||
let ptr: *const () = ($ctor_fn as fn(&mut $crate::vm::Vm, &[u8]) -> oxide_runtime_api::NativeResult) as *const ();
|
||||
ctor.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw(ptr) }));
|
||||
ctor.set_native_arg_count($nargs);
|
||||
ctor.type_tag = oxide_types::object::JsObject::OBJ_TYPE_CONSTRUCTOR;
|
||||
// 设置 constructor.length (Function.length = formal parameter count)
|
||||
let length_si = $core.perm_interner().intern("length").0;
|
||||
let length_shape = $core.shape_forge().make_shape(ctor.shape_id(), length_si);
|
||||
@@ -86,6 +87,7 @@ pub(crate) fn configure_native_constructor(ctor: &mut JsObject, native_fn: *cons
|
||||
// SAFETY: native_fn 始终是调用方转成 *const () 的合法 NativeFn 函数项指针。
|
||||
ctor.set_native_fn(Some(unsafe { NativeFnPtr::from_raw(native_fn) }));
|
||||
ctor.set_native_arg_count(arg_count);
|
||||
ctor.type_tag = JsObject::OBJ_TYPE_CONSTRUCTOR;
|
||||
}
|
||||
|
||||
fn configure_existing_ctor(ctor: &P<JsObject>, native_fn: *const (), arg_count: u8) {
|
||||
|
||||
@@ -35,6 +35,12 @@ impl Vm {
|
||||
.raise_type_error("arrow functions cannot be used as constructors")
|
||||
.map(|_| true);
|
||||
}
|
||||
// native 方法(非构造器)不可 new。
|
||||
if ctor_obj.native_fn().is_some() && ctor_obj.type_tag != oxide_types::object::JsObject::OBJ_TYPE_CONSTRUCTOR {
|
||||
return self
|
||||
.raise_type_error("object is not a constructor")
|
||||
.map(|_| true);
|
||||
}
|
||||
|
||||
let ext = self.bytecode[self.pc];
|
||||
self.pc += 1;
|
||||
|
||||
Reference in New Issue
Block a user