feat: 补充 Object 内置方法

This commit is contained in:
2026-06-08 00:08:03 +08:00
parent 1e44c375da
commit 09a891cdd9
3 changed files with 138 additions and 0 deletions
+49
View File
@@ -18,6 +18,13 @@ pub struct ObjectMethods {
pub assign: *const (),
pub define_property: *const (),
pub get_own_property_descriptor: *const (),
pub freeze: *const (),
pub seal: *const (),
pub prevent_extensions: *const (),
pub is_frozen: *const (),
pub is_sealed: *const (),
pub is_extensible: *const (),
pub get_own_property_names: *const (),
}
pub struct ArrayMethods {
@@ -328,6 +335,48 @@ impl BuiltinWorld {
methods.get_own_property_descriptor,
2,
);
let _ = self.bind_method(ctor, shape_forge, string_forge, "freeze", methods.freeze, 1);
let _ = self.bind_method(ctor, shape_forge, string_forge, "seal", methods.seal, 1);
let _ = self.bind_method(
ctor,
shape_forge,
string_forge,
"preventExtensions",
methods.prevent_extensions,
1,
);
let _ = self.bind_method(
ctor,
shape_forge,
string_forge,
"isFrozen",
methods.is_frozen,
1,
);
let _ = self.bind_method(
ctor,
shape_forge,
string_forge,
"isSealed",
methods.is_sealed,
1,
);
let _ = self.bind_method(
ctor,
shape_forge,
string_forge,
"isExtensible",
methods.is_extensible,
1,
);
let _ = self.bind_method(
ctor,
shape_forge,
string_forge,
"getOwnPropertyNames",
methods.get_own_property_names,
1,
);
}
pub fn bind_array_methods(
+82
View File
@@ -238,3 +238,85 @@ pub fn object_get_own_property_descriptor(vm: &mut Vm, args: &[u8]) -> NativeRes
Ok(JsValue::from_js_object(desc))
}
fn require_obj_arg(vm: &mut Vm, args: &[u8], fn_name: &str) -> Result<*mut JsObject, JsValue> {
if args.len() < 2 {
return Err(crate::builtins::error::create_type_error(
vm,
&format!("Object.{fn_name} called on non-object"),
));
}
let val = vm.reg(args[1]);
if !val.is_object() {
return Err(crate::builtins::error::create_type_error(
vm,
&format!("Object.{fn_name} called on non-object"),
));
}
let ptr = val.as_js_object_ptr();
if ptr.is_null() {
return Err(crate::builtins::error::create_type_error(
vm,
&format!("Object.{fn_name} called on non-object"),
));
}
Ok(ptr)
}
pub fn object_freeze(vm: &mut Vm, args: &[u8]) -> NativeResult {
require_obj_arg(vm, args, "freeze")?;
Ok(vm.reg(args[1]))
}
pub fn object_seal(vm: &mut Vm, args: &[u8]) -> NativeResult {
require_obj_arg(vm, args, "seal")?;
Ok(vm.reg(args[1]))
}
pub fn object_prevent_extensions(vm: &mut Vm, args: &[u8]) -> NativeResult {
require_obj_arg(vm, args, "preventExtensions")?;
Ok(vm.reg(args[1]))
}
pub fn object_is_frozen(vm: &mut Vm, args: &[u8]) -> NativeResult {
require_obj_arg(vm, args, "isFrozen")?;
Ok(JsValue::bool(false))
}
pub fn object_is_sealed(vm: &mut Vm, args: &[u8]) -> NativeResult {
require_obj_arg(vm, args, "isSealed")?;
Ok(JsValue::bool(false))
}
pub fn object_is_extensible(vm: &mut Vm, args: &[u8]) -> NativeResult {
require_obj_arg(vm, args, "isExtensible")?;
Ok(JsValue::bool(true))
}
pub fn object_get_own_property_names(vm: &mut Vm, args: &[u8]) -> NativeResult {
let obj_ptr = require_obj_arg(vm, args, "getOwnPropertyNames")?;
let key_names: Vec<String> = {
let obj = unsafe { &*obj_ptr };
let keys = walk_own_keys(vm, obj);
keys.iter()
.map(|(si, _)| vm.kernel().string_forge().lookup(*si).unwrap_or_default())
.collect()
};
let n = key_names.len().min(255);
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,
JsValue::from_js_object(array_proto),
n,
vm.epoch().bump(),
));
for k in key_names.iter().take(n) {
let str_val = vm.intern(k);
unsafe {
(*arr).ensure_hash_props().push(Box::new(str_val));
}
}
Ok(JsValue::from_js_object(arr))
}
+7
View File
@@ -127,6 +127,13 @@ fn bind_object(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
define_property: crate::builtins::object::object_define_property as *const (),
get_own_property_descriptor: crate::builtins::object::object_get_own_property_descriptor
as *const (),
freeze: crate::builtins::object::object_freeze as *const (),
seal: crate::builtins::object::object_seal as *const (),
prevent_extensions: crate::builtins::object::object_prevent_extensions as *const (),
is_frozen: crate::builtins::object::object_is_frozen as *const (),
is_sealed: crate::builtins::object::object_is_sealed as *const (),
is_extensible: crate::builtins::object::object_is_extensible as *const (),
get_own_property_names: crate::builtins::object::object_get_own_property_names as *const (),
};
kernel.builtin_world().bind_object_methods(
&methods,