fix(object): Object() 对原始值创建 boxed 对象 + String 方法 this 完整转换
This commit is contained in:
@@ -55,8 +55,42 @@ pub(crate) fn walk_own_keys<H: VmHost>(vm: &H, obj: &JsObject) -> Vec<(u32, u32)
|
||||
}
|
||||
|
||||
/// JS `Object()` 构造逻辑:创建空对象(prototype 为 null,由 VM 补装内置原型)。
|
||||
pub fn object_constructor<H: VmHost>(vm: &mut H, _args: &[u8]) -> NativeResult {
|
||||
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
|
||||
pub fn object_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
|
||||
let object_proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject;
|
||||
// 对象参数原样返回;原始值参数创建对应 boxed 对象(规范 ToObject)。
|
||||
if val.is_object() {
|
||||
return NativeResult::Ok(val);
|
||||
}
|
||||
if val.is_null() || val.is_undefined() {
|
||||
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)));
|
||||
return NativeResult::Ok(JsValue::from_js_object(obj));
|
||||
}
|
||||
if val.is_int() || val.is_double() {
|
||||
let proto = vm.session().builtin_world().number_proto.as_ptr() as *mut JsObject;
|
||||
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto)));
|
||||
let obj_ref = unsafe { &mut *obj };
|
||||
obj_ref.type_tag = JsObject::OBJ_TYPE_NUMBER_OBJ;
|
||||
obj_ref.set_prop_at(0, val);
|
||||
return NativeResult::Ok(JsValue::from_js_object(obj));
|
||||
}
|
||||
if val.is_string() {
|
||||
let proto = vm.session().builtin_world().string_proto.as_ptr() as *mut JsObject;
|
||||
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto)));
|
||||
let obj_ref = unsafe { &mut *obj };
|
||||
obj_ref.type_tag = JsObject::OBJ_TYPE_STRING_OBJ;
|
||||
obj_ref.set_prop_at(0, val);
|
||||
return NativeResult::Ok(JsValue::from_js_object(obj));
|
||||
}
|
||||
if val.is_bool() {
|
||||
let proto = vm.session().builtin_world().boolean_proto.as_ptr() as *mut JsObject;
|
||||
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto)));
|
||||
let obj_ref = unsafe { &mut *obj };
|
||||
obj_ref.type_tag = JsObject::OBJ_TYPE_BOOLEAN_OBJ;
|
||||
obj_ref.set_prop_at(0, val);
|
||||
return NativeResult::Ok(JsValue::from_js_object(obj));
|
||||
}
|
||||
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)));
|
||||
NativeResult::Ok(JsValue::from_js_object(obj))
|
||||
}
|
||||
|
||||
@@ -849,3 +883,4 @@ pub fn object_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
}
|
||||
NativeResult::Ok(JsValue::from_js_object(arr))
|
||||
}
|
||||
|
||||
|
||||
@@ -8,12 +8,13 @@ use oxide_runtime_api::{NativeResult, VmHost};
|
||||
use crate::builtins_debug;
|
||||
use crate::builtins_error;
|
||||
|
||||
fn this_string<H: VmHost>(vm: &H, args: &[u8]) -> String {
|
||||
fn this_string<H: VmHost>(vm: &mut H, args: &[u8]) -> String {
|
||||
let this_val = vm.reg(args[0]);
|
||||
if this_val.is_null() || this_val.is_undefined() {
|
||||
String::new() // caller should check and throw TypeError
|
||||
} else {
|
||||
oxide_runtime_api::to_string(this_val)
|
||||
// 对象 this 须经 ToString 完整转换(boxed Number/String 等取内部原始值)。
|
||||
oxide_runtime_api::to_string_full(this_val, vm).unwrap_or_else(|_| String::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user