mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
style: 减少自动格式化换行
This commit is contained in:
@@ -37,20 +37,11 @@ fn get_this_array_ref(val: JsValue) -> Result<*mut JsObject, JsValue> {
|
||||
|
||||
fn create_new_array(vm: &mut Vm, n: usize) -> *mut JsObject {
|
||||
let proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(proto),
|
||||
n,
|
||||
vm.epoch().bump(),
|
||||
))
|
||||
vm.epoch()
|
||||
.alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(proto), n, vm.epoch().bump()))
|
||||
}
|
||||
|
||||
fn invoke_native_callback(
|
||||
vm: &mut Vm,
|
||||
callback_val: JsValue,
|
||||
this_val: JsValue,
|
||||
cb_args: &[JsValue],
|
||||
) -> NativeResult {
|
||||
fn invoke_native_callback(vm: &mut Vm, callback_val: JsValue, this_val: JsValue, cb_args: &[JsValue]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
@@ -85,33 +76,24 @@ pub fn array_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let val = vm.reg(args[1]);
|
||||
if val.is_int() {
|
||||
let n = val.as_int().max(0) as usize;
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
proto_val,
|
||||
n,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
let arr = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, n, vm.epoch().bump()));
|
||||
return Ok(JsValue::from_js_object(arr));
|
||||
}
|
||||
if val.is_double() {
|
||||
let n = val.as_double() as usize;
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
proto_val,
|
||||
n,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
let arr = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, n, vm.epoch().bump()));
|
||||
return Ok(JsValue::from_js_object(arr));
|
||||
}
|
||||
}
|
||||
|
||||
let n_elems = if args.len() > 1 { args.len() - 1 } else { 0 };
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
proto_val,
|
||||
n_elems,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
let arr = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, n_elems, vm.epoch().bump()));
|
||||
for i in 0..n_elems {
|
||||
unsafe {
|
||||
(*arr).set_prop_at(i, vm.reg(args[1 + i]));
|
||||
@@ -359,8 +341,7 @@ pub fn array_flat(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let arr = unsafe { &*arr_ptr };
|
||||
let n = arr.prop_count() as usize;
|
||||
let depth = if args.len() > 1 {
|
||||
(coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as i32).max(1)
|
||||
as usize
|
||||
(coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as i32).max(1) as usize
|
||||
} else {
|
||||
1
|
||||
};
|
||||
@@ -407,19 +388,10 @@ pub fn array_for_each(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
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) };
|
||||
let _ = invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
);
|
||||
let _ = invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]);
|
||||
}
|
||||
Ok(JsValue::undefined())
|
||||
}
|
||||
@@ -433,20 +405,11 @@ pub fn array_map(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() };
|
||||
let new_arr = create_new_array(vm, n);
|
||||
for i in 0..n {
|
||||
let elem = unsafe { (*arr_ptr).get_prop_at(i) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||
Ok(mapped) => unsafe {
|
||||
(*new_arr).set_prop_at(i, mapped);
|
||||
},
|
||||
@@ -468,20 +431,11 @@ pub fn array_filter(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() };
|
||||
let mut kept: Vec<JsValue> = Vec::new();
|
||||
for i in 0..n {
|
||||
let elem = unsafe { (*arr_ptr).get_prop_at(i) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||
Ok(result_val) => {
|
||||
let sf = vm.kernel().string_forge().as_ref();
|
||||
if coercion::to_boolean(result_val, sf) {
|
||||
@@ -548,19 +502,10 @@ pub fn array_find(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Ok(JsValue::undefined());
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
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) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||
Ok(result_val) => {
|
||||
let sf = vm.kernel().string_forge().as_ref();
|
||||
if coercion::to_boolean(result_val, sf) {
|
||||
@@ -582,19 +527,10 @@ pub fn array_some(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Ok(JsValue::bool(false));
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
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) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||
Ok(result_val) => {
|
||||
let sf = vm.kernel().string_forge().as_ref();
|
||||
if coercion::to_boolean(result_val, sf) {
|
||||
@@ -616,19 +552,10 @@ pub fn array_every(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Ok(JsValue::bool(false));
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
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) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||
Ok(result_val) => {
|
||||
let sf = vm.kernel().string_forge().as_ref();
|
||||
if !coercion::to_boolean(result_val, sf) {
|
||||
@@ -650,20 +577,11 @@ pub fn array_flat_map(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !callback_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let this_val = if args.len() > 2 {
|
||||
vm.reg(args[2])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() };
|
||||
let mut flat: Vec<JsValue> = Vec::new();
|
||||
for i in 0..n {
|
||||
let elem = unsafe { (*arr_ptr).get_prop_at(i) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) {
|
||||
Ok(result) => {
|
||||
if result.is_object() {
|
||||
let r_ptr = result.as_js_object_ptr();
|
||||
@@ -730,14 +648,9 @@ pub fn array_fill(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let arr_ptr = array_ptr!(vm, args);
|
||||
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 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
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as i32).max(0) as usize
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@@ -771,8 +684,7 @@ pub fn array_copy_within(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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)
|
||||
(coercion::to_number(vm.reg(args[3]), vm.kernel().string_forge().as_ref()) as i32 as usize).min(len)
|
||||
} else {
|
||||
len
|
||||
};
|
||||
@@ -810,11 +722,7 @@ pub fn array_last_index_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let arr_ptr = array_ptr!(vm, args);
|
||||
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()
|
||||
};
|
||||
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), search) {
|
||||
return Ok(JsValue::int(i));
|
||||
@@ -829,19 +737,10 @@ pub fn array_find_index(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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()
|
||||
};
|
||||
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) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i as i32), vm.reg(args[0])],
|
||||
) {
|
||||
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));
|
||||
@@ -862,19 +761,10 @@ pub fn array_find_last(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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()
|
||||
};
|
||||
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) };
|
||||
match invoke_native_callback(
|
||||
vm,
|
||||
callback_val,
|
||||
this_val,
|
||||
&[elem, JsValue::int(i), vm.reg(args[0])],
|
||||
) {
|
||||
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);
|
||||
|
||||
@@ -13,11 +13,7 @@ pub fn boolean_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
} else if arg.is_bool() {
|
||||
arg.as_bool()
|
||||
} else if arg.is_string() {
|
||||
let s = vm
|
||||
.kernel()
|
||||
.string_forge()
|
||||
.lookup(arg.as_string_index())
|
||||
.unwrap_or_default();
|
||||
let s = vm.kernel().string_forge().lookup(arg.as_string_index()).unwrap_or_default();
|
||||
!s.is_empty()
|
||||
} else if arg.is_object() {
|
||||
true
|
||||
|
||||
@@ -30,10 +30,7 @@ fn is_date(vm: &Vm, obj: &JsObject) -> bool {
|
||||
|
||||
fn ensure_date(vm: &mut Vm, obj: &JsObject) -> NativeResult {
|
||||
if !is_date(vm, obj) {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
Ok(JsValue::undefined())
|
||||
}
|
||||
@@ -114,11 +111,7 @@ pub fn date_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
} else {
|
||||
let val = vm.reg(args[1]);
|
||||
if val.is_string() {
|
||||
let s = vm
|
||||
.kernel()
|
||||
.string_forge()
|
||||
.lookup(val.as_string_index())
|
||||
.unwrap_or_default();
|
||||
let s = vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default();
|
||||
let formats = ["%Y-%m-%dT%H:%M:%S%.fZ", "%Y-%m-%dT%H:%M:%S%.f"];
|
||||
let mut ts = f64::NAN;
|
||||
for fmt in &formats {
|
||||
@@ -129,10 +122,7 @@ pub fn date_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
if ts.is_nan() {
|
||||
if let Ok(nd) = NaiveDate::parse_from_str(&s, "%Y-%m-%d") {
|
||||
if let Some(ndt) = nd
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.and_then(|n| n.and_local_timezone(Utc).earliest())
|
||||
{
|
||||
if let Some(ndt) = nd.and_hms_opt(0, 0, 0).and_then(|n| n.and_local_timezone(Utc).earliest()) {
|
||||
ts = ndt.timestamp_millis() as f64;
|
||||
}
|
||||
}
|
||||
@@ -192,11 +182,7 @@ pub fn date_parse(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !val.is_string() {
|
||||
return Ok(JsValue::float(f64::NAN));
|
||||
}
|
||||
let s = vm
|
||||
.kernel()
|
||||
.string_forge()
|
||||
.lookup(val.as_string_index())
|
||||
.unwrap_or_default();
|
||||
let s = vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default();
|
||||
let formats = ["%Y-%m-%dT%H:%M:%S%.fZ", "%Y-%m-%dT%H:%M:%S%.f"];
|
||||
let mut ts = f64::NAN;
|
||||
for fmt in &formats {
|
||||
@@ -207,10 +193,7 @@ pub fn date_parse(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
if ts.is_nan() {
|
||||
if let Ok(nd) = NaiveDate::parse_from_str(&s, "%Y-%m-%d") {
|
||||
if let Some(ndt) = nd
|
||||
.and_hms_opt(0, 0, 0)
|
||||
.and_then(|n| n.and_local_timezone(Utc).earliest())
|
||||
{
|
||||
if let Some(ndt) = nd.and_hms_opt(0, 0, 0).and_then(|n| n.and_local_timezone(Utc).earliest()) {
|
||||
ts = ndt.timestamp_millis() as f64;
|
||||
}
|
||||
}
|
||||
@@ -227,10 +210,7 @@ macro_rules! make_getter {
|
||||
pub fn $name(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &*raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
@@ -251,10 +231,7 @@ macro_rules! make_utc_getter {
|
||||
pub fn $name(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &*raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
@@ -270,83 +247,27 @@ macro_rules! make_utc_getter {
|
||||
};
|
||||
}
|
||||
|
||||
make_getter!(
|
||||
date_get_time,
|
||||
|dt: DateTime<Utc>| dt.timestamp_millis() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(
|
||||
date_get_full_year,
|
||||
|dt: DateTime<Utc>| dt.year() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(
|
||||
date_get_month,
|
||||
|dt: DateTime<Utc>| dt.month0() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(date_get_time, |dt: DateTime<Utc>| dt.timestamp_millis() as f64, f64::NAN);
|
||||
make_getter!(date_get_full_year, |dt: DateTime<Utc>| dt.year() as f64, f64::NAN);
|
||||
make_getter!(date_get_month, |dt: DateTime<Utc>| dt.month0() as f64, f64::NAN);
|
||||
make_getter!(date_get_date, |dt: DateTime<Utc>| dt.day() as f64, f64::NAN);
|
||||
make_getter!(
|
||||
date_get_day,
|
||||
|dt: DateTime<Utc>| dt.weekday().num_days_from_sunday() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(
|
||||
date_get_hours,
|
||||
|dt: DateTime<Utc>| dt.hour() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(
|
||||
date_get_minutes,
|
||||
|dt: DateTime<Utc>| dt.minute() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(
|
||||
date_get_seconds,
|
||||
|dt: DateTime<Utc>| dt.second() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(
|
||||
date_get_milliseconds,
|
||||
|dt: DateTime<Utc>| dt.timestamp_subsec_millis() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_getter!(date_get_day, |dt: DateTime<Utc>| dt.weekday().num_days_from_sunday() as f64, f64::NAN);
|
||||
make_getter!(date_get_hours, |dt: DateTime<Utc>| dt.hour() as f64, f64::NAN);
|
||||
make_getter!(date_get_minutes, |dt: DateTime<Utc>| dt.minute() as f64, f64::NAN);
|
||||
make_getter!(date_get_seconds, |dt: DateTime<Utc>| dt.second() as f64, f64::NAN);
|
||||
make_getter!(date_get_milliseconds, |dt: DateTime<Utc>| dt.timestamp_subsec_millis() as f64, f64::NAN);
|
||||
|
||||
make_utc_getter!(
|
||||
date_get_utc_full_year,
|
||||
|ndt: NaiveDateTime| ndt.date().year() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(
|
||||
date_get_utc_month,
|
||||
|ndt: NaiveDateTime| ndt.date().month0() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(
|
||||
date_get_utc_date,
|
||||
|ndt: NaiveDateTime| ndt.date().day() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(date_get_utc_full_year, |ndt: NaiveDateTime| ndt.date().year() as f64, f64::NAN);
|
||||
make_utc_getter!(date_get_utc_month, |ndt: NaiveDateTime| ndt.date().month0() as f64, f64::NAN);
|
||||
make_utc_getter!(date_get_utc_date, |ndt: NaiveDateTime| ndt.date().day() as f64, f64::NAN);
|
||||
make_utc_getter!(
|
||||
date_get_utc_day,
|
||||
|ndt: NaiveDateTime| ndt.date().weekday().num_days_from_sunday() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(
|
||||
date_get_utc_hours,
|
||||
|ndt: NaiveDateTime| ndt.time().hour() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(
|
||||
date_get_utc_minutes,
|
||||
|ndt: NaiveDateTime| ndt.time().minute() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(
|
||||
date_get_utc_seconds,
|
||||
|ndt: NaiveDateTime| ndt.time().second() as f64,
|
||||
f64::NAN
|
||||
);
|
||||
make_utc_getter!(date_get_utc_hours, |ndt: NaiveDateTime| ndt.time().hour() as f64, f64::NAN);
|
||||
make_utc_getter!(date_get_utc_minutes, |ndt: NaiveDateTime| ndt.time().minute() as f64, f64::NAN);
|
||||
make_utc_getter!(date_get_utc_seconds, |ndt: NaiveDateTime| ndt.time().second() as f64, f64::NAN);
|
||||
make_utc_getter!(
|
||||
date_get_utc_milliseconds,
|
||||
|ndt: NaiveDateTime| ndt.time().nanosecond() as f64 / 1_000_000.0,
|
||||
@@ -356,10 +277,7 @@ make_utc_getter!(
|
||||
pub fn date_get_timezone_offset(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &*raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
@@ -382,10 +300,7 @@ fn get_opt_arg(vm: &Vm, args: &[u8], idx: usize, default: u32) -> u32 {
|
||||
pub fn date_set_time(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &mut *raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
@@ -438,10 +353,7 @@ pub fn date_set_month(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
None => return Ok(JsValue::float(f64::NAN)),
|
||||
};
|
||||
let d = get_opt_arg(vm, args, 2, dt.day0());
|
||||
let nd = dt
|
||||
.with_month0(v as u32)
|
||||
.and_then(|x| x.with_day0(d))
|
||||
.unwrap_or(dt);
|
||||
let nd = dt.with_month0(v as u32).and_then(|x| x.with_day0(d)).unwrap_or(dt);
|
||||
let ts = nd.timestamp_millis() as f64;
|
||||
set_timestamp(obj, ts);
|
||||
Ok(JsValue::float(ts))
|
||||
@@ -563,10 +475,7 @@ pub fn date_set_milliseconds(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
fn date_to_string_inner(vm: &mut Vm, args: &[u8], format_str: &str, invalid: &str) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &*raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
@@ -588,10 +497,7 @@ pub fn date_to_iso_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
pub fn date_to_json(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &*raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
@@ -625,10 +531,7 @@ pub fn date_to_utc_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
pub fn date_value_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let raw = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
if !raw.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on incompatible receiver",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver"));
|
||||
}
|
||||
let obj = unsafe { &*raw.as_js_object_ptr() };
|
||||
ensure_date(vm, obj)?;
|
||||
|
||||
@@ -9,16 +9,10 @@ use crate::coercion;
|
||||
use crate::native::NativeResult;
|
||||
use crate::vm::Vm;
|
||||
|
||||
fn create_error_object(
|
||||
vm: &mut Vm,
|
||||
error_proto_ptr: *mut JsObject,
|
||||
name: &str,
|
||||
message: &str,
|
||||
) -> JsValue {
|
||||
let obj = vm.epoch().alloc(JsObject::new_empty(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(error_proto_ptr),
|
||||
));
|
||||
fn create_error_object(vm: &mut Vm, error_proto_ptr: *mut JsObject, name: &str, message: &str) -> JsValue {
|
||||
let obj = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(error_proto_ptr)));
|
||||
|
||||
let sf = Arc::clone(vm.kernel().string_forge());
|
||||
let sh = Arc::clone(vm.kernel().shape_forge());
|
||||
@@ -132,18 +126,13 @@ pub fn error_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
.map(|b| **b)
|
||||
.unwrap_or(JsValue::undefined());
|
||||
(
|
||||
vm.lookup_str(name_val)
|
||||
.unwrap_or_else(|| "Error".to_string()),
|
||||
vm.lookup_str(name_val).unwrap_or_else(|| "Error".to_string()),
|
||||
vm.lookup_str(msg_val).unwrap_or_default(),
|
||||
)
|
||||
} else {
|
||||
("Error".to_string(), String::new())
|
||||
};
|
||||
let result = if msg.is_empty() {
|
||||
name
|
||||
} else {
|
||||
format!("{}: {}", name, msg)
|
||||
};
|
||||
let result = if msg.is_empty() { name } else { format!("{}: {}", name, msg) };
|
||||
let si = vm.kernel().string_forge().intern(&result).0;
|
||||
Ok(JsValue::string(si, 0))
|
||||
}
|
||||
@@ -184,14 +173,7 @@ mod tests {
|
||||
});
|
||||
|
||||
let stack = error_stack_getter(&mut vm, &[0]).unwrap();
|
||||
let stack_str = vm
|
||||
.kernel()
|
||||
.string_forge()
|
||||
.lookup(stack.as_string_index())
|
||||
.unwrap_or_default();
|
||||
assert!(
|
||||
stack_str.contains("foo"),
|
||||
"expected function name in stack: {stack_str}"
|
||||
);
|
||||
let stack_str = vm.kernel().string_forge().lookup(stack.as_string_index()).unwrap_or_default();
|
||||
assert!(stack_str.contains("foo"), "expected function name in stack: {stack_str}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,7 @@ use oxide_types::value::JsValue;
|
||||
use crate::native::{NativeFn, NativeResult};
|
||||
use crate::vm::Vm;
|
||||
|
||||
fn invoke_target(
|
||||
vm: &mut Vm,
|
||||
target_val: JsValue,
|
||||
this_val: JsValue,
|
||||
arg_regs: &[u8],
|
||||
) -> NativeResult {
|
||||
fn invoke_target(vm: &mut Vm, target_val: JsValue, this_val: JsValue, arg_regs: &[u8]) -> NativeResult {
|
||||
if !target_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
@@ -79,11 +74,7 @@ pub fn function_call(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let target_val = vm.reg(args[0]);
|
||||
let this_val = if args.len() > 1 {
|
||||
vm.reg(args[1])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
let this_val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
let arg_regs: Vec<u8> = args.iter().skip(2).copied().collect();
|
||||
invoke_target(vm, target_val, this_val, &arg_regs)
|
||||
}
|
||||
@@ -93,11 +84,7 @@ pub fn function_apply(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let target_val = vm.reg(args[0]);
|
||||
let this_val = if args.len() > 1 {
|
||||
vm.reg(args[1])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
let this_val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
|
||||
let arg_regs: Vec<u8>;
|
||||
if args.len() > 2 {
|
||||
@@ -139,15 +126,9 @@ pub fn function_bind(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !target_val.is_object() {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let bound_this = if args.len() > 1 {
|
||||
vm.reg(args[1])
|
||||
} else {
|
||||
JsValue::undefined()
|
||||
};
|
||||
let bound_this = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
|
||||
let wrapper = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
|
||||
let wrapper = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
|
||||
unsafe {
|
||||
(*wrapper).set_function(true);
|
||||
(*wrapper).set_native_fn(Some(bind_dispatcher as *const ()));
|
||||
@@ -189,20 +170,13 @@ pub fn function_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
.unwrap_or_else(|| {
|
||||
let sub_idx = func.sub_module_index();
|
||||
if sub_idx > 0 && (sub_idx as usize) <= vm.sub_modules.len() {
|
||||
vm.sub_modules[sub_idx as usize - 1]
|
||||
.function_name
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
vm.sub_modules[sub_idx as usize - 1].function_name.clone().unwrap_or_default()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
});
|
||||
|
||||
let body = if func.native_fn().is_some() {
|
||||
"[native code]"
|
||||
} else {
|
||||
"[bytecode]"
|
||||
};
|
||||
let body = if func.native_fn().is_some() { "[native code]" } else { "[bytecode]" };
|
||||
let result = if name.is_empty() {
|
||||
format!("function () {{ {body} }}")
|
||||
} else {
|
||||
|
||||
@@ -2,9 +2,6 @@ use std::sync::Arc;
|
||||
|
||||
use oxide_kernel::kernel::OxideKernel;
|
||||
|
||||
pub fn register_global_properties(
|
||||
_kernel: &Arc<OxideKernel>,
|
||||
_bump: &bumpalo::Bump,
|
||||
) -> Result<(), String> {
|
||||
pub fn register_global_properties(_kernel: &Arc<OxideKernel>, _bump: &bumpalo::Bump) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -11,25 +11,19 @@ use crate::vm::Vm;
|
||||
|
||||
pub fn json_parse(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if args.len() < 2 {
|
||||
return Err(crate::builtins::error::create_syntax_error(
|
||||
vm,
|
||||
"JSON.parse requires 1 argument",
|
||||
));
|
||||
return Err(crate::builtins::error::create_syntax_error(vm, "JSON.parse requires 1 argument"));
|
||||
}
|
||||
let val = vm.reg(args[1]);
|
||||
if !val.is_string() {
|
||||
return Err(crate::builtins::error::create_syntax_error(
|
||||
vm,
|
||||
"JSON.parse: argument is not a string",
|
||||
));
|
||||
return Err(crate::builtins::error::create_syntax_error(vm, "JSON.parse: argument is not a string"));
|
||||
}
|
||||
let text = {
|
||||
let si = val.as_string_index();
|
||||
vm.kernel().string_forge().lookup(si).unwrap_or_default()
|
||||
};
|
||||
|
||||
let parsed: serde_json::Value = serde_json::from_str(&text)
|
||||
.map_err(|e| crate::builtins::error::create_syntax_error(vm, &format!("{}", e)))?;
|
||||
let parsed: serde_json::Value =
|
||||
serde_json::from_str(&text).map_err(|e| crate::builtins::error::create_syntax_error(vm, &format!("{}", e)))?;
|
||||
|
||||
Ok(value_to_jsvalue(vm, &parsed))
|
||||
}
|
||||
@@ -65,8 +59,7 @@ fn value_to_jsvalue(vm: &mut Vm, val: &serde_json::Value) -> JsValue {
|
||||
}
|
||||
serde_json::Value::Object(map) => {
|
||||
let object_proto = vm.kernel().builtin_world().object_proto.as_ptr() as *mut JsObject;
|
||||
let mut obj =
|
||||
JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto));
|
||||
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto));
|
||||
for (key, val) in map {
|
||||
let si = vm.kernel().string_forge().intern(key).0;
|
||||
let jsv = value_to_jsvalue(vm, val);
|
||||
@@ -95,12 +88,7 @@ pub fn json_stringify(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
Ok(vm.intern(&output))
|
||||
}
|
||||
|
||||
fn jsvalue_to_json(
|
||||
vm: &Vm,
|
||||
val: JsValue,
|
||||
visited: &mut HashSet<*const u8>,
|
||||
out: &mut String,
|
||||
) -> Result<(), ()> {
|
||||
fn jsvalue_to_json(vm: &Vm, val: JsValue, visited: &mut HashSet<*const u8>, out: &mut String) -> Result<(), ()> {
|
||||
if val.is_null() {
|
||||
out.push_str("null");
|
||||
} else if val.is_undefined() {
|
||||
@@ -169,12 +157,7 @@ fn stringify_string(s: &str, out: &mut String) {
|
||||
out.push('"');
|
||||
}
|
||||
|
||||
fn stringify_object(
|
||||
vm: &Vm,
|
||||
obj: &JsObject,
|
||||
visited: &mut HashSet<*const u8>,
|
||||
out: &mut String,
|
||||
) -> Result<(), ()> {
|
||||
fn stringify_object(vm: &Vm, obj: &JsObject, visited: &mut HashSet<*const u8>, out: &mut String) -> Result<(), ()> {
|
||||
out.push('{');
|
||||
let keys = walk_own_keys(vm, obj);
|
||||
let mut first = true;
|
||||
@@ -204,12 +187,7 @@ fn stringify_object(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stringify_array(
|
||||
vm: &Vm,
|
||||
obj: &JsObject,
|
||||
visited: &mut HashSet<*const u8>,
|
||||
out: &mut String,
|
||||
) -> Result<(), ()> {
|
||||
fn stringify_array(vm: &Vm, obj: &JsObject, visited: &mut HashSet<*const u8>, out: &mut String) -> Result<(), ()> {
|
||||
out.push('[');
|
||||
let len = obj.prop_vec_len();
|
||||
for i in 0..len {
|
||||
|
||||
@@ -8,37 +8,22 @@ use crate::vm::Vm;
|
||||
|
||||
const MAP_PROP_INDEX: u8 = 0;
|
||||
|
||||
fn get_map_inner(
|
||||
vm: &mut Vm,
|
||||
this_val: JsValue,
|
||||
) -> Result<*mut indexmap::IndexMap<SetKey, JsValue>, JsValue> {
|
||||
fn get_map_inner(vm: &mut Vm, this_val: JsValue) -> Result<*mut indexmap::IndexMap<SetKey, JsValue>, JsValue> {
|
||||
if !this_val.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on non-Map object",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on non-Map object"));
|
||||
}
|
||||
let map_ptr = this_val.as_js_object_ptr();
|
||||
if map_ptr.is_null() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"Map internal state invalid",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "Map internal state invalid"));
|
||||
}
|
||||
let map_obj = unsafe { &*map_ptr };
|
||||
let inner_val = map_obj.get_prop_at(MAP_PROP_INDEX);
|
||||
if !inner_val.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"Map internal state invalid",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "Map internal state invalid"));
|
||||
}
|
||||
let inner_ptr = inner_val.as_js_object_ptr() as *mut indexmap::IndexMap<SetKey, JsValue>;
|
||||
if inner_ptr.is_null() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"Map internal state invalid",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "Map internal state invalid"));
|
||||
}
|
||||
Ok(inner_ptr)
|
||||
}
|
||||
|
||||
@@ -18,16 +18,8 @@ fn arg1(vm: &Vm, args: &[u8]) -> f64 {
|
||||
|
||||
fn arg2(vm: &Vm, args: &[u8]) -> (f64, f64) {
|
||||
(
|
||||
if args.len() > 1 {
|
||||
num(vm, args[1])
|
||||
} else {
|
||||
f64::NAN
|
||||
},
|
||||
if args.len() > 2 {
|
||||
num(vm, args[2])
|
||||
} else {
|
||||
f64::NAN
|
||||
},
|
||||
if args.len() > 1 { num(vm, args[1]) } else { f64::NAN },
|
||||
if args.len() > 2 { num(vm, args[2]) } else { f64::NAN },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -82,11 +74,7 @@ pub fn math_atan2(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
pub fn math_round(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let x = arg1(vm, args);
|
||||
let r = if x < 0.0 {
|
||||
(x - 0.5).ceil()
|
||||
} else {
|
||||
(x + 0.5).floor()
|
||||
};
|
||||
let r = if x < 0.0 { (x - 0.5).ceil() } else { (x + 0.5).floor() };
|
||||
Ok(JsValue::float(r))
|
||||
}
|
||||
|
||||
|
||||
@@ -177,10 +177,7 @@ pub fn number_is_integer(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
pub fn number_is_safe_integer(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let val = vm.reg(if args.len() > 1 { args[1] } else { args[0] });
|
||||
let n = coercion::to_number(val, vm.kernel().string_forge().as_ref());
|
||||
let safe = n.trunc() == n
|
||||
&& n.is_finite()
|
||||
&& n >= -9007199254740991i64 as f64
|
||||
&& n <= 9007199254740991i64 as f64;
|
||||
let safe = n.trunc() == n && n.is_finite() && n >= -9007199254740991i64 as f64 && n <= 9007199254740991i64 as f64;
|
||||
Ok(JsValue::bool(safe))
|
||||
}
|
||||
|
||||
@@ -196,11 +193,7 @@ pub fn number_to_exponential(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
return Ok(vm.intern("NaN"));
|
||||
}
|
||||
if n.is_infinite() {
|
||||
return Ok(vm.intern(if n.is_sign_positive() {
|
||||
"Infinity"
|
||||
} else {
|
||||
"-Infinity"
|
||||
}));
|
||||
return Ok(vm.intern(if n.is_sign_positive() { "Infinity" } else { "-Infinity" }));
|
||||
}
|
||||
let formatted = format!("{:.digits$e}", n);
|
||||
Ok(vm.intern(&formatted))
|
||||
@@ -218,11 +211,7 @@ pub fn number_to_precision(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
return Ok(vm.intern("NaN"));
|
||||
}
|
||||
if n.is_infinite() {
|
||||
return Ok(vm.intern(if n.is_sign_positive() {
|
||||
"Infinity"
|
||||
} else {
|
||||
"-Infinity"
|
||||
}));
|
||||
return Ok(vm.intern(if n.is_sign_positive() { "Infinity" } else { "-Infinity" }));
|
||||
}
|
||||
let formatted = format!("{:.precision$}", n);
|
||||
Ok(vm.intern(&formatted))
|
||||
|
||||
@@ -38,9 +38,7 @@ pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u32)> {
|
||||
}
|
||||
|
||||
pub fn object_constructor(vm: &mut Vm, _args: &[u8]) -> NativeResult {
|
||||
let obj = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
|
||||
let obj = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
|
||||
Ok(JsValue::from_js_object(obj))
|
||||
}
|
||||
|
||||
@@ -95,9 +93,7 @@ pub fn object_create(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if !proto_val.is_null() && !proto_val.is_object() {
|
||||
return Ok(JsValue::undefined());
|
||||
}
|
||||
let obj = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_val));
|
||||
let obj = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_val));
|
||||
Ok(JsValue::from_js_object(obj))
|
||||
}
|
||||
|
||||
@@ -210,10 +206,9 @@ pub fn object_get_own_property_descriptor(vm: &mut Vm, args: &[u8]) -> NativeRes
|
||||
let sf_ptr = vm.kernel().string_forge().as_ref() as *const StringForge;
|
||||
let sh_ptr = vm.kernel().shape_forge().as_ref() as *const ShapeForge;
|
||||
let desc_proto = vm.kernel().builtin_world().object_proto.as_ptr() as *mut JsObject;
|
||||
let desc = vm.epoch().alloc(JsObject::new_empty(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(desc_proto),
|
||||
));
|
||||
let desc = vm
|
||||
.epoch()
|
||||
.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(desc_proto)));
|
||||
let true_val = JsValue::bool(true);
|
||||
let sf = unsafe { &*sf_ptr };
|
||||
let sh = unsafe { &*sh_ptr };
|
||||
|
||||
@@ -19,13 +19,7 @@ fn get_regexp_ptr(vm: &Vm, args: &[u8]) -> Result<*mut JsObject, JsValue> {
|
||||
}
|
||||
let ptr = this_val.as_js_object_ptr();
|
||||
if ptr.is_null() {
|
||||
return Err(JsValue::string(
|
||||
vm.kernel()
|
||||
.string_forge()
|
||||
.intern("TypeError: null object")
|
||||
.0,
|
||||
0,
|
||||
));
|
||||
return Err(JsValue::string(vm.kernel().string_forge().intern("TypeError: null object").0, 0));
|
||||
}
|
||||
Ok(ptr)
|
||||
}
|
||||
@@ -101,10 +95,7 @@ pub fn regexp_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
Err(e) => {
|
||||
let msg = format!("SyntaxError: Invalid regular expression: {}", e);
|
||||
return Err(JsValue::string(
|
||||
vm.kernel().string_forge().intern(&msg).0,
|
||||
0,
|
||||
));
|
||||
return Err(JsValue::string(vm.kernel().string_forge().intern(&msg).0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,13 +119,7 @@ pub fn regexp_test(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
let fn_ptr = match re.native_fn() {
|
||||
None => {
|
||||
return Err(JsValue::string(
|
||||
vm.kernel()
|
||||
.string_forge()
|
||||
.intern("TypeError: invalid RegExp")
|
||||
.0,
|
||||
0,
|
||||
));
|
||||
return Err(JsValue::string(vm.kernel().string_forge().intern("TypeError: invalid RegExp").0, 0));
|
||||
}
|
||||
Some(p) => p,
|
||||
};
|
||||
@@ -144,8 +129,7 @@ pub fn regexp_test(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
vm.kernel().string_forge().as_ref(),
|
||||
vm.reg(if args.len() > 1 { args[1] } else { args[0] }),
|
||||
);
|
||||
let last_index =
|
||||
coercion::to_number(get_prop(re, 0), vm.kernel().string_forge().as_ref()) as usize;
|
||||
let last_index = coercion::to_number(get_prop(re, 0), vm.kernel().string_forge().as_ref()) as usize;
|
||||
let is_global = get_prop(re, 3).as_bool();
|
||||
|
||||
if is_global {
|
||||
@@ -163,13 +147,7 @@ pub fn regexp_exec(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let re = unsafe { &*re_ptr };
|
||||
match re.native_fn() {
|
||||
None => {
|
||||
return Err(JsValue::string(
|
||||
vm.kernel()
|
||||
.string_forge()
|
||||
.intern("TypeError: invalid RegExp")
|
||||
.0,
|
||||
0,
|
||||
));
|
||||
return Err(JsValue::string(vm.kernel().string_forge().intern("TypeError: invalid RegExp").0, 0));
|
||||
}
|
||||
Some(p) => p,
|
||||
}
|
||||
@@ -200,25 +178,19 @@ pub fn regexp_exec(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if let Some(m) = match_result {
|
||||
let mut match_obj = JsObject::new_empty(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(
|
||||
vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject
|
||||
),
|
||||
JsValue::from_js_object(vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject),
|
||||
);
|
||||
|
||||
let full_match = &haystack[m.start()..m.end()];
|
||||
let full_si = vm.kernel().string_forge().intern(full_match).0;
|
||||
match_obj
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::string(full_si, 0)));
|
||||
match_obj.ensure_hash_props().push(Box::new(JsValue::string(full_si, 0)));
|
||||
|
||||
let captures = regex.captures(&haystack[m.start()..m.end()]);
|
||||
if let Some(caps) = &captures {
|
||||
for i in 1..caps.len() {
|
||||
let cap_str = caps.get(i).map(|cm| cm.as_str()).unwrap_or("");
|
||||
let si = vm.kernel().string_forge().intern(cap_str).0;
|
||||
match_obj
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::string(si, 0)));
|
||||
match_obj.ensure_hash_props().push(Box::new(JsValue::string(si, 0)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,7 @@ impl PartialEq for SetKey {
|
||||
}
|
||||
return a == b;
|
||||
}
|
||||
unsafe {
|
||||
std::mem::transmute::<JsValue, u64>(self.0)
|
||||
== std::mem::transmute::<JsValue, u64>(other.0)
|
||||
}
|
||||
unsafe { std::mem::transmute::<JsValue, u64>(self.0) == std::mem::transmute::<JsValue, u64>(other.0) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,37 +48,22 @@ impl Hash for SetKey {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_set_inner(
|
||||
vm: &mut Vm,
|
||||
this_val: JsValue,
|
||||
) -> Result<*mut indexmap::IndexSet<SetKey>, JsValue> {
|
||||
fn get_set_inner(vm: &mut Vm, this_val: JsValue) -> Result<*mut indexmap::IndexSet<SetKey>, JsValue> {
|
||||
if !this_val.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"called on non-Set object",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "called on non-Set object"));
|
||||
}
|
||||
let set_ptr = this_val.as_js_object_ptr();
|
||||
if set_ptr.is_null() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"Set internal state invalid",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "Set internal state invalid"));
|
||||
}
|
||||
let set_obj = unsafe { &*set_ptr };
|
||||
let inner_val = set_obj.get_prop_at(SET_PROP_INDEX);
|
||||
if !inner_val.is_object() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"Set internal state invalid",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "Set internal state invalid"));
|
||||
}
|
||||
let inner_ptr = inner_val.as_js_object_ptr() as *mut indexmap::IndexSet<SetKey>;
|
||||
if inner_ptr.is_null() {
|
||||
return Err(crate::builtins::error::create_type_error(
|
||||
vm,
|
||||
"Set internal state invalid",
|
||||
));
|
||||
return Err(crate::builtins::error::create_type_error(vm, "Set internal state invalid"));
|
||||
}
|
||||
Ok(inner_ptr)
|
||||
}
|
||||
|
||||
@@ -14,12 +14,9 @@ fn this_string(vm: &Vm, args: &[u8]) -> String {
|
||||
fn make_string_array(vm: &mut Vm, parts: &[String]) -> JsValue {
|
||||
let proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let n = parts.len();
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(proto),
|
||||
n,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
let arr =
|
||||
vm.epoch()
|
||||
.alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(proto), n, vm.epoch().bump()));
|
||||
unsafe {
|
||||
for (i, s) in parts.iter().enumerate() {
|
||||
let sv = vm.intern(s);
|
||||
@@ -62,8 +59,7 @@ pub fn string_index_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
let search = as_string(vm, vm.reg(args[1]));
|
||||
let pos = if args.len() > 2 {
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize)
|
||||
.min(s.len())
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len())
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@@ -90,8 +86,7 @@ pub fn string_includes(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
let search = as_string(vm, vm.reg(args[1]));
|
||||
let pos = if args.len() > 2 {
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize)
|
||||
.min(s.len())
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len())
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@@ -102,9 +97,7 @@ pub fn string_includes(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
let haystack = &s.as_bytes()[pos..];
|
||||
if search.len() == 1 {
|
||||
Ok(JsValue::bool(
|
||||
memchr(search.as_bytes()[0], haystack).is_some(),
|
||||
))
|
||||
Ok(JsValue::bool(memchr(search.as_bytes()[0], haystack).is_some()))
|
||||
} else {
|
||||
Ok(JsValue::bool(s[pos..].contains(&search)))
|
||||
}
|
||||
@@ -221,8 +214,7 @@ pub fn string_trim(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
pub fn string_repeat(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let s = this_string(vm, args);
|
||||
let n = if args.len() > 1 {
|
||||
(coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize)
|
||||
.min(10000)
|
||||
(coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize).min(10000)
|
||||
} else {
|
||||
1
|
||||
};
|
||||
@@ -236,11 +228,7 @@ pub fn string_pad_start(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
} else {
|
||||
s.len()
|
||||
};
|
||||
let pad = if args.len() > 2 {
|
||||
as_string(vm, vm.reg(args[2]))
|
||||
} else {
|
||||
" ".to_string()
|
||||
};
|
||||
let pad = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { " ".to_string() };
|
||||
if s.len() >= target || pad.is_empty() {
|
||||
return Ok(vm.intern(&s));
|
||||
}
|
||||
@@ -259,11 +247,7 @@ pub fn string_pad_end(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
} else {
|
||||
s.len()
|
||||
};
|
||||
let pad = if args.len() > 2 {
|
||||
as_string(vm, vm.reg(args[2]))
|
||||
} else {
|
||||
" ".to_string()
|
||||
};
|
||||
let pad = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { " ".to_string() };
|
||||
if s.len() >= target || pad.is_empty() {
|
||||
return Ok(vm.intern(&s));
|
||||
}
|
||||
@@ -282,8 +266,7 @@ pub fn string_starts_with(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
let search = as_string(vm, vm.reg(args[1]));
|
||||
let pos = if args.len() > 2 {
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize)
|
||||
.min(s.len())
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len())
|
||||
} else {
|
||||
0
|
||||
};
|
||||
@@ -297,8 +280,7 @@ pub fn string_ends_with(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
let search = as_string(vm, vm.reg(args[1]));
|
||||
let end_pos = if args.len() > 2 {
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize)
|
||||
.min(s.len())
|
||||
(coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len())
|
||||
} else {
|
||||
s.len()
|
||||
};
|
||||
@@ -349,11 +331,7 @@ pub fn string_replace(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
return Ok(vm.intern(&s));
|
||||
}
|
||||
let pattern_val = vm.reg(args[1]);
|
||||
let replacement = if args.len() > 2 {
|
||||
as_string(vm, vm.reg(args[2]))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let replacement = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { String::new() };
|
||||
|
||||
if is_regexp_obj(pattern_val, vm) {
|
||||
let re_ptr = pattern_val.as_js_object_ptr();
|
||||
@@ -387,19 +365,13 @@ pub fn string_match_fn(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
None => return Ok(JsValue::undefined()),
|
||||
};
|
||||
let regex = unsafe { &*(fn_ptr as *const regex::Regex) };
|
||||
let matches: Vec<String> = regex
|
||||
.find_iter(&s)
|
||||
.map(|m| m.as_str().to_string())
|
||||
.collect();
|
||||
let matches: Vec<String> = regex.find_iter(&s).map(|m| m.as_str().to_string()).collect();
|
||||
return Ok(make_string_array(vm, &matches));
|
||||
}
|
||||
|
||||
let pattern = as_string(vm, pattern_val);
|
||||
if let Some(pos) = s.find(&pattern) {
|
||||
return Ok(make_string_array(
|
||||
vm,
|
||||
&[s[pos..pos + pattern.len()].to_string()],
|
||||
));
|
||||
return Ok(make_string_array(vm, &[s[pos..pos + pattern.len()].to_string()]));
|
||||
}
|
||||
Ok(JsValue::undefined())
|
||||
}
|
||||
@@ -467,11 +439,7 @@ pub fn string_code_point_at(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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 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(),
|
||||
@@ -495,10 +463,7 @@ pub fn string_match_all(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
None => return Ok(JsValue::undefined()),
|
||||
};
|
||||
let regex = unsafe { &*(fn_ptr as *const regex::Regex) };
|
||||
let matches: Vec<String> = regex
|
||||
.find_iter(&s)
|
||||
.map(|m| m.as_str().to_string())
|
||||
.collect();
|
||||
let matches: Vec<String> = regex.find_iter(&s).map(|m| m.as_str().to_string()).collect();
|
||||
return Ok(make_string_array(vm, &matches));
|
||||
}
|
||||
Ok(JsValue::undefined())
|
||||
@@ -510,11 +475,7 @@ pub fn string_replace_all(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
return Ok(vm.intern(&s));
|
||||
}
|
||||
let pattern_val = vm.reg(args[1]);
|
||||
let replacement = if args.len() > 2 {
|
||||
as_string(vm, vm.reg(args[2]))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let replacement = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { String::new() };
|
||||
if is_regexp_obj(pattern_val, vm) {
|
||||
let re_ptr = pattern_val.as_js_object_ptr();
|
||||
let re = unsafe { &*re_ptr };
|
||||
|
||||
@@ -18,10 +18,7 @@ pub fn symbol_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let sp = vm.kernel().builtin_world().symbol_proto.as_ptr() as *mut JsObject;
|
||||
if std::ptr::eq(proto_ptr, sp) {
|
||||
return Err(JsValue::string(
|
||||
vm.kernel()
|
||||
.string_forge()
|
||||
.intern("TypeError: Symbol is not a constructor")
|
||||
.0,
|
||||
vm.kernel().string_forge().intern("TypeError: Symbol is not a constructor").0,
|
||||
0,
|
||||
));
|
||||
}
|
||||
@@ -55,11 +52,7 @@ pub fn symbol_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
|
||||
let idx = this_val.as_symbol_index();
|
||||
let desc = vm
|
||||
.symbol_descriptions
|
||||
.get(idx as usize)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let desc = vm.symbol_descriptions.get(idx as usize).cloned().unwrap_or_default();
|
||||
let result = format!("Symbol({})", desc);
|
||||
let si = vm.kernel().string_forge().intern(&result).0;
|
||||
Ok(JsValue::string(si, 0))
|
||||
|
||||
Reference in New Issue
Block a user