From 1be90d90aa87c2673adda5536e6c608d9a83f028 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Tue, 22 Sep 2026 15:48:39 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20TA=20=E5=85=B1=E4=BA=AB=E5=8E=9F?= =?UTF-8?q?=E5=9E=8B=E7=88=B6=E9=93=BE=E5=9B=9E=E9=80=80=20Object.prototyp?= =?UTF-8?q?e=20=E5=AF=B9=E9=BD=90=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/builtin/construct.rs | 20 +++++++++---------- crates/oxide_kernel/src/builtin/rebuild.rs | 2 +- .../builtins_typed_array_base64_tests.rs | 6 ++++-- .../tests/builtins_typed_array_tests.rs | 10 ++++++++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/crates/oxide_kernel/src/builtin/construct.rs b/crates/oxide_kernel/src/builtin/construct.rs index ca1c216d..ad80adbd 100644 --- a/crates/oxide_kernel/src/builtin/construct.rs +++ b/crates/oxide_kernel/src/builtin/construct.rs @@ -159,12 +159,12 @@ fn make_typed_array_abstract_ctor( } pub(crate) fn make_typed_array_family( - string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, array_proto: &P, + string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, object_proto: &P, ) -> TypedArrayFamily { - let array_proto_val = JsValue::from_js_object(array_proto.as_ptr() as *mut JsObject); + let obj_proto_val = JsValue::from_js_object(object_proto.as_ptr() as *mut JsObject); // 给共享原型开 "constructor" 槽位(占位值在 wire 时填抽象构造器); - // [[Prototype]] 按规范接 Array.prototype(toString 经绑定层共享同一函数对象)。 - let mut typed_array_proto_obj = JsObject::new_empty(EMPTY_SHAPE_ID, array_proto_val); + // [[Prototype]] 接 Object.prototype(own toString 由绑定层安装,不经 Array.prototype 继承)。 + let mut typed_array_proto_obj = JsObject::new_empty(EMPTY_SHAPE_ID, obj_proto_val); let ctor_si = labels.constructor; let proto_shape = shape_forge.make_shape(typed_array_proto_obj.shape_id(), ctor_si); typed_array_proto_obj.set_shape_id(proto_shape); @@ -253,9 +253,9 @@ fn set_proto_if_changed(obj: &P, proto: JsValue) { /// TypedArray 家族共享对),经 `wire_ctor_proto` 覆盖占位槽; /// 2. 23 个非 TypedArray 构造器的 `[[Prototype]]` → Function.prototype /// (标准内置函数对象均继承 Function.prototype); -/// 3. 24 个非 Object 原型的 `[[Prototype]]` → Object.prototype,另含 +/// 3. 25 个非 Object 原型的 `[[Prototype]]` → Object.prototype,另含 /// Temporal 命名空间对象、Temporal.now、Console 单例与 Math/JSON -/// 命名空间对象;%TypedArray% 共享原型例外接 Array.prototype; +/// 命名空间对象; /// 4. %IteratorPrototype% → Object.prototype,6 个集合迭代器原型 /// → %IteratorPrototype%; /// 5. TypedArray 家族:11 个具体原型 → %TypedArray% 共享原型,11 个具体 @@ -338,7 +338,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) { } let obj_proto_val = JsValue::from_js_object(world.object_proto.as_ptr() as *mut JsObject); - let non_object_protos: [&P; 24] = [ + let non_object_protos: [&P; 25] = [ &world.array_proto, &world.function_proto, &world.string_proto, @@ -352,6 +352,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) { &world.regexp_proto, &world.array_buffer_proto, &world.data_view_proto, + &world.typed_array_proto, &world.instant_proto, &world.plain_date_proto, &world.plain_time_proto, @@ -367,9 +368,6 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) { for proto in &non_object_protos { set_proto_if_changed(proto, obj_proto_val); } - // %TypedArray%.prototype → Array.prototype(toString 语义经此继承)。 - let array_proto_val = JsValue::from_js_object(world.array_proto.as_ptr() as *mut JsObject); - set_proto_if_changed(&world.typed_array_proto, array_proto_val); // Temporal 命名空间对象(非构造器)继承 Object.prototype。 set_proto_if_changed(&world.temporal_object, obj_proto_val); @@ -471,7 +469,7 @@ impl BuiltinWorld { let (array_buffer_proto, array_buffer_constructor) = make_named_pair(string_forge, shape_forge, labels, "ArrayBuffer"); let (data_view_proto, data_view_constructor) = make_named_pair(string_forge, shape_forge, labels, "DataView"); - let typed_arrays = make_typed_array_family(string_forge, shape_forge, labels, &array_proto); + let typed_arrays = make_typed_array_family(string_forge, shape_forge, labels, &object_proto); let sym_match = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); let sym_replace = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); diff --git a/crates/oxide_kernel/src/builtin/rebuild.rs b/crates/oxide_kernel/src/builtin/rebuild.rs index b335237a..56db6f86 100644 --- a/crates/oxide_kernel/src/builtin/rebuild.rs +++ b/crates/oxide_kernel/src/builtin/rebuild.rs @@ -311,7 +311,7 @@ impl BuiltinWorld { (current.data_view_proto.clone(), current.data_view_constructor.clone()) }; let typed_arrays = if dirty.typed_array_family { - make_typed_array_family(string_forge, shape_forge, labels, &array_proto) + make_typed_array_family(string_forge, shape_forge, labels, &object_proto) } else { TypedArrayFamily { typed_array_proto: current.typed_array_proto.clone(), diff --git a/crates/oxide_vm/tests/builtins_typed_array_base64_tests.rs b/crates/oxide_vm/tests/builtins_typed_array_base64_tests.rs index 701894f3..25279b82 100644 --- a/crates/oxide_vm/tests/builtins_typed_array_base64_tests.rs +++ b/crates/oxide_vm/tests/builtins_typed_array_base64_tests.rs @@ -361,8 +361,10 @@ fn typed_array_prototype_to_string_chain() { var d = Object.getOwnPropertyDescriptor(TypedArray.prototype, "toString"); if (d === undefined) return "not own"; if (d.writable !== true || d.enumerable !== false || d.configurable !== true) return "attrs"; - // proto 链接 Array.prototype。 - if (Object.getPrototypeOf(TypedArray.prototype) !== Array.prototype) return "chain"; + // proto 链接 Object.prototype,不继承 Array.prototype。 + if (Object.getPrototypeOf(TypedArray.prototype) !== Object.prototype) return "chain"; + if (new Int8Array(1) instanceof Array) return "instanceof"; + if (Int8Array.prototype.push !== undefined) return "inherited"; // 实例 toString 走 Array 语义(经 TA 自身 join)。 if (new Uint8Array([1, 2, 3]).toString() !== "1,2,3") return "instance"; if (new Int16Array([7]).toString() !== "7") return "instance16"; diff --git a/crates/oxide_vm/tests/builtins_typed_array_tests.rs b/crates/oxide_vm/tests/builtins_typed_array_tests.rs index f5714d67..846ab23c 100644 --- a/crates/oxide_vm/tests/builtins_typed_array_tests.rs +++ b/crates/oxide_vm/tests/builtins_typed_array_tests.rs @@ -150,8 +150,14 @@ fn typed_array_bigint_fill_with_number_throws() { #[test] fn typed_array_to_string_is_identifiable() { let mut vm = Vm::new(); - let result = eval(&mut vm, "var ta = new Uint8Array(1); ta.toString()").unwrap(); - assert_eq!(to_str(&vm, result), "[object Uint8Array]"); + // own toString 走 Array join 语义(Uint8Array(1) → "0"); + // @@toStringTag 经 Object.prototype.toString 仍可辨识。 + let result = eval( + &mut vm, + "var ta = new Uint8Array(1); Object.prototype.toString.call(ta) + \";\" + ta.toString()", + ) + .unwrap(); + assert_eq!(to_str(&vm, result), "[object Uint8Array];0"); } #[test]