mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 11:11:11 +08:00
fix: 不可扩展对象设置原型返回失败
This commit is contained in:
@@ -1256,11 +1256,12 @@ pub fn object_get_prototype_of<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResu
|
||||
/// - `obj` 为 null/undefined 抛 TypeError(RequireObjectCoercible);原始值原样返回,
|
||||
/// 不装箱。
|
||||
/// - `proto` 既非对象也非 null 时抛 TypeError。
|
||||
/// - 目标不可设置(原型环)时抛 TypeError;普通对象恒可设置,与 Reflect 版
|
||||
/// 按布尔返回的语义不同。
|
||||
/// - 目标不可设置(原型环,或不可扩展且新旧原型不同)时抛 TypeError;与 Reflect
|
||||
/// 版按布尔返回的语义不同。
|
||||
///
|
||||
/// # 副作用
|
||||
/// - 目标为对象时改写其 proto 槽并递增 generation。
|
||||
/// - 目标为对象且设置成功时改写其 proto 槽并递增 generation;新旧原型相同
|
||||
/// (SameValue)时按规范直接成功。
|
||||
pub fn object_set_prototype_of<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let target_val = args.get(1).map(|reg| vm.reg(*reg)).unwrap_or_else(JsValue::undefined);
|
||||
if target_val.is_null() || target_val.is_undefined() {
|
||||
@@ -1280,7 +1281,16 @@ pub fn object_set_prototype_of<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResu
|
||||
return NativeResult::Ok(target_val);
|
||||
}
|
||||
let target_ptr = target_val.as_js_object_ptr();
|
||||
if unsafe { &mut *target_ptr }.set_proto(proto).is_err() {
|
||||
let target = unsafe { &mut *target_ptr };
|
||||
// OrdinarySetPrototypeOf 步 2-4:新旧原型 SameValue 时直接成功,可扩展标志
|
||||
// 不参与判断;不可扩展且新旧不同才失败。set_proto 是裸写槽操作,不含该判定。
|
||||
if !target.is_extensible() && target.proto() != proto {
|
||||
return NativeResult::Err(crate::error::create_type_error(
|
||||
vm,
|
||||
"Object.setPrototypeOf: cannot set prototype of non-extensible object",
|
||||
));
|
||||
}
|
||||
if target.set_proto(proto).is_err() {
|
||||
return NativeResult::Err(crate::error::create_type_error(vm, "Object.setPrototypeOf: cannot set prototype"));
|
||||
}
|
||||
NativeResult::Ok(target_val)
|
||||
|
||||
Reference in New Issue
Block a user