feat: 补充 Object 内置方法
This commit is contained in:
@@ -18,6 +18,13 @@ pub struct ObjectMethods {
|
|||||||
pub assign: *const (),
|
pub assign: *const (),
|
||||||
pub define_property: *const (),
|
pub define_property: *const (),
|
||||||
pub get_own_property_descriptor: *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 {
|
pub struct ArrayMethods {
|
||||||
@@ -328,6 +335,48 @@ impl BuiltinWorld {
|
|||||||
methods.get_own_property_descriptor,
|
methods.get_own_property_descriptor,
|
||||||
2,
|
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(
|
pub fn bind_array_methods(
|
||||||
|
|||||||
@@ -238,3 +238,85 @@ pub fn object_get_own_property_descriptor(vm: &mut Vm, args: &[u8]) -> NativeRes
|
|||||||
|
|
||||||
Ok(JsValue::from_js_object(desc))
|
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))
|
||||||
|
}
|
||||||
|
|||||||
@@ -127,6 +127,13 @@ fn bind_object(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
|||||||
define_property: crate::builtins::object::object_define_property as *const (),
|
define_property: crate::builtins::object::object_define_property as *const (),
|
||||||
get_own_property_descriptor: crate::builtins::object::object_get_own_property_descriptor
|
get_own_property_descriptor: crate::builtins::object::object_get_own_property_descriptor
|
||||||
as *const (),
|
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(
|
kernel.builtin_world().bind_object_methods(
|
||||||
&methods,
|
&methods,
|
||||||
|
|||||||
Reference in New Issue
Block a user