feat: 支持 to_string 与错误栈
This commit is contained in:
@@ -116,3 +116,31 @@ pub fn eval_error_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let proto_ptr = P::as_ptr(&vm.kernel().builtin_world().eval_error_proto) as *mut JsObject;
|
||||
Ok(create_error_object(vm, proto_ptr, "EvalError", &msg))
|
||||
}
|
||||
|
||||
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())
|
||||
} else {
|
||||
("Error".to_string(), String::new())
|
||||
};
|
||||
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))
|
||||
}
|
||||
|
||||
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());
|
||||
lines.push(format!(" at {} (native)", func_name));
|
||||
}
|
||||
lines.push(" at <anonymous> (native)".to_string());
|
||||
let result = lines.join("\n");
|
||||
let si = vm.kernel().string_forge().intern(&result).0;
|
||||
Ok(JsValue::string(si, 0))
|
||||
}
|
||||
|
||||
@@ -158,3 +158,14 @@ pub fn function_bind(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
|
||||
Ok(JsValue::from_js_object(wrapper))
|
||||
}
|
||||
|
||||
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 result = if name.is_empty() {
|
||||
"function () { [native code] }".to_string()
|
||||
} else {
|
||||
format!("function {}() {{ [native code] }}", name)
|
||||
};
|
||||
let si = vm.kernel().string_forge().intern(&result).0;
|
||||
Ok(JsValue::string(si, 0))
|
||||
}
|
||||
|
||||
@@ -167,3 +167,50 @@ pub fn number_to_fixed(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let formatted = format!("{:.digits$}", n);
|
||||
Ok(vm.intern(&formatted))
|
||||
}
|
||||
|
||||
pub fn number_is_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());
|
||||
Ok(JsValue::bool(n.trunc() == n && n.is_finite()))
|
||||
}
|
||||
|
||||
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;
|
||||
Ok(JsValue::bool(safe))
|
||||
}
|
||||
|
||||
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")); }
|
||||
if n.is_infinite() {
|
||||
return Ok(vm.intern(if n.is_sign_positive() { "Infinity" } else { "-Infinity" }));
|
||||
}
|
||||
let formatted = format!("{:.digits$e}", n);
|
||||
Ok(vm.intern(&formatted))
|
||||
}
|
||||
|
||||
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")); }
|
||||
if n.is_infinite() {
|
||||
return Ok(vm.intern(if n.is_sign_positive() { "Infinity" } else { "-Infinity" }));
|
||||
}
|
||||
let formatted = format!("{:.precision$}", n);
|
||||
Ok(vm.intern(&formatted))
|
||||
}
|
||||
|
||||
pub fn number_value_of(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||
let this_val = vm.reg(args[0]);
|
||||
if this_val.is_int() || this_val.is_double() {
|
||||
return Ok(this_val);
|
||||
}
|
||||
Ok(JsValue::float(f64::NAN))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user