mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: TA toStringTag 访问器收窄并补 ArrayBuffer tag
This commit is contained in:
@@ -768,11 +768,18 @@ pub fn typed_array_length_getter<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeRe
|
||||
NativeResult::Ok(JsValue::int(view.length as i32))
|
||||
}
|
||||
|
||||
/// `%TypedArray%.prototype[@@toStringTag]` 访问器:返回具体类型名(如 `Int16Array`),
|
||||
/// 供 `Object.prototype.toString` 区分类型。
|
||||
/// `%TypedArray%.prototype[@@toStringTag]` 访问器:返回具体类型名(如
|
||||
/// `Int16Array`),供 `Object.prototype.toString` 区分类型。
|
||||
///
|
||||
/// # 边界与前提
|
||||
/// - this 非对象、无 `[[TypedArrayName]]` 内部槽(如原型自身)或内部状态无效时
|
||||
/// 返回 undefined(规范语义,不抛错)。
|
||||
pub fn typed_array_to_string_tag_getter<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
|
||||
let view = native_try!(get_typed_array_data(vm, this_val));
|
||||
let view = match get_typed_array_data(vm, this_val) {
|
||||
Ok(view) => view,
|
||||
Err(_) => return NativeResult::Ok(JsValue::undefined()),
|
||||
};
|
||||
NativeResult::Ok(vm.new_string(view.kind.name()))
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ pub fn bind_typed_array(core: &Arc<KernelCore>, session: &KernelSession, global:
|
||||
session,
|
||||
shared_proto,
|
||||
oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG),
|
||||
"get @@toStringTag",
|
||||
"get [Symbol.toStringTag]",
|
||||
oxide_builtins::typed_array::typed_array_to_string_tag_getter::<crate::vm::Vm> as *const (),
|
||||
);
|
||||
|
||||
|
||||
@@ -628,8 +628,9 @@ fn install_to_string_tags(core: &Arc<KernelCore>, session: &KernelSession) {
|
||||
let sh = core.shape_forge().as_ref();
|
||||
let tag_id = oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG;
|
||||
let tag_key = oxide_types::private_key::make_well_known_symbol_key(tag_id);
|
||||
let cases: [(*mut JsObject, &str); 11] = [
|
||||
let cases: [(*mut JsObject, &str); 12] = [
|
||||
(world.map_proto.as_ptr() as *mut JsObject, "Map"),
|
||||
(world.array_buffer_proto.as_ptr() as *mut JsObject, "ArrayBuffer"),
|
||||
(world.set_proto.as_ptr() as *mut JsObject, "Set"),
|
||||
(world.data_view_proto.as_ptr() as *mut JsObject, "DataView"),
|
||||
(world.array_iterator_proto.as_ptr() as *mut JsObject, "Array Iterator"),
|
||||
|
||||
@@ -406,3 +406,50 @@ fn typed_array_bigint_methods_receive_bigint_values() {
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typed_array_to_string_tag_undefined_for_non_ta_this() {
|
||||
// 原型自身(无 [[TypedArrayName]] 内部槽)与基元/非 TA 对象 this 读值均为
|
||||
// undefined,规范语义不抛错。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"var g = Object.getOwnPropertyDescriptor(TypedArray.prototype, Symbol.toStringTag).get; \
|
||||
g.call(TypedArray.prototype) === undefined && \
|
||||
g.call(null) === undefined && g.call(42) === undefined && \
|
||||
g.call('x') === undefined && g.call({}) === undefined && g.call([]) === undefined",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typed_array_to_string_tag_accessor_name_label() {
|
||||
// getter 的 name/length/set 描述符面按规范钉。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"var d = Object.getOwnPropertyDescriptor(TypedArray.prototype, Symbol.toStringTag); \
|
||||
d.set === undefined && d.enumerable === false && d.configurable === true && \
|
||||
d.get.name === 'get [Symbol.toStringTag]' && d.get.length === 0",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typed_array_instance_tag_and_arraybuffer_proto_tag() {
|
||||
// 实例读类型名(经 Object.prototype.toString 与直读两面);
|
||||
// ArrayBuffer.prototype 的 tag 为数据属性。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"new Int16Array(2)[Symbol.toStringTag] === 'Int16Array' && \
|
||||
Object.prototype.toString.call(new BigUint64Array(1)) === '[object BigUint64Array]' && \
|
||||
Object.prototype.toString.call(new ArrayBuffer(4)) === '[object ArrayBuffer]' && \
|
||||
ArrayBuffer.prototype[Symbol.toStringTag] === 'ArrayBuffer' && \
|
||||
Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, Symbol.toStringTag).writable === false",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user