fix: 修复数组长度与槽位索引截断问题

This commit is contained in:
爱特每羊队
2026-06-08 22:55:52 +08:00
parent 22cbccdf6c
commit e57e140bef
16 changed files with 242 additions and 159 deletions
+25 -18
View File
@@ -7,10 +7,10 @@ use crate::coercion;
use crate::native::NativeResult;
use crate::vm::Vm;
pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u8)> {
let mut keys: Vec<(u32, u8)> = Vec::new();
pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u32)> {
let mut keys: Vec<(u32, u32)> = Vec::new();
let shape_id = obj.shape_id();
let mut pos: u8 = 0;
let mut pos: u32 = 0;
let mut shape_ids = Vec::new();
let mut cursor = Some(shape_id);
while let Some(id) = cursor {
@@ -67,7 +67,7 @@ pub fn object_keys(vm: &mut Vm, args: &[u8]) -> NativeResult {
.collect();
}
let n = key_names.len().min(255);
let n = key_names.len();
let array_proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
let arr = vm.epoch().alloc(JsObject::new_array(
EMPTY_SHAPE_ID,
@@ -75,12 +75,15 @@ pub fn object_keys(vm: &mut Vm, args: &[u8]) -> NativeResult {
n,
vm.epoch().bump(),
));
for k in key_names.iter().take(n) {
for (i, k) in key_names.iter().enumerate() {
let str_val = vm.intern(k);
unsafe {
(*arr).ensure_hash_props().push(Box::new(str_val));
(*arr).set_prop_at(i, str_val);
}
}
unsafe {
(*arr).set_prop_count(n);
}
Ok(JsValue::from_js_object(arr))
}
@@ -334,7 +337,7 @@ pub fn object_get_own_property_names(vm: &mut Vm, args: &[u8]) -> NativeResult {
.collect()
};
let n = key_names.len().min(255);
let n = key_names.len();
let array_proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
let arr = vm.epoch().alloc(JsObject::new_array(
EMPTY_SHAPE_ID,
@@ -342,12 +345,15 @@ pub fn object_get_own_property_names(vm: &mut Vm, args: &[u8]) -> NativeResult {
n,
vm.epoch().bump(),
));
for k in key_names.iter().take(n) {
for (i, k) in key_names.iter().enumerate() {
let str_val = vm.intern(k);
unsafe {
(*arr).ensure_hash_props().push(Box::new(str_val));
(*arr).set_prop_at(i, str_val);
}
}
unsafe {
(*arr).set_prop_count(n);
}
Ok(JsValue::from_js_object(arr))
}
@@ -399,7 +405,7 @@ pub fn object_entries(vm: &mut Vm, args: &[u8]) -> NativeResult {
let obj_ptr = require_obj_arg(vm, args, "entries")?;
let obj = unsafe { &*obj_ptr };
let keys = walk_own_keys(vm, obj);
let n = keys.len().min(255);
let n = keys.len();
let array_proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
let arr = vm.epoch().alloc(JsObject::new_array(
EMPTY_SHAPE_ID,
@@ -407,7 +413,7 @@ pub fn object_entries(vm: &mut Vm, args: &[u8]) -> NativeResult {
n,
vm.epoch().bump(),
));
for (_i, (si, offset)) in keys.iter().enumerate().take(n) {
for (i, (si, offset)) in keys.iter().enumerate() {
let key_str = vm.kernel().string_forge().lookup(*si).unwrap_or_default();
let key_val = vm.intern(&key_str);
let val = obj.get_prop_at(*offset);
@@ -421,11 +427,12 @@ pub fn object_entries(vm: &mut Vm, args: &[u8]) -> NativeResult {
(*pair).set_prop_at(0, key_val);
(*pair).set_prop_at(1, val);
(*pair).set_prop_count(2);
(*arr)
.ensure_hash_props()
.push(Box::new(JsValue::from_js_object(pair)));
(*arr).set_prop_at(i, JsValue::from_js_object(pair));
}
}
unsafe {
(*arr).set_prop_count(n);
}
Ok(JsValue::from_js_object(arr))
}
@@ -433,7 +440,7 @@ pub fn object_values(vm: &mut Vm, args: &[u8]) -> NativeResult {
let obj_ptr = require_obj_arg(vm, args, "values")?;
let obj = unsafe { &*obj_ptr };
let keys = walk_own_keys(vm, obj);
let n = keys.len().min(255);
let n = keys.len();
let array_proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
let arr = vm.epoch().alloc(JsObject::new_array(
EMPTY_SHAPE_ID,
@@ -441,14 +448,14 @@ pub fn object_values(vm: &mut Vm, args: &[u8]) -> NativeResult {
n,
vm.epoch().bump(),
));
for (i, (_si, offset)) in keys.iter().enumerate().take(n) {
for (i, (_si, offset)) in keys.iter().enumerate() {
let val = obj.get_prop_at(*offset);
unsafe {
(*arr).set_prop_at(i as u8, val);
(*arr).set_prop_at(i, val);
}
}
unsafe {
(*arr).set_prop_count(n as u8);
(*arr).set_prop_count(n);
}
Ok(JsValue::from_js_object(arr))
}