mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-26 19:51:11 +08:00
fix: 数组显式 undefined 命名槽存在性改按 shape 槽命中
This commit is contained in:
@@ -249,9 +249,10 @@ impl Vm {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 查找自身属性槽下标:数组 length 虚拟属性返回 `None`,元素区返回下标,
|
/// 查找自身属性槽下标:数组 length 虚拟属性返回 `None`,元素区返回下标
|
||||||
/// shape 槽按数组(元素区之后偏移)与普通对象(槽位即下标)各自定位;
|
/// (hole 视缺失),shape 槽命中即属性在场并返回存储下标(数组加元素区
|
||||||
/// 未命中的槽返回 `None`。
|
/// 偏移,普通对象槽位即下标);值可为显式 undefined,不参与存在性判定;
|
||||||
|
/// 未命中返回 `None`。
|
||||||
pub(crate) fn get_own_property_slot(&self, obj: &JsObject, prop_name_si: u32) -> Option<u32> {
|
pub(crate) fn get_own_property_slot(&self, obj: &JsObject, prop_name_si: u32) -> Option<u32> {
|
||||||
let length_si = self.length_si;
|
let length_si = self.length_si;
|
||||||
if obj.is_array() && prop_name_si == length_si {
|
if obj.is_array() && prop_name_si == length_si {
|
||||||
@@ -271,13 +272,9 @@ impl Vm {
|
|||||||
.and_then(|pos| {
|
.and_then(|pos| {
|
||||||
if obj.is_array() {
|
if obj.is_array() {
|
||||||
// 数组属性存储索引 = array_prop_count + shape 槽位(与元素区分)。
|
// 数组属性存储索引 = array_prop_count + shape 槽位(与元素区分)。
|
||||||
let idx = obj.array_prop_count as usize + pos as usize;
|
// shape 槽命中即属性在场:删除重建保证槽随属性移除,
|
||||||
let val = obj.get_prop_at(idx);
|
// 显式 undefined 值同样在场(规范存在性只看自身槽)。
|
||||||
if !val.is_undefined() || obj.prop_vec_len() > idx {
|
Some(obj.array_prop_count + pos)
|
||||||
Some(idx as u32)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let val = obj.get_prop_at(pos);
|
let val = obj.get_prop_at(pos);
|
||||||
if !val.is_undefined() || obj.prop_vec_len() > pos as usize {
|
if !val.is_undefined() || obj.prop_vec_len() > pos as usize {
|
||||||
|
|||||||
@@ -352,6 +352,35 @@ fn in_operator_ordinary_object_zero_drift() {
|
|||||||
assert!(result.as_bool());
|
assert!(result.as_bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn in_operator_array_explicit_undefined_named_prop_present() {
|
||||||
|
// 数组显式 undefined 自有命名属性判在场:HasProperty 按自身槽存在性
|
||||||
|
// 判定,值语义(显式 undefined)不参与;HasOwnProperty 同面。
|
||||||
|
let mut vm = Vm::new();
|
||||||
|
let result = eval(
|
||||||
|
&mut vm,
|
||||||
|
"var a = [1]; a.x = undefined; \
|
||||||
|
('x' in a) && a.hasOwnProperty('x') && Object.hasOwn(a, 'x') && \
|
||||||
|
!('y' in a) && !a.hasOwnProperty('y')",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert!(result.as_bool());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn in_operator_ordinary_explicit_undefined_named_prop_zero_drift() {
|
||||||
|
// 普通对象显式 undefined 命名槽零漂移守卫:`in`/hasOwnProperty 判在,
|
||||||
|
// 读值仍为 undefined。
|
||||||
|
let mut vm = Vm::new();
|
||||||
|
let result = eval(
|
||||||
|
&mut vm,
|
||||||
|
"var o = {}; o.x = undefined; \
|
||||||
|
('x' in o) && o.hasOwnProperty('x') && o.x === undefined",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert!(result.as_bool());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn typed_array_bigint_methods_receive_bigint_values() {
|
fn typed_array_bigint_methods_receive_bigint_values() {
|
||||||
let mut vm = Vm::new();
|
let mut vm = Vm::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user