From 77411a035404f3ad58528001a55c85a5fc94d5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ralph=20K=C3=BCpper?= Date: Thu, 4 Jun 2026 18:42:27 +0200 Subject: [PATCH] fix(runtime): stringify BigInt elements in Array.prototype.join --- crates/perry-runtime/src/array/iter_methods.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/perry-runtime/src/array/iter_methods.rs b/crates/perry-runtime/src/array/iter_methods.rs index 86dccea01..6b792926e 100644 --- a/crates/perry-runtime/src/array/iter_methods.rs +++ b/crates/perry-runtime/src/array/iter_methods.rs @@ -695,6 +695,19 @@ pub extern "C" fn js_array_join( } else { result.push_str("[object Object]"); } + } else if jsvalue.is_bigint() { + // BigInt elements are NaN-boxed with BIGINT_TAG (not POINTER_TAG), + // so they bypass the pointer arm above and previously fell through + // to the `[object Object]` catch-all. ToString(BigInt) is the plain + // decimal digits with NO `n` suffix (`[10n].join() === "10"`). + let s_ptr = crate::bigint::js_bigint_to_string(jsvalue.as_bigint_ptr()); + if !s_ptr.is_null() { + let str_len = (*s_ptr).byte_len as usize; + let str_data = (s_ptr as *const u8).add(std::mem::size_of::()); + result.push_str(std::str::from_utf8_unchecked(std::slice::from_raw_parts( + str_data, str_len, + ))); + } } else if jsvalue.is_number() { let n = jsvalue.as_number(); if n.is_nan() {