From f0f45c4ae00cf37a51e700cc46a44942d3d35aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Fri, 7 Aug 2026 22:06:09 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Object.prototype.toString=20=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=A0=87=E7=AD=BE=EF=BC=88[object=20Array]=20?= =?UTF-8?q?=E7=AD=89=EF=BC=89+=20array=5Fpush=20=E7=BB=B4=E6=8A=A4?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E5=85=83=E7=B4=A0=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_builtins/src/array.rs | 5 ++- crates/oxide_builtins/src/object.rs | 48 ++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/crates/oxide_builtins/src/array.rs b/crates/oxide_builtins/src/array.rs index 28d4fea..6f0b67a 100644 --- a/crates/oxide_builtins/src/array.rs +++ b/crates/oxide_builtins/src/array.rs @@ -233,7 +233,10 @@ pub fn array_push(vm: &mut H, args: &[u8]) -> NativeResult { let arr_ptr = array_ptr!(vm, args); for &arg_reg in args.iter().skip(1) { let val = vm.promote_if_needed_for_write_ptr(arr_ptr, vm.reg(arg_reg)); - unsafe { &mut *arr_ptr }.push_prop(val); + // 元素写入须维护 array_prop_count(set_prop_at 对数组自动更新)。 + let arr = unsafe { &mut *arr_ptr }; + let idx = arr.prop_count(); + arr.set_prop_at(idx, val); } let len = unsafe { &*arr_ptr }.prop_count(); NativeResult::Ok(JsValue::int(len as i32)) diff --git a/crates/oxide_builtins/src/object.rs b/crates/oxide_builtins/src/object.rs index 522d6fc..139c4ea 100644 --- a/crates/oxide_builtins/src/object.rs +++ b/crates/oxide_builtins/src/object.rs @@ -760,10 +760,50 @@ pub fn object_proto_value_of(vm: &mut H, args: &[u8]) -> NativeResult } /// `Object.prototype.toString`:返回 `[object Object]`(暂不区分具体类型标签)。 -pub fn object_proto_to_string(vm: &mut H, _args: &[u8]) -> NativeResult { - // ponytail: minimal [[Class]] string — always "[object Object]". Type-specific - // tags ("[object Array]" etc.) and Symbol.toStringTag are a later refinement. - NativeResult::Ok(vm.new_string("[object Object]")) +pub fn object_proto_to_string(vm: &mut H, args: &[u8]) -> NativeResult { + let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); + let tag = if !this_val.is_object() { + if this_val.is_string() { + "String" + } else if this_val.is_int() || this_val.is_double() { + "Number" + } else if this_val.is_bool() { + "Boolean" + } else if this_val.is_symbol() { + "Symbol" + } else { + "Object" + } + } else { + let ptr = this_val.as_js_object_ptr(); + if ptr.is_null() { + "Object" + } else { + let obj = unsafe { &*ptr }; + if obj.is_array() { + "Array" + } else if obj.is_function() { + "Function" + } else if obj.is_string_obj() { + "String" + } else if obj.is_number_obj() { + "Number" + } else if obj.is_boolean_obj() { + "Boolean" + } else if obj.is_regexp_obj() { + "RegExp" + } else if obj.is_date_obj() { + "Date" + } else if obj.is_typed_array_obj() { + "TypedArray" + } else if obj.is_array_buffer_obj() { + "ArrayBuffer" + } else { + "Object" + } + } + }; + NativeResult::Ok(vm.new_string(&format!("[object {tag}]"))) } /// `Object.prototype.hasOwnProperty(key)`:this 是否有指定自身属性。