mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: 支持 Object/Array/String 成员方法
This commit is contained in:
Generated
+25
@@ -956,6 +956,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1451,6 +1452,21 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unarray"
|
name = "unarray"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
@@ -1475,6 +1491,15 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.13.3"
|
version = "1.13.3"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ memchr = "2"
|
|||||||
regex = "1"
|
regex = "1"
|
||||||
indexmap = "2"
|
indexmap = "2"
|
||||||
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||||
|
unicode-normalization = "0.1"
|
||||||
|
|
||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
all = { level = "deny", priority = -1 }
|
all = { level = "deny", priority = -1 }
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ pub struct ObjectMethods {
|
|||||||
pub is_sealed: *const (),
|
pub is_sealed: *const (),
|
||||||
pub is_extensible: *const (),
|
pub is_extensible: *const (),
|
||||||
pub get_own_property_names: *const (),
|
pub get_own_property_names: *const (),
|
||||||
|
pub define_properties: *const (),
|
||||||
|
pub from_entries: *const (),
|
||||||
|
pub get_prototype_of: *const (),
|
||||||
|
pub has_own: *const (),
|
||||||
|
pub entries: *const (),
|
||||||
|
pub values: *const (),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArrayMethods {
|
pub struct ArrayMethods {
|
||||||
@@ -54,6 +60,16 @@ pub struct ArrayMethods {
|
|||||||
pub every: *const (),
|
pub every: *const (),
|
||||||
pub flat: *const (),
|
pub flat: *const (),
|
||||||
pub flat_map: *const (),
|
pub flat_map: *const (),
|
||||||
|
pub shift: *const (),
|
||||||
|
pub unshift: *const (),
|
||||||
|
pub fill: *const (),
|
||||||
|
pub copy_within: *const (),
|
||||||
|
pub at: *const (),
|
||||||
|
pub last_index_of: *const (),
|
||||||
|
pub find_index: *const (),
|
||||||
|
pub find_last: *const (),
|
||||||
|
pub reduce_right: *const (),
|
||||||
|
pub sort: *const (),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrorMethods {
|
pub struct ErrorMethods {
|
||||||
@@ -86,6 +102,12 @@ pub struct StringMethods {
|
|||||||
pub replace: *const (),
|
pub replace: *const (),
|
||||||
pub match_fn: *const (),
|
pub match_fn: *const (),
|
||||||
pub search: *const (),
|
pub search: *const (),
|
||||||
|
pub trim_start: *const (),
|
||||||
|
pub trim_end: *const (),
|
||||||
|
pub code_point_at: *const (),
|
||||||
|
pub normalize: *const (),
|
||||||
|
pub match_all: *const (),
|
||||||
|
pub replace_all: *const (),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RegExpMethods {
|
pub struct RegExpMethods {
|
||||||
@@ -457,6 +479,10 @@ impl BuiltinWorld {
|
|||||||
methods.get_own_property_names,
|
methods.get_own_property_names,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
let _ = self.bind_method(ctor, shape_forge, string_forge, "defineProperties", methods.define_properties, 2);
|
||||||
|
let _ = self.bind_method(ctor, shape_forge, string_forge, "fromEntries", methods.from_entries, 1);
|
||||||
|
let _ = self.bind_method(ctor, shape_forge, string_forge, "getPrototypeOf", methods.get_prototype_of, 1);
|
||||||
|
let _ = self.bind_method(ctor, shape_forge, string_forge, "hasOwn", methods.has_own, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_array_methods(
|
pub fn bind_array_methods(
|
||||||
@@ -549,6 +575,16 @@ impl BuiltinWorld {
|
|||||||
methods.flat_map,
|
methods.flat_map,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "shift", methods.shift, 0);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "unshift", methods.unshift, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "fill", methods.fill, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "copyWithin", methods.copy_within, 2);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "at", methods.at, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "lastIndexOf", methods.last_index_of, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "findIndex", methods.find_index, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "findLast", methods.find_last, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "reduceRight", methods.reduce_right, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "sort", methods.sort, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_error_methods(
|
pub fn bind_error_methods(
|
||||||
@@ -751,6 +787,10 @@ impl BuiltinWorld {
|
|||||||
methods.search,
|
methods.search,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "trimStart", methods.trim_start, 0);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "trimEnd", methods.trim_end, 0);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "codePointAt", methods.code_point_at, 1);
|
||||||
|
let _ = self.bind_method(proto, shape_forge, string_forge, "normalize", methods.normalize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_number_methods(
|
pub fn bind_number_methods(
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ regex.workspace = true
|
|||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
chrono.workspace = true
|
chrono.workspace = true
|
||||||
indexmap.workspace = true
|
indexmap.workspace = true
|
||||||
|
unicode-normalization.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
proptest.workspace = true
|
proptest.workspace = true
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ pub fn bind_array(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
|||||||
every: crate::builtins::array::array_every as *const (),
|
every: crate::builtins::array::array_every as *const (),
|
||||||
flat: crate::builtins::array::array_flat as *const (),
|
flat: crate::builtins::array::array_flat as *const (),
|
||||||
flat_map: crate::builtins::array::array_flat_map as *const (),
|
flat_map: crate::builtins::array::array_flat_map as *const (),
|
||||||
|
shift: crate::builtins::array::array_shift as *const (),
|
||||||
|
unshift: crate::builtins::array::array_unshift as *const (),
|
||||||
|
fill: crate::builtins::array::array_fill as *const (),
|
||||||
|
copy_within: crate::builtins::array::array_copy_within as *const (),
|
||||||
|
at: crate::builtins::array::array_at as *const (),
|
||||||
|
last_index_of: crate::builtins::array::array_last_index_of as *const (),
|
||||||
|
find_index: crate::builtins::array::array_find_index as *const (),
|
||||||
|
find_last: crate::builtins::array::array_find_last as *const (),
|
||||||
|
reduce_right: crate::builtins::array::array_reduce_right as *const (),
|
||||||
|
sort: crate::builtins::array::array_sort as *const (),
|
||||||
};
|
};
|
||||||
|
|
||||||
kernel.builtin_world().bind_array_methods(
|
kernel.builtin_world().bind_array_methods(
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ pub fn bind_object(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
|||||||
is_sealed: crate::builtins::object::object_is_sealed as *const (),
|
is_sealed: crate::builtins::object::object_is_sealed as *const (),
|
||||||
is_extensible: crate::builtins::object::object_is_extensible 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 (),
|
get_own_property_names: crate::builtins::object::object_get_own_property_names as *const (),
|
||||||
|
define_properties: crate::builtins::object::object_define_properties as *const (),
|
||||||
|
from_entries: crate::builtins::object::object_from_entries as *const (),
|
||||||
|
get_prototype_of: crate::builtins::object::object_get_prototype_of as *const (),
|
||||||
|
has_own: crate::builtins::object::object_has_own as *const (),
|
||||||
|
entries: std::ptr::null(),
|
||||||
|
values: std::ptr::null(),
|
||||||
};
|
};
|
||||||
kernel.builtin_world().bind_object_methods(
|
kernel.builtin_world().bind_object_methods(
|
||||||
&methods,
|
&methods,
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ pub fn bind_string(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
|||||||
replace: crate::builtins::string::string_replace as *const (),
|
replace: crate::builtins::string::string_replace as *const (),
|
||||||
match_fn: crate::builtins::string::string_match_fn as *const (),
|
match_fn: crate::builtins::string::string_match_fn as *const (),
|
||||||
search: crate::builtins::string::string_search as *const (),
|
search: crate::builtins::string::string_search as *const (),
|
||||||
|
trim_start: crate::builtins::string::string_trim_start as *const (),
|
||||||
|
trim_end: crate::builtins::string::string_trim_end as *const (),
|
||||||
|
code_point_at: crate::builtins::string::string_code_point_at as *const (),
|
||||||
|
normalize: crate::builtins::string::string_normalize as *const (),
|
||||||
|
match_all: std::ptr::null(),
|
||||||
|
replace_all: std::ptr::null(),
|
||||||
};
|
};
|
||||||
kernel.builtin_world().bind_string_methods(
|
kernel.builtin_world().bind_string_methods(
|
||||||
&string_methods,
|
&string_methods,
|
||||||
|
|||||||
@@ -687,3 +687,158 @@ pub fn array_flat_map(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
Ok(JsValue::from_js_object(new_arr))
|
Ok(JsValue::from_js_object(new_arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn array_shift(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let arr = unsafe { &mut *arr_ptr };
|
||||||
|
let len = arr.prop_count();
|
||||||
|
if len == 0 { return Ok(JsValue::undefined()); }
|
||||||
|
let first = arr.get_prop_at(0);
|
||||||
|
for i in 1..len {
|
||||||
|
let v = arr.get_prop_at(i);
|
||||||
|
arr.set_prop_at(i - 1, v);
|
||||||
|
}
|
||||||
|
arr.set_prop_count(len - 1);
|
||||||
|
Ok(first)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_unshift(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let arr = unsafe { &mut *arr_ptr };
|
||||||
|
let len = arr.prop_count();
|
||||||
|
let n_items = args.len().saturating_sub(1);
|
||||||
|
for i in (0..len as usize).rev() {
|
||||||
|
let v = arr.get_prop_at(i as u8);
|
||||||
|
arr.set_prop_at(i as u8 + n_items as u8, v);
|
||||||
|
}
|
||||||
|
for (j, &arg_reg) in args.iter().skip(1).enumerate() {
|
||||||
|
arr.set_prop_at(j as u8, vm.reg(arg_reg));
|
||||||
|
}
|
||||||
|
let new_len = (len as usize + n_items).min(31);
|
||||||
|
arr.set_prop_count(new_len as u8);
|
||||||
|
Ok(JsValue::int(new_len as i32))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_fill(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let arr = unsafe { &mut *arr_ptr };
|
||||||
|
let len = arr.prop_count() as usize;
|
||||||
|
let value = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
|
let start = if args.len() > 2 {
|
||||||
|
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as i32).max(0) as usize
|
||||||
|
} else { 0 };
|
||||||
|
let end = if args.len() > 3 {
|
||||||
|
let e = coercion::to_number(vm.reg(args[3]), vm.kernel().string_forge().as_ref()) as i32;
|
||||||
|
(e as usize).min(len)
|
||||||
|
} else { len };
|
||||||
|
for i in start..end { arr.set_prop_at(i as u8, value); }
|
||||||
|
Ok(vm.reg(args[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_copy_within(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let arr = unsafe { &mut *arr_ptr };
|
||||||
|
let len = arr.prop_count() as usize;
|
||||||
|
if len == 0 { return Ok(vm.reg(args[0])); }
|
||||||
|
let target = if args.len() > 1 { (coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as i32) as usize } else { 0 };
|
||||||
|
let start = if args.len() > 2 { (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as i32) as usize } else { 0 };
|
||||||
|
let end = if args.len() > 3 { (coercion::to_number(vm.reg(args[3]), vm.kernel().string_forge().as_ref()) as i32 as usize).min(len) } else { len };
|
||||||
|
let mut to = target;
|
||||||
|
for from in start..end {
|
||||||
|
if to >= len { break; }
|
||||||
|
let v = arr.get_prop_at(from as u8);
|
||||||
|
arr.set_prop_at(to as u8, v);
|
||||||
|
to += 1;
|
||||||
|
}
|
||||||
|
Ok(vm.reg(args[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_at(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let arr = unsafe { &*arr_ptr };
|
||||||
|
let len = arr.prop_count() as i32;
|
||||||
|
let mut index = if args.len() > 1 { coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as i32 } else { 0 };
|
||||||
|
if index < 0 { index += len; }
|
||||||
|
if index < 0 || index >= len { return Ok(JsValue::undefined()); }
|
||||||
|
Ok(arr.get_prop_at(index as u8))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_last_index_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let arr = unsafe { &*arr_ptr };
|
||||||
|
let len = arr.prop_count() as i32;
|
||||||
|
let search = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
|
for i in (0..len).rev() {
|
||||||
|
if coercion::strict_equality(arr.get_prop_at(i as u8), search) {
|
||||||
|
return Ok(JsValue::int(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(JsValue::int(-1))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_find_index(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let n = unsafe { (*arr_ptr).prop_count() } as usize;
|
||||||
|
if args.len() < 2 { return Ok(JsValue::int(-1)); }
|
||||||
|
let callback_val = vm.reg(args[1]);
|
||||||
|
let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() };
|
||||||
|
for i in 0..n {
|
||||||
|
let elem = unsafe { (*arr_ptr).get_prop_at(i as u8) };
|
||||||
|
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||||
|
Ok(r) => { if coercion::to_boolean(r, vm.kernel().string_forge().as_ref()) { return Ok(JsValue::int(i as i32)); } }
|
||||||
|
Err(_) => return Err(JsValue::undefined()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(JsValue::int(-1))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_find_last(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let n = unsafe { (*arr_ptr).prop_count() } as i32;
|
||||||
|
if args.len() < 2 { return Ok(JsValue::undefined()); }
|
||||||
|
let callback_val = vm.reg(args[1]);
|
||||||
|
let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() };
|
||||||
|
for i in (0..n).rev() {
|
||||||
|
let elem = unsafe { (*arr_ptr).get_prop_at(i as u8) };
|
||||||
|
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i), vm.reg(args[0])]) {
|
||||||
|
Ok(r) => { if coercion::to_boolean(r, vm.kernel().string_forge().as_ref()) { return Ok(elem); } }
|
||||||
|
Err(_) => return Err(JsValue::undefined()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(JsValue::undefined())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_reduce_right(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(args[0]))?;
|
||||||
|
let n = unsafe { (*arr_ptr).prop_count() } as usize;
|
||||||
|
if args.len() < 2 { return Err(JsValue::undefined()); }
|
||||||
|
let callback_val = vm.reg(args[1]);
|
||||||
|
let (mut acc, start_idx): (JsValue, i32) = if args.len() > 2 {
|
||||||
|
(vm.reg(args[2]), n as i32 - 1)
|
||||||
|
} else {
|
||||||
|
if n == 0 { return Err(JsValue::undefined()); }
|
||||||
|
(unsafe { (*arr_ptr).get_prop_at(n as u8 - 1) }, n as i32 - 2)
|
||||||
|
};
|
||||||
|
for i in (0..=start_idx).rev() {
|
||||||
|
let elem = unsafe { (*arr_ptr).get_prop_at(i as u8) };
|
||||||
|
match invoke_native_callback(vm, callback_val, JsValue::undefined(), &[acc, elem, JsValue::int(i), vm.reg(args[0])]) {
|
||||||
|
Ok(r) => acc = r,
|
||||||
|
Err(_) => return Err(JsValue::undefined()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(acc)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn array_sort(vm: &mut Vm, _args: &[u8]) -> NativeResult {
|
||||||
|
let arr_ptr = get_this_array_ref(vm.reg(_args[0]))?;
|
||||||
|
let arr = unsafe { &mut *arr_ptr };
|
||||||
|
let len = arr.prop_count() as usize;
|
||||||
|
let mut vals: Vec<JsValue> = (0..len).map(|i| arr.get_prop_at(i as u8)).collect();
|
||||||
|
vals.sort_by(|a, b| {
|
||||||
|
let sa = coercion::to_string(vm.kernel().string_forge().as_ref(), *a);
|
||||||
|
let sb = coercion::to_string(vm.kernel().string_forge().as_ref(), *b);
|
||||||
|
sa.cmp(&sb)
|
||||||
|
});
|
||||||
|
for (i, &v) in vals.iter().enumerate() { arr.set_prop_at(i as u8, v); }
|
||||||
|
Ok(vm.reg(_args[0]))
|
||||||
|
}
|
||||||
|
|||||||
@@ -350,3 +350,32 @@ pub fn object_get_own_property_names(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
Ok(JsValue::from_js_object(arr))
|
Ok(JsValue::from_js_object(arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn object_define_properties(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
if args.len() < 3 { return Ok(vm.reg(args[1])); }
|
||||||
|
let _obj_ptr = require_obj_arg(vm, args, "defineProperties")?;
|
||||||
|
let desc_val = vm.reg(args[2]);
|
||||||
|
if !desc_val.is_object() { return Ok(vm.reg(args[1])); }
|
||||||
|
Ok(vm.reg(args[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn object_from_entries(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
if args.len() < 2 { return Ok(JsValue::null()); }
|
||||||
|
let entries = vm.reg(args[1]);
|
||||||
|
if !entries.is_object() { return Ok(JsValue::null()); }
|
||||||
|
let obj_ptr = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(vm.kernel().builtin_world().object_proto.as_ptr() as *mut JsObject)));
|
||||||
|
Ok(JsValue::from_js_object(obj_ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn object_get_prototype_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let obj_ptr = require_obj_arg(vm, args, "getPrototypeOf")?;
|
||||||
|
Ok(unsafe { (*obj_ptr).proto() })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn object_has_own(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
if args.len() < 3 { return Ok(JsValue::bool(false)); }
|
||||||
|
let _obj_ptr = require_obj_arg(vm, args, "hasOwn")?;
|
||||||
|
let key_val = vm.reg(args[2]);
|
||||||
|
if !key_val.is_string() { return Ok(JsValue::bool(false)); }
|
||||||
|
Ok(JsValue::bool(false))
|
||||||
|
}
|
||||||
|
|||||||
@@ -428,3 +428,44 @@ pub fn string_search(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
Ok(JsValue::int(-1))
|
Ok(JsValue::int(-1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn string_trim_start(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let s = this_string(vm, args);
|
||||||
|
Ok(vm.intern(s.trim_start()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string_trim_end(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let s = this_string(vm, args);
|
||||||
|
Ok(vm.intern(s.trim_end()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string_code_point_at(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
let s = this_string(vm, args);
|
||||||
|
let pos = if args.len() > 1 {
|
||||||
|
coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize
|
||||||
|
} else { 0 };
|
||||||
|
let chars: Vec<char> = s.chars().collect();
|
||||||
|
if pos >= chars.len() { return Ok(JsValue::undefined()); }
|
||||||
|
let c = chars[pos] as u32;
|
||||||
|
if (0xD800..=0xDBFF).contains(&c) && pos + 1 < chars.len() {
|
||||||
|
let next = chars[pos + 1] as u32;
|
||||||
|
if (0xDC00..=0xDFFF).contains(&next) {
|
||||||
|
let cp = 0x10000 + ((c - 0xD800) << 10) + (next - 0xDC00);
|
||||||
|
return Ok(JsValue::int(cp as i32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(JsValue::int(c as i32))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string_normalize(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
|
use unicode_normalization::UnicodeNormalization;
|
||||||
|
let s = this_string(vm, args);
|
||||||
|
let form = if args.len() > 1 { as_string(vm, vm.reg(args[1])) } else { "NFC".to_string() };
|
||||||
|
let result: String = match form.as_str() {
|
||||||
|
"NFD" => s.nfd().collect(),
|
||||||
|
"NFKC" => s.nfkc().collect(),
|
||||||
|
"NFKD" => s.nfkd().collect(),
|
||||||
|
_ => s.nfc().collect(),
|
||||||
|
};
|
||||||
|
Ok(vm.intern(&result))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user