fix: sloppy 模式属性赋值静默 no-op——写失败按写方严格模式分派,内置写路径一律按严格

This commit is contained in:
2026-09-09 17:48:33 +08:00
parent 64f582d34b
commit c8bcff83f6
18 changed files with 529 additions and 89 deletions
+4 -4
View File
@@ -619,7 +619,7 @@ fn array_from_set_length<H: VmHost>(vm: &mut H, a: *mut JsObject, is_array: bool
let length_key = vm.new_string("length");
let length_si = vm.property_key_si(length_key);
let a_val = JsValue::from_js_object(a);
match vm.ordinary_set(a_obj, length_si, JsValue::int(len as i32), a_val) {
match vm.ordinary_set(a_obj, length_si, JsValue::int(len as i32), a_val, true) {
Ok(()) => Ok(()),
Err(err) => Err(from_engine_error(vm, &err)),
}
@@ -731,7 +731,7 @@ pub fn array_slice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let a_val = JsValue::from_js_object(a_ptr);
let length_key = vm.new_string("length");
let length_si = vm.property_key_si(length_key);
if let Err(err) = vm.ordinary_set(unsafe { &mut *a_ptr }, length_si, js_array_index(out_idx), a_val) {
if let Err(err) = vm.ordinary_set(unsafe { &mut *a_ptr }, length_si, js_array_index(out_idx), a_val, true) {
return NativeResult::Err(from_engine_error(vm, &err));
}
NativeResult::Ok(JsValue::from_js_object(a_ptr))
@@ -1843,7 +1843,7 @@ pub fn array_iterator_next<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
}
_ => element,
};
if let Err(msg) = vm.ordinary_set(iter, index_si, JsValue::int(index + 1), this_val) {
if let Err(msg) = vm.ordinary_set(iter, index_si, JsValue::int(index + 1), this_val, true) {
return NativeResult::Err(crate::error::create_from_text(vm, &msg));
}
return NativeResult::Ok(crate::iterator::make_iter_result(vm, value, false));
@@ -1876,7 +1876,7 @@ pub fn array_iterator_next<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
}
_ => element,
};
if let Err(msg) = vm.ordinary_set(iter, index_si, JsValue::int(index + 1), this_val) {
if let Err(msg) = vm.ordinary_set(iter, index_si, JsValue::int(index + 1), this_val, true) {
return NativeResult::Err(crate::error::create_from_text(vm, &msg));
}
NativeResult::Ok(crate::iterator::make_iter_result(vm, value, false))
+1 -1
View File
@@ -114,7 +114,7 @@ fn iterator_setter_ignore_proto_props<H: VmHost>(vm: &mut H, args: &[u8], key: u
Err(err) => NativeResult::Err(crate::error::create_type_error(vm, &err)),
}
} else {
match vm.ordinary_set(this_obj, key, val, this_val) {
match vm.ordinary_set(this_obj, key, val, this_val, true) {
Ok(()) => NativeResult::Ok(JsValue::undefined()),
Err(err) => NativeResult::Err(crate::error::create_type_error(vm, &err)),
}
+3 -3
View File
@@ -496,7 +496,7 @@ pub fn object_assign<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
for (si, val) in all_assignments {
let promoted = vm.promote_if_needed_for_write_ptr(target_ptr, val);
// Set(to, key, value, true):receiver 为目标对象(目标同名 setter 的 this 指向 target)。
if let Err(err) = vm.ordinary_set(target, si, promoted, target_val) {
if let Err(err) = vm.ordinary_set(target, si, promoted, target_val, true) {
return NativeResult::Err(crate::error::create_type_error(vm, &err));
}
}
@@ -1089,7 +1089,7 @@ pub fn object_from_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
// ToPropertyKey 语义建键:int/规范数字串/symbol 统一映射,避免数字键分裂。
let si = vm.property_key_si(key_val);
let promoted = vm.promote_if_needed_for_write_ptr(obj, value_val);
let _ = vm.ordinary_set(unsafe { &mut *obj }, si, promoted, target_val);
let _ = vm.ordinary_set(unsafe { &mut *obj }, si, promoted, target_val, true);
}
NativeResult::Ok(target_val)
}
@@ -1483,7 +1483,7 @@ pub fn object_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let new_arr_val = JsValue::from_js_object(arr);
let result_ref_mut = unsafe { &mut *result };
let promoted = vm.promote_if_needed_for_write_ptr(result, new_arr_val);
let _ = vm.ordinary_set(result_ref_mut, key_si, promoted, result_val);
let _ = vm.ordinary_set(result_ref_mut, key_si, promoted, result_val, true);
new_arr_val
};
// push element 到分组数组(写入前 promote,与 Array.prototype.push 同款)。
+1 -1
View File
@@ -222,7 +222,7 @@ pub fn reflect_set<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if !target.is_extensible() && vm.get_own_property_slot(target, key_si).is_none() {
return NativeResult::Ok(JsValue::bool(false));
}
NativeResult::Ok(JsValue::bool(vm.ordinary_set(target, key_si, value, receiver).is_ok()))
NativeResult::Ok(JsValue::bool(vm.ordinary_set(target, key_si, value, receiver, true).is_ok()))
}
/// `Reflect.setPrototypeOf(target, proto)`:设置 prototype(对象或 null)。