mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
refactor: 用户数字参数改走 coerce_number_bounded,对象参数支持 ToPrimitive
This commit is contained in:
@@ -68,7 +68,7 @@ fn create_new_array<H: VmHost>(vm: &mut H, n: usize) -> *mut JsObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn array_length_arg<H: VmHost>(vm: &mut H, value: JsValue) -> Result<usize, JsValue> {
|
fn array_length_arg<H: VmHost>(vm: &mut H, value: JsValue) -> Result<usize, JsValue> {
|
||||||
let n = oxide_runtime_api::to_number(value);
|
let n = vm.coerce_number_bounded(value).unwrap_or(f64::NAN);
|
||||||
if !n.is_finite() || n < 0.0 || n.fract() != 0.0 || n > MAX_DENSE_PROPS as f64 {
|
if !n.is_finite() || n < 0.0 || n.fract() != 0.0 || n > MAX_DENSE_PROPS as f64 {
|
||||||
return Err(crate::error::create_range_error(vm, "Invalid array length"));
|
return Err(crate::error::create_range_error(vm, "Invalid array length"));
|
||||||
}
|
}
|
||||||
@@ -195,12 +195,12 @@ pub fn array_slice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let arr = unsafe { &*arr_ptr };
|
let arr = unsafe { &*arr_ptr };
|
||||||
let n = arr.prop_count() as usize;
|
let n = arr.prop_count() as usize;
|
||||||
let start = if args.len() > 1 {
|
let start = if args.len() > 1 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[1])) as i32) as usize
|
(vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32) as usize
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let end = if args.len() > 2 {
|
let end = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as i32) as usize
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as i32) as usize
|
||||||
} else {
|
} else {
|
||||||
n
|
n
|
||||||
};
|
};
|
||||||
@@ -225,7 +225,7 @@ pub fn array_splice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let n = arr.prop_count() as usize;
|
let n = arr.prop_count() as usize;
|
||||||
|
|
||||||
let start = if args.len() > 1 {
|
let start = if args.len() > 1 {
|
||||||
let v = oxide_runtime_api::to_number(vm.reg(args[1]));
|
let v = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN);
|
||||||
let s = v as i32;
|
let s = v as i32;
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
(n as i32 + s).max(0) as usize
|
(n as i32 + s).max(0) as usize
|
||||||
@@ -237,7 +237,7 @@ pub fn array_splice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let delete_count = if args.len() > 2 {
|
let delete_count = if args.len() > 2 {
|
||||||
let v = oxide_runtime_api::to_number(vm.reg(args[2]));
|
let v = vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN);
|
||||||
(v as usize).min(n - start)
|
(v as usize).min(n - start)
|
||||||
} else {
|
} else {
|
||||||
n - start
|
n - start
|
||||||
@@ -413,7 +413,7 @@ pub fn array_flat<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let arr = unsafe { &*arr_ptr };
|
let arr = unsafe { &*arr_ptr };
|
||||||
let n = arr.prop_count() as usize;
|
let n = arr.prop_count() as usize;
|
||||||
let depth = if args.len() > 1 {
|
let depth = if args.len() > 1 {
|
||||||
let n = oxide_runtime_api::to_number(vm.reg(args[1]));
|
let n = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN);
|
||||||
if !n.is_finite() {
|
if !n.is_finite() {
|
||||||
vm.kernel_core().config.max_call_depth
|
vm.kernel_core().config.max_call_depth
|
||||||
} else {
|
} else {
|
||||||
@@ -834,12 +834,12 @@ pub fn array_fill<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let len = arr.prop_count() as usize;
|
let len = arr.prop_count() as usize;
|
||||||
let value = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let value = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let start = if args.len() > 2 {
|
let start = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as i32).max(0) as usize
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as i32).max(0) as usize
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let end = if args.len() > 3 {
|
let end = if args.len() > 3 {
|
||||||
let e = oxide_runtime_api::to_number(vm.reg(args[3])) as i32;
|
let e = vm.coerce_number_bounded(vm.reg(args[3])).unwrap_or(f64::NAN) as i32;
|
||||||
(e as usize).min(len)
|
(e as usize).min(len)
|
||||||
} else {
|
} else {
|
||||||
len
|
len
|
||||||
@@ -859,17 +859,17 @@ pub fn array_copy_within<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
return NativeResult::Ok(vm.reg(args[0]));
|
return NativeResult::Ok(vm.reg(args[0]));
|
||||||
}
|
}
|
||||||
let target = if args.len() > 1 {
|
let target = if args.len() > 1 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[1])) as i32) as usize
|
(vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32) as usize
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let start = if args.len() > 2 {
|
let start = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as i32) as usize
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as i32) as usize
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let end = if args.len() > 3 {
|
let end = if args.len() > 3 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[3])) as i32 as usize).min(len)
|
(vm.coerce_number_bounded(vm.reg(args[3])).unwrap_or(f64::NAN) as i32 as usize).min(len)
|
||||||
} else {
|
} else {
|
||||||
len
|
len
|
||||||
};
|
};
|
||||||
@@ -891,7 +891,7 @@ pub fn array_at<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let arr = unsafe { &*arr_ptr };
|
let arr = unsafe { &*arr_ptr };
|
||||||
let len = arr.prop_count() as i32;
|
let len = arr.prop_count() as i32;
|
||||||
let mut index = if args.len() > 1 {
|
let mut index = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as i32
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ fn type_error<H: VmHost>(vm: &mut H, msg: &str) -> NativeResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn to_index<H: VmHost>(vm: &mut H, value: JsValue) -> Result<usize, JsValue> {
|
fn to_index<H: VmHost>(vm: &mut H, value: JsValue) -> Result<usize, JsValue> {
|
||||||
let n = oxide_runtime_api::to_number(value);
|
let n = vm.coerce_number_bounded(value).unwrap_or(f64::NAN);
|
||||||
if n.is_nan() {
|
if n.is_nan() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@@ -30,8 +30,8 @@ fn to_index<H: VmHost>(vm: &mut H, value: JsValue) -> Result<usize, JsValue> {
|
|||||||
Ok(n.trunc() as usize)
|
Ok(n.trunc() as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normalize_index<H: VmHost>(_vm: &mut H, value: JsValue, len: usize) -> usize {
|
fn normalize_index<H: VmHost>(vm: &mut H, value: JsValue, len: usize) -> usize {
|
||||||
let n = oxide_runtime_api::to_number(value);
|
let n = vm.coerce_number_bounded(value).unwrap_or(f64::NAN);
|
||||||
if n.is_nan() {
|
if n.is_nan() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ macro_rules! native_try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn to_index<H: VmHost>(vm: &mut H, value: JsValue, msg: &str) -> Result<usize, JsValue> {
|
fn to_index<H: VmHost>(vm: &mut H, value: JsValue, msg: &str) -> Result<usize, JsValue> {
|
||||||
let n = oxide_runtime_api::to_number(value);
|
let n = vm.coerce_number_bounded(value).unwrap_or(f64::NAN);
|
||||||
if n.is_nan() {
|
if n.is_nan() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ fn is_little_endian<H: VmHost>(vm: &mut H, args: &[u8], idx: usize) -> bool {
|
|||||||
|
|
||||||
fn numeric_arg<H: VmHost>(vm: &mut H, args: &[u8], idx: usize) -> f64 {
|
fn numeric_arg<H: VmHost>(vm: &mut H, args: &[u8], idx: usize) -> f64 {
|
||||||
args.get(idx)
|
args.get(idx)
|
||||||
.map(|reg| oxide_runtime_api::to_number(vm.reg(*reg)))
|
.map(|reg| vm.coerce_number_bounded(vm.reg(*reg)).unwrap_or(f64::NAN))
|
||||||
.unwrap_or(0.0)
|
.unwrap_or(0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,30 +102,30 @@ pub fn date_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let timestamp = if args.len() < 2 {
|
let timestamp = if args.len() < 2 {
|
||||||
Utc::now().timestamp_millis() as f64
|
Utc::now().timestamp_millis() as f64
|
||||||
} else if args.len() > 2 {
|
} else if args.len() > 2 {
|
||||||
let y = oxide_runtime_api::to_number(vm.reg(args[1])) as i32;
|
let y = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32;
|
||||||
let m = oxide_runtime_api::to_number(vm.reg(args[2])) as u32;
|
let m = vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as u32;
|
||||||
let d = if args.len() > 3 {
|
let d = if args.len() > 3 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[3])) as u32
|
vm.coerce_number_bounded(vm.reg(args[3])).unwrap_or(f64::NAN) as u32
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
let h = if args.len() > 4 {
|
let h = if args.len() > 4 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[4])) as u32
|
vm.coerce_number_bounded(vm.reg(args[4])).unwrap_or(f64::NAN) as u32
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let min = if args.len() > 5 {
|
let min = if args.len() > 5 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[5])) as u32
|
vm.coerce_number_bounded(vm.reg(args[5])).unwrap_or(f64::NAN) as u32
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let sec = if args.len() > 6 {
|
let sec = if args.len() > 6 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[6])) as u32
|
vm.coerce_number_bounded(vm.reg(args[6])).unwrap_or(f64::NAN) as u32
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let ms = if args.len() > 7 {
|
let ms = if args.len() > 7 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[7])) as u32
|
vm.coerce_number_bounded(vm.reg(args[7])).unwrap_or(f64::NAN) as u32
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
@@ -316,7 +316,7 @@ fn get_opt_arg<H: VmHost>(vm: &H, args: &[u8], idx: usize, default: u32) -> u32
|
|||||||
pub fn date_set_time<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_time<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let val = if args.len() > 1 {
|
let val = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1]))
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN)
|
||||||
} else {
|
} else {
|
||||||
f64::NAN
|
f64::NAN
|
||||||
};
|
};
|
||||||
@@ -326,7 +326,7 @@ pub fn date_set_time<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
|
|
||||||
pub fn date_set_full_year<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_full_year<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
@@ -349,7 +349,7 @@ pub fn date_set_full_year<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
pub fn date_set_month<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_month<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
@@ -367,7 +367,7 @@ pub fn date_set_month<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
pub fn date_set_date<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_date<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
@@ -384,7 +384,7 @@ pub fn date_set_date<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
pub fn date_set_hours<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_hours<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
@@ -409,7 +409,7 @@ pub fn date_set_hours<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
pub fn date_set_minutes<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_minutes<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
@@ -432,7 +432,7 @@ pub fn date_set_minutes<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
pub fn date_set_seconds<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_seconds<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
@@ -453,7 +453,7 @@ pub fn date_set_seconds<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
pub fn date_set_milliseconds<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn date_set_milliseconds<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||||
let v = oxide_runtime_api::to_number(val);
|
let v = vm.coerce_number_bounded(val).unwrap_or(f64::NAN);
|
||||||
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
let obj = unsafe { &mut *native_try!(date_this_mut(vm, args)) };
|
||||||
let ms = get_timestamp(obj);
|
let ms = get_timestamp(obj);
|
||||||
if !ms.is_finite() {
|
if !ms.is_finite() {
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ use oxide_types::value::JsValue;
|
|||||||
|
|
||||||
use oxide_runtime_api::{NativeResult, VmHost};
|
use oxide_runtime_api::{NativeResult, VmHost};
|
||||||
|
|
||||||
fn num<H: VmHost>(vm: &H, reg: u8) -> f64 {
|
fn num<H: VmHost>(vm: &mut H, reg: u8) -> f64 {
|
||||||
oxide_runtime_api::to_number(vm.reg(reg))
|
vm.coerce_number_bounded(vm.reg(reg)).unwrap_or(f64::NAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arg1<H: VmHost>(vm: &H, args: &[u8]) -> f64 {
|
fn arg1<H: VmHost>(vm: &mut H, args: &[u8]) -> f64 {
|
||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
f64::NAN
|
f64::NAN
|
||||||
} else {
|
} else {
|
||||||
@@ -14,11 +14,11 @@ fn arg1<H: VmHost>(vm: &H, args: &[u8]) -> f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arg2<H: VmHost>(vm: &H, args: &[u8]) -> (f64, f64) {
|
fn arg2<H: VmHost>(vm: &mut H, args: &[u8]) -> (f64, f64) {
|
||||||
(
|
// Sequenced (not a tuple literal) so the two coercions take &mut H one at a time.
|
||||||
if args.len() > 1 { num(vm, args[1]) } else { f64::NAN },
|
let a = if args.len() > 1 { num(vm, args[1]) } else { f64::NAN };
|
||||||
if args.len() > 2 { num(vm, args[2]) } else { f64::NAN },
|
let b = if args.len() > 2 { num(vm, args[2]) } else { f64::NAN };
|
||||||
)
|
(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn math_abs<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn math_abs<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ use oxide_types::value::JsValue;
|
|||||||
use oxide_runtime_api::{NativeResult, VmHost};
|
use oxide_runtime_api::{NativeResult, VmHost};
|
||||||
|
|
||||||
pub fn number_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn number_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let n = if args.len() > 1 { oxide_runtime_api::to_number(vm.reg(args[1])) } else { 0.0 };
|
let n = if args.len() > 1 {
|
||||||
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN)
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
let number_proto = vm.session().builtin_world().number_proto.as_ptr() as *mut oxide_types::object::JsObject;
|
let number_proto = vm.session().builtin_world().number_proto.as_ptr() as *mut oxide_types::object::JsObject;
|
||||||
let is_ctor = if let Some(this_reg) = args.first().copied() {
|
let is_ctor = if let Some(this_reg) = args.first().copied() {
|
||||||
let this_val = vm.reg(this_reg);
|
let this_val = vm.reg(this_reg);
|
||||||
@@ -81,7 +85,7 @@ pub fn number_parse_int<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let radix = if args.len() > 2 {
|
let radix = if args.len() > 2 {
|
||||||
let r = oxide_runtime_api::to_number(vm.reg(args[2])) as i32;
|
let r = vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as i32;
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
10
|
10
|
||||||
} else {
|
} else {
|
||||||
@@ -128,9 +132,9 @@ pub fn number_parse_float<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn number_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn number_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let n = oxide_runtime_api::to_number(vm.reg(args[0]));
|
let n = vm.coerce_number_bounded(vm.reg(args[0])).unwrap_or(f64::NAN);
|
||||||
let radix = if args.len() > 1 {
|
let radix = if args.len() > 1 {
|
||||||
let r = oxide_runtime_api::to_number(vm.reg(args[1])) as u32;
|
let r = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as u32;
|
||||||
r.clamp(2, 36)
|
r.clamp(2, 36)
|
||||||
} else {
|
} else {
|
||||||
10u32
|
10u32
|
||||||
@@ -179,9 +183,9 @@ pub fn number_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn number_to_fixed<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn number_to_fixed<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let n = oxide_runtime_api::to_number(vm.reg(args[0]));
|
let n = vm.coerce_number_bounded(vm.reg(args[0])).unwrap_or(f64::NAN);
|
||||||
let digits = if args.len() > 1 {
|
let digits = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as usize
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
0usize
|
0usize
|
||||||
}
|
}
|
||||||
@@ -205,9 +209,9 @@ pub fn number_is_safe_integer<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResul
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn number_to_exponential<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn number_to_exponential<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let n = oxide_runtime_api::to_number(vm.reg(args[0]));
|
let n = vm.coerce_number_bounded(vm.reg(args[0])).unwrap_or(f64::NAN);
|
||||||
let digits = if args.len() > 1 {
|
let digits = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as usize
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
0usize
|
0usize
|
||||||
}
|
}
|
||||||
@@ -223,9 +227,9 @@ pub fn number_to_exponential<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn number_to_precision<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
pub fn number_to_precision<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||||
let n = oxide_runtime_api::to_number(vm.reg(args[0]));
|
let n = vm.coerce_number_bounded(vm.reg(args[0])).unwrap_or(f64::NAN);
|
||||||
let precision = if args.len() > 1 {
|
let precision = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as usize
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
0usize
|
0usize
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ pub fn regexp_test<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
// SAFETY: fn_ptr holds a Box<regex::Regex> pointer stored by regexp_constructor.
|
// SAFETY: fn_ptr holds a Box<regex::Regex> pointer stored by regexp_constructor.
|
||||||
let regex = unsafe { &*(fn_ptr.as_ptr() as *const regex::Regex) };
|
let regex = unsafe { &*(fn_ptr.as_ptr() as *const regex::Regex) };
|
||||||
let haystack = oxide_runtime_api::to_string(vm.reg(if args.len() > 1 { args[1] } else { args[0] }));
|
let haystack = oxide_runtime_api::to_string(vm.reg(if args.len() > 1 { args[1] } else { args[0] }));
|
||||||
let last_index = oxide_runtime_api::to_number(get_prop(re, 0)) as usize;
|
let last_index = vm.coerce_number_bounded(get_prop(re, 0)).unwrap_or(f64::NAN) as usize;
|
||||||
let is_global = get_prop(re, 3).as_bool();
|
let is_global = get_prop(re, 3).as_bool();
|
||||||
|
|
||||||
if is_global {
|
if is_global {
|
||||||
@@ -181,7 +181,7 @@ pub fn regexp_exec<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
|
|
||||||
let (last_index, is_global) = {
|
let (last_index, is_global) = {
|
||||||
let re = unsafe { &*re_ptr };
|
let re = unsafe { &*re_ptr };
|
||||||
let li = oxide_runtime_api::to_number(get_prop(re, 0)) as usize;
|
let li = vm.coerce_number_bounded(get_prop(re, 0)).unwrap_or(f64::NAN) as usize;
|
||||||
let g = get_prop(re, 3).as_bool();
|
let g = get_prop(re, 3).as_bool();
|
||||||
(li, g)
|
(li, g)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ pub fn string_index_of<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
let search = as_string(vm, vm.reg(args[1]));
|
let search = as_string(vm, vm.reg(args[1]));
|
||||||
let pos = if args.len() > 2 {
|
let pos = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as usize).min(n)
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as usize).min(n)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
@@ -203,7 +203,7 @@ pub fn string_includes<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
let search = as_string(vm, vm.reg(args[1]));
|
let search = as_string(vm, vm.reg(args[1]));
|
||||||
let pos = if args.len() > 2 {
|
let pos = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as usize).min(n)
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as usize).min(n)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
@@ -229,7 +229,7 @@ pub fn string_char_at<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
return NativeResult::Ok(vm.new_string(&take_chars(&s, 1)));
|
return NativeResult::Ok(vm.new_string(&take_chars(&s, 1)));
|
||||||
}
|
}
|
||||||
let idx = oxide_runtime_api::to_number(vm.reg(args[1])) as i32;
|
let idx = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32;
|
||||||
if idx < 0 || idx as usize >= char_len(&s) {
|
if idx < 0 || idx as usize >= char_len(&s) {
|
||||||
return NativeResult::Ok(vm.new_string(""));
|
return NativeResult::Ok(vm.new_string(""));
|
||||||
}
|
}
|
||||||
@@ -246,7 +246,7 @@ pub fn string_char_code_at<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
return NativeResult::Ok(JsValue::int(s.chars().next().unwrap() as i32));
|
return NativeResult::Ok(JsValue::int(s.chars().next().unwrap() as i32));
|
||||||
}
|
}
|
||||||
let idx = oxide_runtime_api::to_number(vm.reg(args[1])) as i32;
|
let idx = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32;
|
||||||
if idx < 0 || idx as usize >= char_len(&s) {
|
if idx < 0 || idx as usize >= char_len(&s) {
|
||||||
return NativeResult::Ok(JsValue::float(f64::NAN));
|
return NativeResult::Ok(JsValue::float(f64::NAN));
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,7 @@ pub fn string_slice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let s = this_string(vm, args);
|
let s = this_string(vm, args);
|
||||||
let n = char_len(&s) as i32;
|
let n = char_len(&s) as i32;
|
||||||
let start = if args.len() > 1 {
|
let start = if args.len() > 1 {
|
||||||
let v = oxide_runtime_api::to_number(vm.reg(args[1])) as i32;
|
let v = vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32;
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
(n + v).max(0)
|
(n + v).max(0)
|
||||||
} else {
|
} else {
|
||||||
@@ -277,7 +277,7 @@ pub fn string_slice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
let end = if args.len() > 2 {
|
let end = if args.len() > 2 {
|
||||||
let v = oxide_runtime_api::to_number(vm.reg(args[2])) as i32;
|
let v = vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as i32;
|
||||||
if v < 0 {
|
if v < 0 {
|
||||||
(n + v).max(0)
|
(n + v).max(0)
|
||||||
} else {
|
} else {
|
||||||
@@ -297,12 +297,16 @@ pub fn string_substring<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let s = this_string(vm, args);
|
let s = this_string(vm, args);
|
||||||
let n = char_len(&s) as i32;
|
let n = char_len(&s) as i32;
|
||||||
let mut start = if args.len() > 1 {
|
let mut start = if args.len() > 1 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[1])) as i32).max(0).min(n)
|
(vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as i32)
|
||||||
|
.max(0)
|
||||||
|
.min(n)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let mut end = if args.len() > 2 {
|
let mut end = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as i32).max(0).min(n)
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as i32)
|
||||||
|
.max(0)
|
||||||
|
.min(n)
|
||||||
} else {
|
} else {
|
||||||
n
|
n
|
||||||
};
|
};
|
||||||
@@ -335,7 +339,7 @@ pub fn string_repeat<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
builtins_debug!("String.prototype.repeat called with {} args", args.len());
|
builtins_debug!("String.prototype.repeat called with {} args", args.len());
|
||||||
let s = this_string(vm, args);
|
let s = this_string(vm, args);
|
||||||
let n = if args.len() > 1 {
|
let n = if args.len() > 1 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[1])) as usize).min(10000)
|
(vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize).min(10000)
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
@@ -347,7 +351,7 @@ pub fn string_pad_start<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let s = this_string(vm, args);
|
let s = this_string(vm, args);
|
||||||
let s_len = char_len(&s);
|
let s_len = char_len(&s);
|
||||||
let target = if args.len() > 1 {
|
let target = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as usize
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
s_len
|
s_len
|
||||||
};
|
};
|
||||||
@@ -372,7 +376,7 @@ pub fn string_pad_end<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
let s = this_string(vm, args);
|
let s = this_string(vm, args);
|
||||||
let s_len = char_len(&s);
|
let s_len = char_len(&s);
|
||||||
let target = if args.len() > 1 {
|
let target = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as usize
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
s_len
|
s_len
|
||||||
};
|
};
|
||||||
@@ -401,7 +405,7 @@ pub fn string_starts_with<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
let search = as_string(vm, vm.reg(args[1]));
|
let search = as_string(vm, vm.reg(args[1]));
|
||||||
let pos = if args.len() > 2 {
|
let pos = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as usize).min(n)
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as usize).min(n)
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
@@ -417,7 +421,7 @@ pub fn string_ends_with<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
let search = as_string(vm, vm.reg(args[1]));
|
let search = as_string(vm, vm.reg(args[1]));
|
||||||
let end_pos = if args.len() > 2 {
|
let end_pos = if args.len() > 2 {
|
||||||
(oxide_runtime_api::to_number(vm.reg(args[2])) as usize).min(n)
|
(vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as usize).min(n)
|
||||||
} else {
|
} else {
|
||||||
n
|
n
|
||||||
};
|
};
|
||||||
@@ -433,7 +437,7 @@ pub fn string_split<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
|||||||
}
|
}
|
||||||
let sep_val = vm.reg(args[1]);
|
let sep_val = vm.reg(args[1]);
|
||||||
let limit = if args.len() > 2 {
|
let limit = if args.len() > 2 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[2])) as usize
|
vm.coerce_number_bounded(vm.reg(args[2])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
usize::MAX
|
usize::MAX
|
||||||
};
|
};
|
||||||
@@ -565,7 +569,7 @@ pub fn string_code_point_at<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult
|
|||||||
builtins_debug!("String.prototype.codePointAt called with {} args", args.len());
|
builtins_debug!("String.prototype.codePointAt called with {} args", args.len());
|
||||||
let s = this_string(vm, args);
|
let s = this_string(vm, args);
|
||||||
let pos = if args.len() > 1 {
|
let pos = if args.len() > 1 {
|
||||||
oxide_runtime_api::to_number(vm.reg(args[1])) as usize
|
vm.coerce_number_bounded(vm.reg(args[1])).unwrap_or(f64::NAN) as usize
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ fn range_error<H: VmHost>(vm: &mut H, msg: &str) -> JsValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn to_index<H: VmHost>(vm: &mut H, value: JsValue, msg: &str) -> Result<usize, JsValue> {
|
fn to_index<H: VmHost>(vm: &mut H, value: JsValue, msg: &str) -> Result<usize, JsValue> {
|
||||||
let n = oxide_runtime_api::to_number(value);
|
let n = vm.coerce_number_bounded(value).unwrap_or(f64::NAN);
|
||||||
if n.is_nan() {
|
if n.is_nan() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
@@ -42,8 +42,8 @@ fn to_index<H: VmHost>(vm: &mut H, value: JsValue, msg: &str) -> Result<usize, J
|
|||||||
Ok(n.trunc() as usize)
|
Ok(n.trunc() as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normalize_index<H: VmHost>(_vm: &mut H, value: JsValue, len: usize) -> usize {
|
fn normalize_index<H: VmHost>(vm: &mut H, value: JsValue, len: usize) -> usize {
|
||||||
let n = oxide_runtime_api::to_number(value);
|
let n = vm.coerce_number_bounded(value).unwrap_or(f64::NAN);
|
||||||
if n.is_nan() {
|
if n.is_nan() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -235,8 +235,8 @@ fn read_element(kind: TypedArrayKind, bytes: &[u8], offset: usize) -> JsValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn numeric_value<H: VmHost>(_vm: &mut H, value: JsValue) -> f64 {
|
fn numeric_value<H: VmHost>(vm: &mut H, value: JsValue) -> f64 {
|
||||||
oxide_runtime_api::to_number(value)
|
vm.coerce_number_bounded(value).unwrap_or(f64::NAN)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_element(kind: TypedArrayKind, bytes: &mut [u8], offset: usize, value: f64) {
|
fn write_element(kind: TypedArrayKind, bytes: &mut [u8], offset: usize, value: f64) {
|
||||||
|
|||||||
Reference in New Issue
Block a user