style: 自动格式化
This commit is contained in:
@@ -32,12 +32,54 @@ pub fn bind_error(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
||||
global.ensure_hash_props().push(Box::new(err_val));
|
||||
global.bump_generation();
|
||||
|
||||
bind_constructor_hash!(kernel, global, "TypeError", kernel.builtin_world().type_error_proto.as_ptr() as *mut JsObject, crate::builtins::error::type_error_constructor, 1);
|
||||
bind_constructor_hash!(kernel, global, "ReferenceError", kernel.builtin_world().reference_error_proto.as_ptr() as *mut JsObject, crate::builtins::error::reference_error_constructor, 1);
|
||||
bind_constructor_hash!(kernel, global, "RangeError", kernel.builtin_world().range_error_proto.as_ptr() as *mut JsObject, crate::builtins::error::range_error_constructor, 1);
|
||||
bind_constructor_hash!(kernel, global, "SyntaxError", kernel.builtin_world().syntax_error_proto.as_ptr() as *mut JsObject, crate::builtins::error::syntax_error_constructor, 1);
|
||||
bind_constructor_hash!(kernel, global, "URIError", kernel.builtin_world().uri_error_proto.as_ptr() as *mut JsObject, crate::builtins::error::uri_error_constructor, 1);
|
||||
bind_constructor_hash!(kernel, global, "EvalError", kernel.builtin_world().eval_error_proto.as_ptr() as *mut JsObject, crate::builtins::error::eval_error_constructor, 1);
|
||||
bind_constructor_hash!(
|
||||
kernel,
|
||||
global,
|
||||
"TypeError",
|
||||
kernel.builtin_world().type_error_proto.as_ptr() as *mut JsObject,
|
||||
crate::builtins::error::type_error_constructor,
|
||||
1
|
||||
);
|
||||
bind_constructor_hash!(
|
||||
kernel,
|
||||
global,
|
||||
"ReferenceError",
|
||||
kernel.builtin_world().reference_error_proto.as_ptr() as *mut JsObject,
|
||||
crate::builtins::error::reference_error_constructor,
|
||||
1
|
||||
);
|
||||
bind_constructor_hash!(
|
||||
kernel,
|
||||
global,
|
||||
"RangeError",
|
||||
kernel.builtin_world().range_error_proto.as_ptr() as *mut JsObject,
|
||||
crate::builtins::error::range_error_constructor,
|
||||
1
|
||||
);
|
||||
bind_constructor_hash!(
|
||||
kernel,
|
||||
global,
|
||||
"SyntaxError",
|
||||
kernel.builtin_world().syntax_error_proto.as_ptr() as *mut JsObject,
|
||||
crate::builtins::error::syntax_error_constructor,
|
||||
1
|
||||
);
|
||||
bind_constructor_hash!(
|
||||
kernel,
|
||||
global,
|
||||
"URIError",
|
||||
kernel.builtin_world().uri_error_proto.as_ptr() as *mut JsObject,
|
||||
crate::builtins::error::uri_error_constructor,
|
||||
1
|
||||
);
|
||||
bind_constructor_hash!(
|
||||
kernel,
|
||||
global,
|
||||
"EvalError",
|
||||
kernel.builtin_world().eval_error_proto.as_ptr() as *mut JsObject,
|
||||
crate::builtins::error::eval_error_constructor,
|
||||
1
|
||||
);
|
||||
|
||||
{
|
||||
let err_ctor_ptr = kernel.builtin_world().error_constructor.as_ptr() as *mut JsObject;
|
||||
|
||||
@@ -43,44 +43,72 @@ pub fn bind_number(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
||||
));
|
||||
num_ctor.set_native_arg_count(1);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(2.220446049250313e-16)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(2.220446049250313e-16)));
|
||||
let eps_si = kernel.string_forge().intern("EPSILON").0;
|
||||
let _shape1 = kernel.shape_forge().make_shape(num_ctor.shape_id(), eps_si);
|
||||
num_ctor.set_shape_id(_shape1);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(9007199254740991f64)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(9007199254740991f64)));
|
||||
let max_safe_si = kernel.string_forge().intern("MAX_SAFE_INTEGER").0;
|
||||
let _shape2 = kernel.shape_forge().make_shape(num_ctor.shape_id(), max_safe_si);
|
||||
let _shape2 = kernel
|
||||
.shape_forge()
|
||||
.make_shape(num_ctor.shape_id(), max_safe_si);
|
||||
num_ctor.set_shape_id(_shape2);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(-9007199254740991f64)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(-9007199254740991f64)));
|
||||
let min_safe_si = kernel.string_forge().intern("MIN_SAFE_INTEGER").0;
|
||||
let _shape3 = kernel.shape_forge().make_shape(num_ctor.shape_id(), min_safe_si);
|
||||
let _shape3 = kernel
|
||||
.shape_forge()
|
||||
.make_shape(num_ctor.shape_id(), min_safe_si);
|
||||
num_ctor.set_shape_id(_shape3);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(1.7976931348623157e308)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(1.7976931348623157e308)));
|
||||
let max_val_si = kernel.string_forge().intern("MAX_VALUE").0;
|
||||
let _shape4 = kernel.shape_forge().make_shape(num_ctor.shape_id(), max_val_si);
|
||||
let _shape4 = kernel
|
||||
.shape_forge()
|
||||
.make_shape(num_ctor.shape_id(), max_val_si);
|
||||
num_ctor.set_shape_id(_shape4);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(5e-324)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(5e-324)));
|
||||
let min_val_si = kernel.string_forge().intern("MIN_VALUE").0;
|
||||
let _shape5 = kernel.shape_forge().make_shape(num_ctor.shape_id(), min_val_si);
|
||||
let _shape5 = kernel
|
||||
.shape_forge()
|
||||
.make_shape(num_ctor.shape_id(), min_val_si);
|
||||
num_ctor.set_shape_id(_shape5);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(f64::NAN)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(f64::NAN)));
|
||||
let nan_si = kernel.string_forge().intern("NaN").0;
|
||||
let _shape6 = kernel.shape_forge().make_shape(num_ctor.shape_id(), nan_si);
|
||||
num_ctor.set_shape_id(_shape6);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(f64::NEG_INFINITY)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(f64::NEG_INFINITY)));
|
||||
let neg_inf_si = kernel.string_forge().intern("NEGATIVE_INFINITY").0;
|
||||
let _shape7 = kernel.shape_forge().make_shape(num_ctor.shape_id(), neg_inf_si);
|
||||
let _shape7 = kernel
|
||||
.shape_forge()
|
||||
.make_shape(num_ctor.shape_id(), neg_inf_si);
|
||||
num_ctor.set_shape_id(_shape7);
|
||||
|
||||
num_ctor.ensure_hash_props().push(Box::new(JsValue::float(f64::INFINITY)));
|
||||
num_ctor
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::float(f64::INFINITY)));
|
||||
let pos_inf_si = kernel.string_forge().intern("POSITIVE_INFINITY").0;
|
||||
let _shape8 = kernel.shape_forge().make_shape(num_ctor.shape_id(), pos_inf_si);
|
||||
let _shape8 = kernel
|
||||
.shape_forge()
|
||||
.make_shape(num_ctor.shape_id(), pos_inf_si);
|
||||
num_ctor.set_shape_id(_shape8);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ pub fn bind_regexp(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
||||
let sf = kernel.string_forge().as_ref();
|
||||
let sh = kernel.shape_forge().as_ref();
|
||||
|
||||
ctor.set_native_fn(Some(crate::builtins::regexp::regexp_constructor as *const ()));
|
||||
ctor.set_native_fn(Some(
|
||||
crate::builtins::regexp::regexp_constructor as *const (),
|
||||
));
|
||||
ctor.set_native_arg_count(2);
|
||||
|
||||
bind_method!(
|
||||
|
||||
@@ -25,29 +25,24 @@ pub fn bind_symbol(kernel: &Arc<OxideKernel>, global: &mut JsObject) {
|
||||
0
|
||||
);
|
||||
|
||||
let sym_match_val = JsValue::from_js_object(
|
||||
kernel.builtin_world().sym_match.as_ptr() as *mut JsObject,
|
||||
);
|
||||
let sym_match_val =
|
||||
JsValue::from_js_object(kernel.builtin_world().sym_match.as_ptr() as *mut JsObject);
|
||||
bind_well_known_symbol(kernel, ctor, sf, sh, "match", sym_match_val);
|
||||
|
||||
let sym_replace_val = JsValue::from_js_object(
|
||||
kernel.builtin_world().sym_replace.as_ptr() as *mut JsObject,
|
||||
);
|
||||
let sym_replace_val =
|
||||
JsValue::from_js_object(kernel.builtin_world().sym_replace.as_ptr() as *mut JsObject);
|
||||
bind_well_known_symbol(kernel, ctor, sf, sh, "replace", sym_replace_val);
|
||||
|
||||
let sym_search_val = JsValue::from_js_object(
|
||||
kernel.builtin_world().sym_search.as_ptr() as *mut JsObject,
|
||||
);
|
||||
let sym_search_val =
|
||||
JsValue::from_js_object(kernel.builtin_world().sym_search.as_ptr() as *mut JsObject);
|
||||
bind_well_known_symbol(kernel, ctor, sf, sh, "search", sym_search_val);
|
||||
|
||||
let sym_split_val = JsValue::from_js_object(
|
||||
kernel.builtin_world().sym_split.as_ptr() as *mut JsObject,
|
||||
);
|
||||
let sym_split_val =
|
||||
JsValue::from_js_object(kernel.builtin_world().sym_split.as_ptr() as *mut JsObject);
|
||||
bind_well_known_symbol(kernel, ctor, sf, sh, "split", sym_split_val);
|
||||
|
||||
let sym_iterator_val = JsValue::from_js_object(
|
||||
kernel.builtin_world().sym_iterator.as_ptr() as *mut JsObject,
|
||||
);
|
||||
let sym_iterator_val =
|
||||
JsValue::from_js_object(kernel.builtin_world().sym_iterator.as_ptr() as *mut JsObject);
|
||||
bind_well_known_symbol(kernel, ctor, sf, sh, "iterator", sym_iterator_val);
|
||||
|
||||
bind_constructor_hash!(
|
||||
|
||||
@@ -692,7 +692,9 @@ 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()); }
|
||||
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);
|
||||
@@ -723,15 +725,26 @@ 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 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 };
|
||||
(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); }
|
||||
} else {
|
||||
len
|
||||
};
|
||||
for i in start..end {
|
||||
arr.set_prop_at(i as u8, value);
|
||||
}
|
||||
Ok(vm.reg(args[0]))
|
||||
}
|
||||
|
||||
@@ -739,13 +752,30 @@ 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 };
|
||||
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; }
|
||||
if to >= len {
|
||||
break;
|
||||
}
|
||||
let v = arr.get_prop_at(from as u8);
|
||||
arr.set_prop_at(to as u8, v);
|
||||
to += 1;
|
||||
@@ -757,9 +787,17 @@ 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()); }
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -767,7 +805,11 @@ 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() };
|
||||
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));
|
||||
@@ -779,13 +821,28 @@ pub fn array_last_index_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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)); }
|
||||
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() };
|
||||
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)); } }
|
||||
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()),
|
||||
}
|
||||
}
|
||||
@@ -795,13 +852,28 @@ pub fn array_find_index(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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()); }
|
||||
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() };
|
||||
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); } }
|
||||
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()),
|
||||
}
|
||||
}
|
||||
@@ -811,17 +883,26 @@ pub fn array_find_last(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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()); }
|
||||
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()); }
|
||||
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])]) {
|
||||
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()),
|
||||
}
|
||||
@@ -839,6 +920,8 @@ pub fn array_sort(vm: &mut Vm, _args: &[u8]) -> NativeResult {
|
||||
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); }
|
||||
for (i, &v) in vals.iter().enumerate() {
|
||||
arr.set_prop_at(i as u8, v);
|
||||
}
|
||||
Ok(vm.reg(_args[0]))
|
||||
}
|
||||
|
||||
@@ -121,14 +121,29 @@ pub fn error_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let this_val = vm.reg(args[0]);
|
||||
let (name, msg) = if this_val.is_object() {
|
||||
let obj = unsafe { &*this_val.as_js_object_ptr() };
|
||||
let name_val = obj.hash_props_vec().and_then(|v| v.first()).map(|b| **b).unwrap_or(JsValue::undefined());
|
||||
let msg_val = obj.hash_props_vec().and_then(|v| v.get(1)).map(|b| **b).unwrap_or(JsValue::undefined());
|
||||
(vm.lookup_str(name_val).unwrap_or_else(|| "Error".to_string()),
|
||||
vm.lookup_str(msg_val).unwrap_or_default())
|
||||
let name_val = obj
|
||||
.hash_props_vec()
|
||||
.and_then(|v| v.first())
|
||||
.map(|b| **b)
|
||||
.unwrap_or(JsValue::undefined());
|
||||
let msg_val = obj
|
||||
.hash_props_vec()
|
||||
.and_then(|v| v.get(1))
|
||||
.map(|b| **b)
|
||||
.unwrap_or(JsValue::undefined());
|
||||
(
|
||||
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))
|
||||
}
|
||||
@@ -136,7 +151,11 @@ pub fn error_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
pub fn error_stack_getter(vm: &mut Vm, _args: &[u8]) -> NativeResult {
|
||||
let mut lines = vec![];
|
||||
for frame in vm.frames.iter().rev() {
|
||||
let func_name = vm.kernel().string_forge().lookup(frame.function_name).unwrap_or_else(|| "<anonymous>".to_string());
|
||||
let func_name = vm
|
||||
.kernel()
|
||||
.string_forge()
|
||||
.lookup(frame.function_name)
|
||||
.unwrap_or_else(|| "<anonymous>".to_string());
|
||||
lines.push(format!(" at {} (native)", func_name));
|
||||
}
|
||||
lines.push(" at <anonymous> (native)".to_string());
|
||||
|
||||
@@ -160,7 +160,11 @@ pub fn function_bind(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
|
||||
pub fn function_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let name = vm.kernel().string_forge().lookup(vm.reg(args[0]).as_string_index()).unwrap_or_default();
|
||||
let name = vm
|
||||
.kernel()
|
||||
.string_forge()
|
||||
.lookup(vm.reg(args[0]).as_string_index())
|
||||
.unwrap_or_default();
|
||||
let result = if name.is_empty() {
|
||||
"function () { [native code] }".to_string()
|
||||
} else {
|
||||
|
||||
@@ -177,7 +177,10 @@ 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))
|
||||
}
|
||||
|
||||
@@ -185,10 +188,19 @@ pub fn number_to_exponential(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let n = coercion::to_number(vm.reg(args[0]), vm.kernel().string_forge().as_ref());
|
||||
let digits = if args.len() > 1 {
|
||||
coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize
|
||||
} else { 0usize }.min(100);
|
||||
if n.is_nan() { return Ok(vm.intern("NaN")); }
|
||||
} else {
|
||||
0usize
|
||||
}
|
||||
.min(100);
|
||||
if n.is_nan() {
|
||||
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))
|
||||
@@ -198,10 +210,19 @@ pub fn number_to_precision(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let n = coercion::to_number(vm.reg(args[0]), vm.kernel().string_forge().as_ref());
|
||||
let precision = if args.len() > 1 {
|
||||
coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize
|
||||
} else { 0usize }.min(21);
|
||||
if n.is_nan() { return Ok(vm.intern("NaN")); }
|
||||
} else {
|
||||
0usize
|
||||
}
|
||||
.min(21);
|
||||
if n.is_nan() {
|
||||
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))
|
||||
|
||||
@@ -352,18 +352,29 @@ pub fn object_get_own_property_names(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
|
||||
pub fn object_define_properties(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if args.len() < 3 { return Ok(vm.reg(args[1])); }
|
||||
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])); }
|
||||
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()); }
|
||||
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)));
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -373,10 +384,14 @@ pub fn object_get_prototype_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
|
||||
pub fn object_has_own(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
if args.len() < 3 { return Ok(JsValue::bool(false)); }
|
||||
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)); }
|
||||
if !key_val.is_string() {
|
||||
return Ok(JsValue::bool(false));
|
||||
}
|
||||
Ok(JsValue::bool(false))
|
||||
}
|
||||
|
||||
@@ -386,17 +401,29 @@ pub fn object_entries(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let keys = walk_own_keys(vm, obj);
|
||||
let n = keys.len().min(255);
|
||||
let array_proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(array_proto), n, vm.epoch().bump()));
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(array_proto),
|
||||
n,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
for (_i, (si, offset)) in keys.iter().enumerate().take(n) {
|
||||
let key_str = vm.kernel().string_forge().lookup(*si).unwrap_or_default();
|
||||
let key_val = vm.intern(&key_str);
|
||||
let val = obj.get_prop_at(*offset);
|
||||
let pair = vm.epoch().alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(array_proto), 2, vm.epoch().bump()));
|
||||
let pair = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(array_proto),
|
||||
2,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
unsafe {
|
||||
(*pair).set_prop_at(0, key_val);
|
||||
(*pair).set_prop_at(1, val);
|
||||
(*pair).set_prop_count(2);
|
||||
(*arr).ensure_hash_props().push(Box::new(JsValue::from_js_object(pair)));
|
||||
(*arr)
|
||||
.ensure_hash_props()
|
||||
.push(Box::new(JsValue::from_js_object(pair)));
|
||||
}
|
||||
}
|
||||
Ok(JsValue::from_js_object(arr))
|
||||
@@ -408,11 +435,20 @@ pub fn object_values(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let keys = walk_own_keys(vm, obj);
|
||||
let n = keys.len().min(255);
|
||||
let array_proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject;
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(array_proto), n, vm.epoch().bump()));
|
||||
let arr = vm.epoch().alloc(JsObject::new_array(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(array_proto),
|
||||
n,
|
||||
vm.epoch().bump(),
|
||||
));
|
||||
for (i, (_si, offset)) in keys.iter().enumerate().take(n) {
|
||||
let val = obj.get_prop_at(*offset);
|
||||
unsafe { (*arr).set_prop_at(i as u8, val); }
|
||||
unsafe {
|
||||
(*arr).set_prop_at(i as u8, val);
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
(*arr).set_prop_count(n as u8);
|
||||
}
|
||||
unsafe { (*arr).set_prop_count(n as u8); }
|
||||
Ok(JsValue::from_js_object(arr))
|
||||
}
|
||||
|
||||
@@ -86,9 +86,7 @@ pub fn regexp_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
let mut obj = JsObject::new_empty(
|
||||
EMPTY_SHAPE_ID,
|
||||
JsValue::from_js_object(
|
||||
vm.kernel().builtin_world().regexp_proto.as_ptr() as *mut JsObject,
|
||||
),
|
||||
JsValue::from_js_object(vm.kernel().builtin_world().regexp_proto.as_ptr() as *mut JsObject),
|
||||
);
|
||||
|
||||
let compiled = regex::RegexBuilder::new(&pattern)
|
||||
@@ -185,8 +183,7 @@ pub fn regexp_exec(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
let (last_index, is_global) = {
|
||||
let re = unsafe { &*re_ptr };
|
||||
let li =
|
||||
coercion::to_number(get_prop(re, 0), vm.kernel().string_forge().as_ref()) as usize;
|
||||
let li = coercion::to_number(get_prop(re, 0), vm.kernel().string_forge().as_ref()) as usize;
|
||||
let g = get_prop(re, 3).as_bool();
|
||||
(li, g)
|
||||
};
|
||||
@@ -204,7 +201,7 @@ pub fn regexp_exec(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
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,
|
||||
vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -387,7 +387,10 @@ 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));
|
||||
}
|
||||
|
||||
@@ -443,9 +446,13 @@ 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 };
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let chars: Vec<char> = s.chars().collect();
|
||||
if pos >= chars.len() { return Ok(JsValue::undefined()); }
|
||||
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;
|
||||
@@ -460,7 +467,11 @@ 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(),
|
||||
@@ -472,14 +483,22 @@ pub fn string_normalize(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
pub fn string_match_all(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let s = this_string(vm, args);
|
||||
if args.len() < 2 { return Err(JsValue::undefined()); }
|
||||
if args.len() < 2 {
|
||||
return Err(JsValue::undefined());
|
||||
}
|
||||
let pattern_val = vm.reg(args[1]);
|
||||
if is_regexp_obj(pattern_val, vm) {
|
||||
let re_ptr = pattern_val.as_js_object_ptr();
|
||||
let re = unsafe { &*re_ptr };
|
||||
let fn_ptr = match re.native_fn() { Some(p) => p, None => return Ok(JsValue::undefined()) };
|
||||
let fn_ptr = match re.native_fn() {
|
||||
Some(p) => p,
|
||||
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())
|
||||
@@ -487,13 +506,22 @@ pub fn string_match_all(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
pub fn string_replace_all(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let s = this_string(vm, args);
|
||||
if args.len() < 2 { return Ok(vm.intern(&s)); }
|
||||
if args.len() < 2 {
|
||||
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 };
|
||||
let fn_ptr = match re.native_fn() { Some(p) => p, None => return Ok(vm.intern(&s)) };
|
||||
let fn_ptr = match re.native_fn() {
|
||||
Some(p) => p,
|
||||
None => return Ok(vm.intern(&s)),
|
||||
};
|
||||
let regex = unsafe { &*(fn_ptr as *const regex::Regex) };
|
||||
let result = regex.replace_all(&s, replacement.as_str()).to_string();
|
||||
return Ok(vm.intern(&result));
|
||||
|
||||
+16
-14
@@ -675,11 +675,7 @@ impl Vm {
|
||||
if b != 0 {
|
||||
// const guard: check if already initialized
|
||||
if !self.regs[rd].is_undefined() {
|
||||
throw_err!(
|
||||
self,
|
||||
TypeError,
|
||||
"Assignment to constant variable"
|
||||
);
|
||||
throw_err!(self, TypeError, "Assignment to constant variable");
|
||||
}
|
||||
}
|
||||
self.regs[rd] = self.regs[a];
|
||||
@@ -1307,10 +1303,11 @@ impl Vm {
|
||||
continue;
|
||||
}
|
||||
let prop_name_si = prop_name_val.as_string_index();
|
||||
if let Some(pos) = self.kernel.shape_forge().lookup_position(
|
||||
obj.shape_id(),
|
||||
prop_name_si,
|
||||
) {
|
||||
if let Some(pos) = self
|
||||
.kernel
|
||||
.shape_forge()
|
||||
.lookup_position(obj.shape_id(), prop_name_si)
|
||||
{
|
||||
obj.set_prop_at(pos, JsValue::undefined());
|
||||
}
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
@@ -1334,10 +1331,11 @@ impl Vm {
|
||||
};
|
||||
let obj_ptr = obj_val.as_js_object_ptr();
|
||||
let obj = unsafe { &mut *obj_ptr };
|
||||
if let Some(pos) = self.kernel.shape_forge().lookup_position(
|
||||
obj.shape_id(),
|
||||
prop_name_si,
|
||||
) {
|
||||
if let Some(pos) = self
|
||||
.kernel
|
||||
.shape_forge()
|
||||
.lookup_position(obj.shape_id(), prop_name_si)
|
||||
{
|
||||
obj.set_prop_at(pos, JsValue::undefined());
|
||||
}
|
||||
self.regs[rd] = JsValue::bool(true);
|
||||
@@ -1349,7 +1347,11 @@ impl Vm {
|
||||
let rhs_val = self.regs[b];
|
||||
|
||||
if !rhs_val.is_object() {
|
||||
throw_err!(self, TypeError, "INSTANCEOF right-hand side is not callable");
|
||||
throw_err!(
|
||||
self,
|
||||
TypeError,
|
||||
"INSTANCEOF right-hand side is not callable"
|
||||
);
|
||||
}
|
||||
if !lhs_val.is_object() {
|
||||
self.regs[rd] = JsValue::bool(false);
|
||||
|
||||
Reference in New Issue
Block a user