feat: Object keys 系列合并数组元素区,assign 按规范过滤枚举/触发 getter
walk_own_keys 返回值语义改为绝对存储索引:数组对象先枚举元素区 (跳过 hole),命名属性偏移到元素区之后;shape 槽位计数含 symbol 键 与物理存储对齐(修 symbol 键错位读值)。delete_own_property / REST / SPREAD 四连锁点同步去偏移,REST/SPREAD 删除独立元素区循环 (由 walk_own_keys 统一覆盖,防重复键)。 Object.assign 增补:源只取可枚举自身属性;取值改 ordinary_get (accessor 触发 getter,receiver=源);提交写 receiver 修正为 target (目标同名 setter 的 this 指向 target)。
This commit is contained in:
@@ -766,36 +766,12 @@ impl Vm {
|
||||
}
|
||||
}
|
||||
|
||||
// 数组元素区:整数下标可枚举元素(hole 跳过),排除 pattern 已绑定的键。
|
||||
if src_obj.is_array() {
|
||||
for i in 0..src_obj.array_prop_count {
|
||||
if src_obj.prop_meta_at(i).is_some_and(|m| m.is_hole()) {
|
||||
continue;
|
||||
}
|
||||
let enumerable = src_obj
|
||||
.prop_meta_at(i)
|
||||
.map(|m| m.attributes.enumerable())
|
||||
.unwrap_or(PropAttributes::DEFAULT_DATA.enumerable());
|
||||
if enumerable {
|
||||
let si = make_int_key(i);
|
||||
if excluded.contains(&si) {
|
||||
continue;
|
||||
}
|
||||
let val = match self.ordinary_get(src_obj, si, src) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return self.raise_call_error(&e).map(|_| ()),
|
||||
};
|
||||
assignments.push((si, val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 命名属性:shape 链(walk_own_keys 规范顺序),仅可枚举,跳过 pattern 已绑定的键。
|
||||
// 自身属性:walk_own_keys 已合并数组元素区(hole 跳过)并返回绝对存储索引,
|
||||
// 仅可枚举,跳过 pattern 已绑定的键。
|
||||
let keys = oxide_builtins::object::walk_own_keys(self, src_obj);
|
||||
for (si, pos) in keys {
|
||||
let store = if src_obj.is_array() { src_obj.array_prop_count + pos } else { pos };
|
||||
let enumerable = src_obj
|
||||
.prop_meta_at(store)
|
||||
.prop_meta_at(pos)
|
||||
.map(|m| m.attributes.enumerable())
|
||||
.unwrap_or(PropAttributes::DEFAULT_DATA.enumerable());
|
||||
if !enumerable {
|
||||
@@ -882,30 +858,12 @@ impl Vm {
|
||||
// 再统一写目标,避免提交写与取值互相交错。
|
||||
let mut assignments: Vec<(u32, JsValue)> = Vec::new();
|
||||
|
||||
// 数组元素区:整数下标可枚举元素(hole 跳过)。
|
||||
if src_obj.is_array() {
|
||||
for i in 0..src_obj.array_prop_count {
|
||||
if src_obj.prop_meta_at(i).is_some_and(|m| m.is_hole()) {
|
||||
continue;
|
||||
}
|
||||
let enumerable = src_obj
|
||||
.prop_meta_at(i)
|
||||
.map(|m| m.attributes.enumerable())
|
||||
.unwrap_or(PropAttributes::DEFAULT_DATA.enumerable());
|
||||
if enumerable {
|
||||
let si = make_int_key(i);
|
||||
let val = self.ordinary_get(src_obj, si, src)?;
|
||||
assignments.push((si, val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 命名属性:shape 链(walk_own_keys 规范顺序),仅可枚举。
|
||||
// 自身属性:walk_own_keys 已合并数组元素区(hole 跳过)并返回绝对存储索引,
|
||||
// 仅可枚举;取值经 ordinary_get 触发访问器 getter。
|
||||
let keys = oxide_builtins::object::walk_own_keys(self, src_obj);
|
||||
for (si, pos) in keys {
|
||||
let store = if src_obj.is_array() { src_obj.array_prop_count + pos } else { pos };
|
||||
let enumerable = src_obj
|
||||
.prop_meta_at(store)
|
||||
.prop_meta_at(pos)
|
||||
.map(|m| m.attributes.enumerable())
|
||||
.unwrap_or(PropAttributes::DEFAULT_DATA.enumerable());
|
||||
if !enumerable {
|
||||
|
||||
Reference in New Issue
Block a user