Skip to main content

onion_vm/types/
object.rs

1//! Onion VM 对象模型核心实现。
2//!
3//! 本模块定义了 Onion 语言运行时的完整对象系统,包括对象枚举、对象单元格、
4//! 静态对象封装、扩展trait、以及丰富的类型操作与转换接口。
5//!
6//! # 核心设计原则
7//!
8//! ## 不可变性原则
9//! Onion VM 采用严格的不可变对象模型:
10//! - 所有基础类型都是不可变的
11//! - "可变"操作实际上是创建新对象并更新引用
12//! - `Mut` 类型只是指向 `OnionObjectCell` 的弱引用容器
13//!
14//! ## 垃圾回收集成
15//! - 所有对象都支持 GC 跟踪与升级
16//! - 使用 `arc_gc` 提供的智能指针系统
17//! - 支持弱引用避免循环引用
18//!
19//! ## 类型安全与扩展性
20//! - 通过 `OnionObjectExt` trait 支持自定义类型
21//! - 统一的错误处理与类型转换接口
22//! - 丰富的运算符重载支持
23//!
24//! # 主要组件
25//!
26//! ## `OnionObject`
27//! 核心对象枚举,包含所有内置类型:
28//! - 基础类型:Integer, Float, String, Boolean 等
29//! - 容器类型:Tuple, Pair, LazySet
30//! - 函数类型:Lambda
31//! - 扩展类型:Custom
32//! - 可变引用:Mut
33//!
34//! ## `OnionObjectCell`
35//! 线程安全的对象容器,提供:
36//! - 读写锁保护的对象访问
37//! - 幂等性检查与验证
38//! - GC 跟踪支持
39//!
40//! ## `OnionStaticObject`
41//! 稳定化的对象封装,用于:
42//! - 跨函数调用的对象传递
43//! - 常量与字面量的表示
44//! - 序列化与反序列化
45//!
46//! # 典型用法
47//! ```ignore
48//! // 创建基础对象
49//! let obj = OnionObject::Integer(42);
50//! let static_obj = obj.stabilize();
51//!
52//! // 类型转换
53//! let as_float = obj.to_float()?;
54//! let as_string = obj.to_string(&vec![])?;
55//!
56//! // 运算操作
57//! let sum = obj1.binary_add(&obj2)?;
58//!
59//! // 属性访问
60//! obj.with_attribute(&key, |value| { ... })?;
61//! ```
62
63use std::{
64    collections::VecDeque,
65    fmt::{Debug, Display},
66    ptr::addr_eq,
67    sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
68};
69
70use crate::{
71    lambda::runnable::RuntimeError,
72    types::lambda::{
73        native::{
74            native_bool_converter, native_bytes_converter, native_elements_method,
75            native_float_converter, native_int_converter, native_length_method,
76            native_string_converter, wrap_native_function,
77        },
78        parameter::LambdaParameter,
79    },
80    utils::fastmap::{OnionFastMap, OnionKeyPool},
81};
82use arc_gc::{
83    arc::{GCArc, GCArcWeak},
84    gc::GC,
85    traceable::GCTraceable,
86};
87use base64::{Engine as _, engine::general_purpose};
88
89use super::{
90    lambda::{
91        definition::OnionLambdaDefinition, vm_instructions::instruction_set::VMInstructionPackage,
92    },
93    lazy_set::OnionLazySet,
94    pair::OnionPair,
95    tuple::OnionTuple,
96};
97
98/// Onion 对象单元格。
99///
100/// 线程安全的对象容器,使用读写锁保护内部对象,确保并发访问的安全性。
101/// 是 GC 系统中对象存储的基本单位。
102///
103/// # 设计原则
104/// - 严格的幂等性检查:Cell 中不应包含 `Mut` 对象
105/// - 线程安全的读写操作
106/// - GC 跟踪与弱引用支持
107///
108/// # 关键方法
109/// - `with_data()`: 安全地访问内部对象
110/// - `with_data_mut()`: 安全地可变访问内部对象
111/// - `with_attribute()`: 属性访问代理
112pub struct OnionObjectCell(pub RwLock<OnionObject>);
113
114impl OnionObjectCell {
115    /// 安全地访问内部对象数据。
116    ///
117    /// 获取对象的只读访问权限,并执行提供的闭包。
118    /// 包含严格的幂等性检查,确保 Cell 中不包含 `Mut` 对象。
119    ///
120    /// # 参数
121    /// - `f`: 处理对象的闭包
122    ///
123    /// # 返回
124    /// 闭包的执行结果
125    ///
126    /// # 错误
127    /// - `BorrowError`: 无法获取读锁
128    /// - Panic: 如果 Cell 中包含 `Mut` 对象(表示 VM 逻辑错误)
129    #[inline(always)]
130    // 严格遵循幂等律的情况下,Cell里不可能出现Mut对象。
131    // 如果出现了Mut对象,说明VM对象分配或GC逻辑有bug
132    pub fn with_data<T, F>(&self, f: F) -> Result<T, RuntimeError>
133    where
134        F: FnOnce(&OnionObject) -> Result<T, RuntimeError>,
135    {
136        match self.0.read() {
137            Ok(guard) => match &*guard {
138                OnionObject::Mut(_) => {
139                    panic!(
140                        "CRITICAL: OnionObjectCell contains Mut object. This indicates a bug in VM object allocation or GC logic. Check mutablize() and object creation paths."
141                    )
142                }
143                obj => f(obj),
144            },
145            Err(_) => Err(RuntimeError::BorrowError(
146                "Failed to borrow OnionObjectCell at 'with_data'"
147                    .to_string()
148                    .into(),
149            )),
150        }
151    }
152
153    /// 安全地可变访问内部对象数据。
154    ///
155    /// 获取对象的可写访问权限,并执行提供的闭包。
156    /// 同样包含严格的幂等性检查。
157    ///
158    /// # 参数
159    /// - `f`: 处理对象的可变闭包
160    ///
161    /// # 返回
162    /// 闭包的执行结果
163    ///
164    /// # 错误
165    /// - `BorrowError`: 无法获取写锁
166    /// - Panic: 如果 Cell 中包含 `Mut` 对象
167    #[inline(always)]
168    // 严格遵循幂等律的情况下,Cell里不可能出现Mut对象。
169    // 如果出现了Mut对象,说明VM对象分配或GC逻辑有bug
170    pub fn with_data_mut<T, F>(&self, f: F) -> Result<T, RuntimeError>
171    where
172        F: FnOnce(&mut OnionObject) -> Result<T, RuntimeError>,
173    {
174        match self.0.write() {
175            Ok(mut guard) => match &mut *guard {
176                OnionObject::Mut(_) => {
177                    panic!(
178                        "CRITICAL: OnionObjectCell contains Mut object. This indicates a bug in VM object allocation or GC logic. Check mutablize() and object creation paths."
179                    )
180                }
181                obj => f(obj),
182            },
183            Err(_) => Err(RuntimeError::BorrowError(
184                "Failed to borrow OnionObjectCell at 'with_data_mut'"
185                    .to_string()
186                    .into(),
187            )),
188        }
189    }
190
191    /// 属性访问代理。
192    ///
193    /// 通过内部对象的 `with_attribute` 方法访问属性。
194    ///
195    /// # 参数
196    /// - `key`: 属性键对象
197    /// - `f`: 处理属性值的闭包
198    #[inline(always)]
199    pub fn with_attribute<T, F>(&self, key: &OnionObject, f: &F) -> Result<T, RuntimeError>
200    where
201        F: Fn(&OnionObject) -> Result<T, RuntimeError>,
202    {
203        self.0
204            .read()
205            .map_err(|_| {
206                RuntimeError::BorrowError(
207                    "Failed to borrow OnionObjectCell at 'with_attribute'"
208                        .to_string()
209                        .into(),
210                )
211            })?
212            .with_attribute(key, f)
213    }
214
215    /// 升级对象的弱引用为强引用。
216    ///
217    /// 用于 GC 跟踪,防止对象被提前回收。
218    #[inline(always)]
219    pub fn upgrade(&self, collected: &mut Vec<GCArc<OnionObjectCell>>) {
220        match self.0.read() {
221            Ok(obj) => obj.upgrade(collected),
222            Err(_) => {
223                // 如果无法借用,可能是因为对象已经被回收或正在被其他线程使用
224                // 这里选择忽略
225            }
226        }
227    }
228
229    /// 稳定化对象为静态对象。
230    ///
231    /// 将 Cell 中的对象转换为 `OnionStaticObject`,
232    /// 用于跨函数调用和长期存储。
233    #[inline(always)]
234    pub fn stabilize(self) -> OnionStaticObject {
235        OnionStaticObject::new(self.try_borrow().unwrap().clone())
236    }
237
238    #[inline(always)]
239    pub fn equals(&self, other: &Self) -> Result<bool, RuntimeError> {
240        self.with_data(|obj| other.with_data(|other_obj| obj.equals(other_obj)))
241    }
242
243    #[inline(always)]
244    pub fn repr(&self, ptrs: &Vec<*const OnionObject>) -> Result<String, RuntimeError> {
245        self.with_data(|obj| obj.repr(ptrs))
246    }
247
248    #[inline(always)]
249    pub fn try_borrow(&self) -> Result<RwLockReadGuard<OnionObject>, RuntimeError> {
250        self.0.read().map_err(|_| {
251            RuntimeError::BorrowError(
252                "Failed to borrow OnionObjectCell at 'try_borrow'"
253                    .to_string()
254                    .into(),
255            )
256        })
257    }
258    #[inline(always)]
259    pub fn try_borrow_mut(&self) -> Result<RwLockWriteGuard<OnionObject>, RuntimeError> {
260        self.0.write().map_err(|_| {
261            RuntimeError::BorrowError(
262                "Failed to borrow OnionObjectCell at 'try_borrow_mut'"
263                    .to_string()
264                    .into(),
265            )
266        })
267    }
268}
269
270impl std::ops::Deref for OnionObjectCell {
271    type Target = RwLock<OnionObject>;
272
273    fn deref(&self) -> &Self::Target {
274        &self.0
275    }
276}
277
278impl std::ops::DerefMut for OnionObjectCell {
279    fn deref_mut(&mut self) -> &mut Self::Target {
280        &mut self.0
281    }
282}
283
284impl From<RwLock<OnionObject>> for OnionObjectCell {
285    fn from(cell: RwLock<OnionObject>) -> Self {
286        OnionObjectCell(cell)
287    }
288}
289
290impl From<OnionObject> for OnionObjectCell {
291    fn from(obj: OnionObject) -> Self {
292        OnionObjectCell(RwLock::new(obj))
293    }
294}
295
296impl GCTraceable<OnionObjectCell> for OnionObjectCell {
297    fn collect(&self, queue: &mut VecDeque<GCArcWeak<OnionObjectCell>>) {
298        if let Ok(obj) = self.0.read() {
299            obj.collect(queue);
300        }
301    }
302}
303
304impl Debug for OnionObjectCell {
305    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
306        write!(f, "{:?}", self.0.read())
307    }
308}
309
310impl Display for OnionObjectCell {
311    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
312        write!(f, "{:?}", self.0.read())
313    }
314}
315
316#[derive(Clone)]
317/// Onion VM 核心对象枚举。
318///
319/// 定义了 Onion 语言运行时的所有对象类型。遵循严格的不可变性原则:
320/// 所有类型都是不可变的,"可变"操作通过创建新对象并更新引用实现。
321///
322/// # 设计原则
323/// - **不可变性**: 对象一旦创建就不能修改
324/// - **引用透明性**: 相同输入总是产生相同输出
325/// - **GC 友好**: 所有类型都支持垃圾回收跟踪
326/// - **类型安全**: 严格的类型检查与转换
327///
328/// # 类型分类
329///
330/// ## 基础不可变类型
331/// - `Integer(i64)`: 64位有符号整数
332/// - `Float(f64)`: 64位浮点数
333/// - `String(Arc<str>)`: 不可变字符串
334/// - `Bytes(Arc<[u8]>)`: 不可变字节数组
335/// - `Boolean(bool)`: 布尔值
336/// - `Range(i64, i64)`: 整数范围
337/// - `Null`: 空值
338/// - `Undefined(Option<Arc<str>>)`: 未定义值(可选错误信息)
339///
340/// ## 容器类型
341/// - `Tuple(Arc<OnionTuple>)`: 有序对象集合
342/// - `Pair(Arc<OnionPair>)`: 键值对
343/// - `LazySet(Arc<OnionLazySet>)`: 惰性集合
344///
345/// ## 函数与扩展类型
346/// - `Lambda((Arc<OnionLambdaDefinition>, Arc<OnionObject>))`: Lambda 函数
347/// - `Custom(Arc<dyn OnionObjectExt>)`: 自定义扩展类型
348/// - `InstructionPackage(Arc<VMInstructionPackage>)`: 字节码指令包
349///
350/// ## 可变引用类型
351/// - `Mut(GCArcWeak<OnionObjectCell>)`: 可变对象的弱引用容器
352///
353/// # 重要说明
354/// `Mut` 类型不应直接使用,应通过 `mutablize()` 方法创建。
355/// `Mut` 只是一个指向 `OnionObjectCell` 的弱引用容器,不违反不可变性原则。
356pub enum OnionObject {
357    // OnionObject is the main type for all objects in the Onion VM.
358    // The VM's types are all immutable(Mut is a immutable pointer to a VM object)
359    // If we need to 'mutate' an object, it is IMPOSSIBLE to mutate the object itself, we can only let the Mut object point to a new object.
360    // So all types defined in OnionObject do not implement 'Clone', because deep cloning an object is volition of the immutability principle.
361
362    // immutable basic types
363    Integer(i64),
364    Float(f64),
365    String(Arc<str>),
366    Bytes(Arc<[u8]>),
367    Boolean(bool),
368    Range(i64, i64),
369    Null,
370    Undefined(Option<Arc<str>>),
371    InstructionPackage(Arc<VMInstructionPackage>),
372
373    // immutable container types
374    Tuple(OnionTuple), // Arc<[OnionObject]> is used inside OnionTuple
375    Pair(Arc<OnionPair>),
376    LazySet(Arc<OnionLazySet>),
377    Lambda((Arc<OnionLambdaDefinition>, Arc<OnionObject>)), // (definition, self_object)
378    Custom(Arc<dyn OnionObjectExt>),
379
380    // mutable? types, DO NOT USE THIS TYPE DIRECTLY, use 'mutablize' instead
381    // 'Mut' is just a container for a weak reference to an OnionObjectCell,
382    Mut(GCArcWeak<OnionObjectCell>),
383}
384
385/// Onion 对象扩展 trait。
386///
387/// 定义了所有自定义对象类型必须实现的接口,提供完整的对象行为规范。
388/// 支持类型内省、GC 管理、类型转换、运算操作等功能。
389///
390/// # 核心功能分类
391///
392/// ## 类型内省与 GC 管理
393/// - `as_any()`: 类型向下转换支持
394/// - `upgrade()`: GC 弱引用升级
395///
396/// ## 基础类型转换
397/// - `to_integer()`, `to_float()`, `to_string()` 等
398/// - `to_boolean()`: 布尔值转换
399/// - `repr()`: 调试表示
400/// - `type_of()`: 类型名称
401///
402/// ## 容器操作
403/// - `len()`: 长度获取
404/// - `contains()`: 包含关系检查
405/// - `apply()`: 函数应用
406///
407/// ## 键值操作
408/// - `key_of()`, `value_of()`: 键值提取
409/// - `with_attribute()`: 属性访问
410///
411/// ## 比较操作
412/// - `equals()`: 值相等性比较(必须实现)
413/// - `is_same()`: 引用相等性比较(必须实现)
414/// - `binary_eq()`, `binary_lt()`, `binary_gt()`: 二元比较
415///
416/// ## 算术运算
417/// - `binary_add()`, `binary_sub()`, `binary_mul()`, `binary_div()`: 四则运算
418/// - `binary_mod()`, `binary_pow()`: 取模与幂运算
419///
420/// ## 逻辑运算
421/// - `binary_and()`, `binary_or()`, `binary_xor()`: 位运算
422/// - `binary_shl()`, `binary_shr()`: 位移运算
423///
424/// ## 一元运算
425/// - `unary_neg()`: 负号运算
426/// - `unary_not()`: 逻辑非运算
427///
428/// # 实现注意事项
429/// - 所有方法都有默认的错误实现
430/// - 只需要重写适用于特定类型的方法
431/// - 必须实现 `equals()` 和 `is_same()` 方法
432/// - 所有实现都应该是线程安全的
433///
434/// # 错误处理
435/// 大部分方法默认返回 `InvalidType` 或 `InvalidOperation` 错误,
436/// 具体类型应该重写相关方法提供正确的实现。
437pub trait OnionObjectExt: GCTraceable<OnionObjectCell> + Debug + Send + Sync + 'static {
438    // Type introspection for downcasting
439    fn as_any(&self) -> &dyn std::any::Any;
440
441    // GC and memory management
442    fn upgrade(&self, collected: &mut Vec<GCArc<OnionObjectCell>>);
443
444    // Basic type conversions
445    fn to_integer(&self) -> Result<i64, RuntimeError> {
446        Err(RuntimeError::InvalidType(
447            format!("Cannot convert {:?} to Integer", self).into(),
448        ))
449    }
450    fn to_float(&self) -> Result<f64, RuntimeError> {
451        Err(RuntimeError::InvalidType(
452            format!("Cannot convert {:?} to Float", self).into(),
453        ))
454    }
455    #[allow(unused_variables)]
456    fn to_string(&self, ptrs: &Vec<*const OnionObject>) -> Result<String, RuntimeError> {
457        Err(RuntimeError::InvalidType(
458            format!("Cannot convert {:?} to String", self).into(),
459        ))
460    }
461    fn to_bytes(&self) -> Result<Box<[u8]>, RuntimeError> {
462        Err(RuntimeError::InvalidType(
463            format!("Cannot convert {:?} to Bytes", self).into(),
464        ))
465    }
466    fn to_boolean(&self) -> Result<bool, RuntimeError> {
467        Err(RuntimeError::InvalidType(
468            format!("Cannot convert {:?} to Boolean", self).into(),
469        ))
470    }
471    #[allow(unused_variables)]
472    fn repr(&self, ptrs: &Vec<*const OnionObject>) -> Result<String, RuntimeError> {
473        Ok(format!("{:?}", self))
474    }
475    fn type_of(&self) -> Result<String, RuntimeError> {
476        Err(RuntimeError::InvalidType(
477            format!("Cannot get type of {:?}", self).into(),
478        ))
479    }
480
481    // Container operations
482    fn len(&self) -> Result<OnionStaticObject, RuntimeError> {
483        Err(RuntimeError::InvalidOperation(
484            format!("len() not supported for {:?}", self).into(),
485        ))
486    }
487    fn contains(&self, other: &OnionObject) -> Result<bool, RuntimeError> {
488        Err(RuntimeError::InvalidOperation(
489            format!("contains() not supported for {:?} and {:?}", self, other).into(),
490        ))
491    }
492    fn apply(&self, value: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
493        Err(RuntimeError::InvalidOperation(
494            format!(
495                "apply() not supported for {:?} with value {:?}",
496                self, value
497            )
498            .into(),
499        ))
500    }
501
502    // Key-value operations
503    fn key_of(&self) -> Result<OnionStaticObject, RuntimeError> {
504        Err(RuntimeError::InvalidOperation(
505            format!("key_of() not supported for {:?}", self).into(),
506        ))
507    }
508    fn value_of(&self) -> Result<OnionStaticObject, RuntimeError> {
509        Err(RuntimeError::InvalidOperation(
510            format!("value_of() not supported for {:?}", self).into(),
511        ))
512    }
513    #[allow(unused_variables)]
514    fn with_attribute(
515        &self,
516        key: &OnionObject,
517        f: &mut dyn FnMut(&OnionObject) -> Result<(), RuntimeError>,
518    ) -> Result<(), RuntimeError> {
519        Err(RuntimeError::InvalidOperation(
520            format!(
521                "with_attribute() not supported for {:?} with key {:?}",
522                self, key
523            )
524            .into(),
525        ))
526    }
527
528    // Comparison operations
529    fn equals(&self, other: &OnionObject) -> Result<bool, RuntimeError>;
530    fn binary_eq(&self, other: &OnionObject) -> Result<bool, RuntimeError> {
531        Err(RuntimeError::InvalidOperation(
532            format!("binary_eq() not supported for {:?} and {:?}", self, other).into(),
533        ))
534    }
535    fn binary_lt(&self, other: &OnionObject) -> Result<bool, RuntimeError> {
536        Err(RuntimeError::InvalidOperation(
537            format!("binary_lt() not supported for {:?} and {:?}", self, other).into(),
538        ))
539    }
540    fn binary_gt(&self, other: &OnionObject) -> Result<bool, RuntimeError> {
541        Err(RuntimeError::InvalidOperation(
542            format!("binary_gt() not supported for {:?} and {:?}", self, other).into(),
543        ))
544    }
545
546    // Binary arithmetic operations
547    fn binary_add(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
548        Err(RuntimeError::InvalidOperation(
549            format!("binary_add() not supported for {:?} and {:?}", self, other).into(),
550        ))
551    }
552    fn binary_sub(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
553        Err(RuntimeError::InvalidOperation(
554            format!("binary_sub() not supported for {:?} and {:?}", self, other).into(),
555        ))
556    }
557    fn binary_mul(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
558        Err(RuntimeError::InvalidOperation(
559            format!("binary_mul() not supported for {:?} and {:?}", self, other).into(),
560        ))
561    }
562    fn binary_div(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
563        Err(RuntimeError::InvalidOperation(
564            format!("binary_div() not supported for {:?} and {:?}", self, other).into(),
565        ))
566    }
567    fn binary_mod(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
568        Err(RuntimeError::InvalidOperation(
569            format!("binary_mod() not supported for {:?} and {:?}", self, other).into(),
570        ))
571    }
572    fn binary_pow(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
573        Err(RuntimeError::InvalidOperation(
574            format!("binary_pow() not supported for {:?} and {:?}", self, other).into(),
575        ))
576    }
577
578    // Binary logical operations
579    fn binary_and(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
580        Err(RuntimeError::InvalidOperation(
581            format!("binary_and() not supported for {:?} and {:?}", self, other).into(),
582        ))
583    }
584    fn binary_or(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
585        Err(RuntimeError::InvalidOperation(
586            format!("binary_or() not supported for {:?} and {:?}", self, other).into(),
587        ))
588    }
589    fn binary_xor(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
590        Err(RuntimeError::InvalidOperation(
591            format!("binary_xor() not supported for {:?} and {:?}", self, other).into(),
592        ))
593    }
594
595    // Binary shift operations
596    fn binary_shl(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
597        Err(RuntimeError::InvalidOperation(
598            format!("binary_shl() not supported for {:?} and {:?}", self, other).into(),
599        ))
600    }
601    fn binary_shr(&self, other: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
602        Err(RuntimeError::InvalidOperation(
603            format!("binary_shr() not supported for {:?} and {:?}", self, other).into(),
604        ))
605    }
606
607    // Unary operations
608    fn unary_neg(&self) -> Result<OnionStaticObject, RuntimeError> {
609        Err(RuntimeError::InvalidOperation(
610            format!("unary_neg() not supported for {:?}", self).into(),
611        ))
612    }
613    fn unary_plus(&self) -> Result<OnionStaticObject, RuntimeError> {
614        Err(RuntimeError::InvalidOperation(
615            format!("unary_plus() not supported for {:?}", self).into(),
616        ))
617    }
618    fn unary_not(&self) -> Result<OnionStaticObject, RuntimeError> {
619        Err(RuntimeError::InvalidOperation(
620            format!("unary_not() not supported for {:?}", self).into(),
621        ))
622    }
623}
624
625impl Debug for OnionObject {
626    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
627        // 使用 repr
628        write!(
629            f,
630            "{}",
631            self.repr(&vec![])
632                .unwrap_or_else(|_| "BrokenReference".to_string())
633        )
634    }
635}
636
637impl GCTraceable<OnionObjectCell> for OnionObject {
638    fn collect(&self, queue: &mut VecDeque<GCArcWeak<OnionObjectCell>>) {
639        match self {
640            OnionObject::Mut(weak) => {
641                queue.push_back(weak.clone());
642            }
643            OnionObject::Tuple(tuple) => tuple.collect(queue),
644            OnionObject::Pair(pair) => pair.collect(queue),
645            OnionObject::LazySet(lazy_set) => lazy_set.collect(queue),
646            OnionObject::Lambda(lambda) => {
647                lambda.0.collect(queue);
648                lambda.1.collect(queue);
649            }
650            OnionObject::Custom(custom) => custom.collect(queue),
651
652            _ => {}
653        }
654    }
655}
656impl OnionObject {
657    /// 升级对象中的弱引用为强引用。
658    ///
659    /// 遍历对象结构,将所有弱引用升级为强引用,用于 GC 跟踪。
660    ///
661    /// # 参数
662    /// - `collected`: 用于收集强引用的向量
663    pub fn upgrade(&self, collected: &mut Vec<GCArc<OnionObjectCell>>) {
664        match self {
665            OnionObject::Mut(weak) => {
666                if let Some(strong) = weak.upgrade() {
667                    collected.push(strong);
668                }
669            }
670            OnionObject::Tuple(tuple) => tuple.upgrade(collected),
671            OnionObject::Pair(pair) => pair.upgrade(collected),
672            OnionObject::LazySet(lazy_set) => lazy_set.upgrade(collected),
673            OnionObject::Lambda(lambda) => {
674                lambda.0.upgrade(collected);
675                lambda.1.upgrade(collected);
676            }
677            OnionObject::Custom(custom) => custom.upgrade(collected),
678            _ => {}
679        }
680    }
681
682    /// 将对象转换为对象单元格。
683    ///
684    /// 创建一个包含当前对象的 `OnionObjectCell`,用于 GC 管理。
685    #[inline(always)]
686    pub fn to_cell(self) -> OnionObjectCell {
687        OnionObjectCell(RwLock::new(self))
688    }
689
690    /// 稳定化对象(引用方式)。
691    ///
692    /// 创建对象的 `OnionStaticObject` 包装,通过克隆实现。
693    #[inline(always)]
694    pub fn stabilize(&self) -> OnionStaticObject {
695        OnionStaticObject::new(self.clone())
696    }
697
698    /// 稳定化对象(消费方式)。
699    ///
700    /// 通过消费当前对象创建 `OnionStaticObject`,避免克隆。
701    #[inline(always)]
702    pub fn consume_and_stabilize(self) -> OnionStaticObject {
703        OnionStaticObject::new(self)
704    }
705
706    /// 对象的不可变数据访问。
707    ///
708    /// 如果是 `Mut` 对象,则访问其指向的对象;否则直接访问当前对象。
709    ///
710    /// # 参数
711    /// - `f`: 处理对象数据的闭包
712    #[inline(always)]
713    pub fn with_data<T, F>(&self, f: F) -> Result<T, RuntimeError>
714    where
715        F: FnOnce(&OnionObject) -> Result<T, RuntimeError>,
716    {
717        match self {
718            OnionObject::Mut(weak) => {
719                if let Some(strong) = weak.upgrade() {
720                    strong.as_ref().with_data(f)
721                } else {
722                    Err(RuntimeError::BrokenReference)
723                }
724            }
725            _ => f(self),
726        }
727    }
728
729    /// 对象的可变数据访问。
730    ///
731    /// 如果是 `Mut` 对象,则访问其指向的对象;否则直接访问当前对象。
732    ///
733    /// # 参数
734    /// - `f`: 处理对象数据的可变闭包
735    #[inline(always)]
736    pub fn with_data_mut<T, F>(&mut self, f: F) -> Result<T, RuntimeError>
737    where
738        F: FnOnce(&mut OnionObject) -> Result<T, RuntimeError>,
739    {
740        match self {
741            OnionObject::Mut(weak) => {
742                if let Some(strong) = weak.upgrade() {
743                    strong.as_ref().with_data_mut(f)
744                } else {
745                    Err(RuntimeError::BrokenReference)
746                }
747            }
748            _ => f(self),
749        }
750    }
751
752    /// 对可变对象进行赋值操作。
753    ///
754    /// 只有 `Mut` 类型的对象可以被赋值,这保证了不可变性原则。
755    /// 赋值实际上是更新 `Mut` 对象指向的内容。
756    ///
757    /// # 参数
758    /// - `other`: 要赋予的新值
759    ///
760    /// # 错误
761    /// - `InvalidOperation`: 尝试对不可变对象赋值
762    /// - `BrokenReference`: `Mut` 对象的引用已失效
763    ///
764    /// # 安全性
765    /// 由于不可变对象无法保证赋值后的稳定性,只允许对 `Mut` 对象赋值。
766    #[inline(always)]
767    /// Assign a new value to a mutable object.
768    pub fn assign(&self, other: &OnionObject) -> Result<(), RuntimeError> {
769        // 由于我们无法保证赋值后GCArcWeak指向对象的稳定性,对不可变对象进行赋值操作会导致潜在的内存安全问题。
770        // Mut类型由于是被GC管理的,因此可以安全地进行赋值操作(前提是GCArcWeak指向的对象仍然存在)。
771        let OnionObject::Mut(weak) = self else {
772            return Err(RuntimeError::InvalidOperation(
773                format!("Cannot assign to immutable object: {:?}", self).into(),
774            ));
775        };
776        match weak.upgrade() {
777            Some(strong) => {
778                // 先克隆要赋值的内容,避免借用冲突
779                let new_value = other.with_data(|other| Ok(other.clone()))?;
780
781                // 然后进行赋值
782                strong.as_ref().with_data_mut(|obj| {
783                    *obj = new_value;
784                    Ok(())
785                })
786            }
787            None => Err(RuntimeError::BrokenReference),
788        }
789    }
790
791    /// 将对象转换为可变对象。
792    ///
793    /// 在 GC 中创建一个新的 `OnionObjectCell`,并返回指向它的 `Mut` 对象。
794    /// 这是创建可变引用的正确方式,遵循幂等性原则。
795    ///
796    /// # 参数
797    /// - `gc`: GC 管理器,用于分配新的对象单元格
798    ///
799    /// # 返回
800    /// 包含 `Mut` 对象的静态对象
801    ///
802    /// # 幂等性
803    /// 多次调用 `mutablize` 会创建指向相同值的不同可变对象,
804    /// 这符合 Onion VM 的不可变性设计。
805    #[inline(always)]
806    fn mutablize(self, gc: &mut GC<OnionObjectCell>) -> OnionStaticObject {
807        let arc = gc.create(OnionObjectCell::from(self));
808        OnionStaticObject {
809            obj: OnionObject::Mut(arc.as_weak()),
810            _arcs: GCArcStorage::Single(arc),
811        }
812    }
813}
814
815/// OnionObject 的核心方法实现。
816///
817/// 包含对象的相等性比较、类型转换、运算操作等核心功能。
818/// 所有方法都遵循 Onion VM 的不可变性和幂等性原则。
819impl OnionObject {
820    /// 对象相等性比较。
821    ///
822    /// 实现了类型兼容的相等性检查,支持:
823    /// - 基础类型的直接比较
824    /// - 数值类型的隐式转换比较(Integer ↔ Float)
825    /// - 容器类型的递归比较
826    /// - 自定义类型的扩展比较
827    ///
828    /// # 参数
829    /// - `other`: 要比较的另一个对象
830    ///
831    /// # 返回
832    /// - `Ok(true)`: 对象相等
833    /// - `Ok(false)`: 对象不相等
834    /// - `Err(RuntimeError)`: 比较过程中发生错误
835    pub fn equals(&self, other: &Self) -> Result<bool, RuntimeError> {
836        self.with_data(|left| {
837            other.with_data(|right| {
838                match (left, right) {
839                    (OnionObject::Integer(i1), OnionObject::Integer(i2)) => Ok(i1 == i2),
840                    (OnionObject::Float(f1), OnionObject::Float(f2)) => Ok(f1 == f2),
841                    (OnionObject::Integer(i1), OnionObject::Float(f2)) => Ok(*i1 as f64 == *f2),
842                    (OnionObject::Float(f1), OnionObject::Integer(i2)) => Ok(*f1 == *i2 as f64),
843                    (OnionObject::String(s1), OnionObject::String(s2)) => Ok(s1 == s2),
844                    (OnionObject::Bytes(b1), OnionObject::Bytes(b2)) => Ok(b1 == b2),
845                    (OnionObject::Boolean(b1), OnionObject::Boolean(b2)) => Ok(b1 == b2),
846                    (OnionObject::Range(start1, end1), OnionObject::Range(start2, end2)) => {
847                        Ok(start1 == start2 && end1 == end2)
848                    }
849                    (OnionObject::Null, OnionObject::Null) => Ok(true),
850                    (OnionObject::Undefined(_), OnionObject::Undefined(_)) => Ok(true),
851                    (OnionObject::Tuple(t1), _) => t1.equals(other),
852                    (OnionObject::Pair(p1), _) => p1.equals(other),
853                    (OnionObject::Custom(c1), _) => c1.equals(other),
854
855                    // 理论上Mut类型不应该出现在这里
856                    _ => Ok(false),
857                }
858            })
859        })
860    }
861
862    /// 检查两个对象是否是同一个引用。
863    /// 如果是 `Mut` 类型,则比较其指向的强引用对象地址。
864    /// 对于其他类型,直接返回 `false`。
865    pub fn is_same(&self, other: &Self) -> Result<bool, RuntimeError> {
866        match (self, other) {
867            (OnionObject::Mut(weak1), OnionObject::Mut(weak2)) => {
868                if let (Some(strong1), Some(strong2)) = (weak1.upgrade(), weak2.upgrade()) {
869                    Ok(addr_eq(strong1.as_ref(), strong2.as_ref()))
870                } else {
871                    Ok(false)
872                }
873            }
874            _ => Ok(false), // 非 Mut 类型直接返回 false
875        }
876    }
877
878    /// 获取对象的长度。
879    ///
880    /// 支持多种容器类型的长度计算:
881    /// - Tuple: 元素数量
882    /// - String: 字符串长度
883    /// - Bytes: 字节数组长度
884    /// - Range: 范围大小
885    ///
886    /// # 返回
887    /// 包含长度值的静态整数对象
888    pub fn len(&self) -> Result<OnionStaticObject, RuntimeError> {
889        self.with_data(|obj| match obj {
890            OnionObject::Tuple(tuple) => tuple.len(),
891            OnionObject::String(s) => {
892                Ok(OnionStaticObject::new(OnionObject::Integer(s.len() as i64)))
893            }
894            OnionObject::Bytes(b) => {
895                Ok(OnionStaticObject::new(OnionObject::Integer(b.len() as i64)))
896            }
897            OnionObject::Range(start, end) => Ok(OnionStaticObject::new(OnionObject::Integer(
898                (end - start) as i64,
899            ))),
900            OnionObject::Custom(custom) => custom.len(),
901            _ => Err(RuntimeError::InvalidOperation(
902                format!("len() not supported for {:?}", self).into(),
903            )),
904        })
905    }
906
907    pub fn contains(&self, other: &OnionObject) -> Result<bool, RuntimeError> {
908        self.with_data(|obj| {
909            other.with_data(|other_obj| match (obj, other_obj) {
910                (OnionObject::Tuple(tuple), _) => tuple.contains(other_obj),
911                (OnionObject::String(s), OnionObject::String(other_s)) => {
912                    Ok(s.contains(other_s.as_ref()))
913                }
914                (OnionObject::Bytes(b), OnionObject::Bytes(other_b)) => Ok(b
915                    .windows(other_b.len())
916                    .any(|window| window.eq(other_b.as_ref()))),
917                (OnionObject::Range(l, r), OnionObject::Integer(i)) => Ok(*i >= *l && *i < *r),
918                (OnionObject::Range(start, end), OnionObject::Float(f)) => {
919                    Ok(*f >= *start as f64 && *f < *end as f64)
920                }
921                (OnionObject::Range(start, end), OnionObject::Range(other_start, other_end)) => {
922                    Ok(*other_start >= *start && *other_end <= *end)
923                }
924                (OnionObject::Custom(custom), _) => custom.contains(other_obj),
925                _ => Err(RuntimeError::InvalidOperation(
926                    format!("contains() not supported for {:?}", obj).into(),
927                )),
928            })
929        })
930    }
931
932    /// 将对象转换为整数。
933    ///
934    /// 支持多种类型的整数转换:
935    /// - Integer: 直接返回
936    /// - Float: 截断为整数
937    /// - String: 尝试解析为整数
938    /// - Boolean: true=1, false=0
939    /// - Custom: 调用自定义转换逻辑
940    ///
941    /// # 返回
942    /// 转换后的整数值
943    ///
944    /// # 错误
945    /// - `InvalidType`: 无法转换的类型或格式错误
946    pub fn to_integer(&self) -> Result<i64, RuntimeError> {
947        self.with_data(|obj| match obj {
948            OnionObject::Integer(i) => Ok(*i),
949            OnionObject::Float(f) => Ok(*f as i64),
950            OnionObject::String(s) => s
951                .parse::<i64>()
952                .map_err(|e| RuntimeError::InvalidType(e.to_string().into())),
953            OnionObject::Boolean(b) => Ok(if *b { 1 } else { 0 }),
954            OnionObject::Custom(custom) => custom.to_integer(),
955            _ => Err(RuntimeError::InvalidType(
956                format!("Cannot convert {:?} to Integer", obj).into(),
957            )),
958        })
959    }
960    pub fn to_float(&self) -> Result<f64, RuntimeError> {
961        self.with_data(|obj| match obj {
962            OnionObject::Integer(i) => Ok(*i as f64),
963            OnionObject::Float(f) => Ok(*f),
964            OnionObject::String(s) => s
965                .parse::<f64>()
966                .map_err(|e| RuntimeError::InvalidType(e.to_string().into())),
967            OnionObject::Boolean(b) => Ok(if *b { 1.0 } else { 0.0 }),
968            OnionObject::Custom(custom) => custom.to_float(),
969            _ => Err(RuntimeError::InvalidType(
970                format!("Cannot convert {:?} to Float", obj).into(),
971            )),
972        })
973    }
974
975    pub fn to_string(&self, ptrs: &Vec<*const OnionObject>) -> Result<String, RuntimeError> {
976        self.with_data(|obj| {
977            for ptr in ptrs {
978                if addr_eq(obj, *ptr) {
979                    return Ok("...".to_string());
980                }
981            }
982            let mut new_ptrs = ptrs.clone();
983            new_ptrs.push(obj);
984            match obj {
985                OnionObject::Integer(i) => Ok(i.to_string()),
986                OnionObject::Float(f) => Ok(f.to_string()),
987                OnionObject::String(s) => Ok(s.to_string()),
988                OnionObject::Bytes(b) => Ok(format!(
989                    "$\"{}\"",
990                    general_purpose::STANDARD.encode(b.as_ref())
991                )),
992                OnionObject::Boolean(b) => Ok(if *b {
993                    "true".to_string()
994                } else {
995                    "false".to_string()
996                }),
997                OnionObject::Null => Ok("null".to_string()),
998                OnionObject::Undefined(s) => Ok(match s {
999                    Some(s) => format!("undefined({:?})", s),
1000                    None => "undefined".to_string(),
1001                }),
1002                OnionObject::Range(start, end) => Ok(format!("{}..{}", start, end)),
1003                OnionObject::Tuple(tuple) => match tuple.get_elements().len() {
1004                    0 => Ok("()".to_string()),
1005                    1 => {
1006                        let first = tuple.get_elements().first().unwrap();
1007                        Ok(format!("({},)", first.repr(&new_ptrs)?))
1008                    }
1009                    _ => {
1010                        let elements: Result<Vec<String>, RuntimeError> = tuple
1011                            .get_elements()
1012                            .iter()
1013                            .map(|e| e.repr(&new_ptrs))
1014                            .collect();
1015                        Ok(format!("({})", elements?.join(", ")))
1016                    }
1017                },
1018                OnionObject::Pair(pair) => {
1019                    let left = pair.get_key().repr(&new_ptrs)?;
1020                    let right = pair.get_value().repr(&new_ptrs)?;
1021                    Ok(format!("{} : {}", left, right))
1022                }
1023                OnionObject::LazySet(lazy_set) => {
1024                    let container = lazy_set.get_container().repr(&new_ptrs)?;
1025                    let filter = lazy_set.get_filter().repr(&new_ptrs)?;
1026                    Ok(format!("[{} | {}]", container, filter))
1027                }
1028                OnionObject::InstructionPackage(_) => Ok("InstructionPackage(...)".to_string()),
1029                OnionObject::Lambda(lambda) => {
1030                    let body = lambda.0.get_body().to_string();
1031                    Ok(format!(
1032                        "{}::{} -> {}",
1033                        lambda.0.get_signature(),
1034                        lambda.0.get_parameter(),
1035                        body
1036                    ))
1037                }
1038                OnionObject::Custom(custom) => custom.to_string(&new_ptrs),
1039                _ => {
1040                    // 使用 Debug trait来处理其他类型的转换
1041                    Ok(format!("{:?}", obj))
1042                }
1043            }
1044        })
1045    }
1046
1047    pub fn repr(&self, ptrs: &Vec<*const OnionObject>) -> Result<String, RuntimeError> {
1048        self.with_data(|obj| {
1049            for ptr in ptrs {
1050                if addr_eq(obj, *ptr) {
1051                    return Ok("...".to_string());
1052                }
1053            }
1054            let mut new_ptrs = ptrs.clone();
1055            new_ptrs.push(obj);
1056            match obj {
1057                OnionObject::Integer(i) => Ok(format!("{}", i)),
1058                OnionObject::Float(f) => Ok(format!("{}", f)),
1059                OnionObject::String(s) => Ok(format!("{:?}", s)),
1060                OnionObject::Bytes(b) => Ok(format!(
1061                    "$\"{}\"",
1062                    general_purpose::STANDARD.encode(b.as_ref())
1063                )),
1064                OnionObject::Boolean(b) => Ok(format!("{}", b)),
1065                OnionObject::Null => Ok("null".to_string()),
1066                OnionObject::Undefined(s) => Ok(match s {
1067                    Some(s) => format!("undefined({:?})", s),
1068                    None => "undefined".to_string(),
1069                }),
1070                OnionObject::Range(start, end) => Ok(format!("{}..{}", start, end)),
1071                OnionObject::Tuple(tuple) => match tuple.get_elements().len() {
1072                    0 => Ok("()".to_string()),
1073                    1 => {
1074                        let first = tuple.get_elements().first().unwrap();
1075                        Ok(format!("({},)", first.repr(&new_ptrs)?))
1076                    }
1077                    _ => {
1078                        let elements: Result<Vec<String>, RuntimeError> = tuple
1079                            .get_elements()
1080                            .iter()
1081                            .map(|e| e.repr(&new_ptrs))
1082                            .collect();
1083                        Ok(format!("({})", elements?.join(", ")))
1084                    }
1085                },
1086                OnionObject::Pair(pair) => {
1087                    let left = pair.get_key().repr(&new_ptrs)?;
1088                    let right = pair.get_value().repr(&new_ptrs)?;
1089                    Ok(format!("{} : {}", left, right))
1090                }
1091                OnionObject::LazySet(lazy_set) => {
1092                    let container = lazy_set.get_container().repr(&new_ptrs)?;
1093                    let filter = lazy_set.get_filter().repr(&new_ptrs)?;
1094                    Ok(format!("[{} | {}]", container, filter))
1095                }
1096                OnionObject::InstructionPackage(_) => Ok("InstructionPackage(...)".to_string()),
1097                OnionObject::Lambda(lambda) => Ok(format!(
1098                    "{}::{} -> {}",
1099                    lambda.0.get_signature(),
1100                    lambda.0.get_parameter(),
1101                    lambda.0.get_body()
1102                )),
1103                OnionObject::Mut(weak) => {
1104                    if let Some(strong) = weak.upgrade() {
1105                        let inner_repr = strong
1106                            .as_ref()
1107                            .try_borrow()
1108                            .map_err(|_| {
1109                                RuntimeError::BorrowError(
1110                                    "Failed to borrow Mut object at 'repr'".into(),
1111                                )
1112                            })?
1113                            .repr(&new_ptrs)?;
1114                        Ok(format!("mut ({})", inner_repr))
1115                    } else {
1116                        Ok("Mut(BrokenReference)".to_string())
1117                    }
1118                }
1119                OnionObject::Custom(custom) => {
1120                    let custom_repr = custom.repr(&new_ptrs)?;
1121                    Ok(format!("Custom({})", custom_repr))
1122                }
1123            }
1124        })
1125    }
1126    pub fn to_bytes(&self) -> Result<Box<[u8]>, RuntimeError> {
1127        self.with_data(|obj| match obj {
1128            OnionObject::Integer(i) => Ok(i.to_string().into_bytes().into_boxed_slice()),
1129            OnionObject::Float(f) => Ok(f.to_string().into_bytes().into_boxed_slice()),
1130            OnionObject::String(s) => Ok(s.as_bytes().to_vec().into_boxed_slice()),
1131            OnionObject::Bytes(b) => Ok(b.as_ref().to_vec().into_boxed_slice()),
1132            OnionObject::Boolean(b) => Ok(if *b {
1133                b"true".to_vec().into_boxed_slice()
1134            } else {
1135                b"false".to_vec().into_boxed_slice()
1136            }),
1137            OnionObject::Custom(custom) => custom.to_bytes(),
1138            _ => Err(RuntimeError::InvalidType(
1139                format!("Cannot convert {:?} to Bytes", obj).into(),
1140            )),
1141        })
1142    }
1143
1144    pub fn to_boolean(&self) -> Result<bool, RuntimeError> {
1145        self.with_data(|obj| match obj {
1146            OnionObject::Integer(i) => Ok(*i != 0),
1147            OnionObject::Float(f) => Ok(*f != 0.0),
1148            OnionObject::String(s) => Ok(!s.is_empty()),
1149            OnionObject::Bytes(b) => Ok(!b.is_empty()),
1150            OnionObject::Boolean(b) => Ok(*b),
1151            OnionObject::Null => Ok(false),
1152            OnionObject::Undefined(_) => Ok(false),
1153            OnionObject::Custom(custom) => custom.to_boolean(),
1154            _ => Err(RuntimeError::InvalidType(
1155                format!("Cannot convert {:?} to Boolean", obj).into(),
1156            )),
1157        })
1158    }
1159
1160    pub fn binary_add(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1161        self.with_data(|obj| {
1162            other.with_data(|other_obj| match (obj, other_obj) {
1163                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1164                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 + i2)))
1165                }
1166                (OnionObject::Float(f1), OnionObject::Float(f2)) => {
1167                    Ok(OnionStaticObject::new(OnionObject::Float(f1 + f2)))
1168                }
1169                (OnionObject::Integer(i1), OnionObject::Float(f2)) => {
1170                    Ok(OnionStaticObject::new(OnionObject::Float(*i1 as f64 + f2)))
1171                }
1172                (OnionObject::Float(f1), OnionObject::Integer(i2)) => {
1173                    Ok(OnionStaticObject::new(OnionObject::Float(f1 + *i2 as f64)))
1174                }
1175                (OnionObject::String(s1), OnionObject::String(s2)) => Ok(OnionStaticObject::new(
1176                    OnionObject::String(Arc::from(format!("{}{}", s1, s2))),
1177                )),
1178                (OnionObject::Bytes(b1), OnionObject::Bytes(b2)) => {
1179                    let mut new_bytes = Vec::with_capacity(b1.len() + b2.len());
1180                    new_bytes.extend_from_slice(b1.as_ref());
1181                    new_bytes.extend_from_slice(b2.as_ref());
1182                    Ok(OnionStaticObject::new(OnionObject::Bytes(Arc::from(
1183                        new_bytes,
1184                    ))))
1185                }
1186                (OnionObject::Range(start1, end1), OnionObject::Range(start2, end2)) => Ok(
1187                    OnionStaticObject::new(OnionObject::Range(start1 + start2, end1 + end2)),
1188                ),
1189                (OnionObject::Tuple(t1), _) => t1.binary_add(other_obj),
1190                (OnionObject::Custom(c1), _) => c1.binary_add(other_obj),
1191                _ => Err(RuntimeError::InvalidOperation(
1192                    format!(
1193                        "Invalid binary add operation for {:?} and {:?}",
1194                        obj, other_obj
1195                    )
1196                    .into(),
1197                )),
1198            })
1199        })
1200    }
1201
1202    pub fn binary_sub(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1203        self.with_data(|obj| {
1204            other.with_data(|other_obj| match (obj, other_obj) {
1205                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1206                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 - i2)))
1207                }
1208                (OnionObject::Float(f1), OnionObject::Float(f2)) => {
1209                    Ok(OnionStaticObject::new(OnionObject::Float(f1 - f2)))
1210                }
1211                (OnionObject::Integer(i1), OnionObject::Float(f2)) => {
1212                    Ok(OnionStaticObject::new(OnionObject::Float(*i1 as f64 - f2)))
1213                }
1214                (OnionObject::Float(f1), OnionObject::Integer(i2)) => {
1215                    Ok(OnionStaticObject::new(OnionObject::Float(f1 - *i2 as f64)))
1216                }
1217                (OnionObject::Custom(c1), _) => c1.binary_sub(other_obj),
1218                _ => Err(RuntimeError::InvalidOperation(
1219                    format!(
1220                        "Invalid binary sub operation for {:?} and {:?}",
1221                        obj, other_obj
1222                    )
1223                    .into(),
1224                )),
1225            })
1226        })
1227    }
1228
1229    pub fn binary_mul(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1230        self.with_data(|obj| {
1231            other.with_data(|other_obj| match (obj, other_obj) {
1232                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1233                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 * i2)))
1234                }
1235                (OnionObject::Float(f1), OnionObject::Float(f2)) => {
1236                    Ok(OnionStaticObject::new(OnionObject::Float(f1 * f2)))
1237                }
1238                (OnionObject::Integer(i1), OnionObject::Float(f2)) => {
1239                    Ok(OnionStaticObject::new(OnionObject::Float(*i1 as f64 * f2)))
1240                }
1241                (OnionObject::Float(f1), OnionObject::Integer(i2)) => {
1242                    Ok(OnionStaticObject::new(OnionObject::Float(f1 * *i2 as f64)))
1243                }
1244                (OnionObject::Custom(c1), _) => c1.binary_mul(other_obj),
1245                _ => Err(RuntimeError::InvalidOperation(
1246                    format!(
1247                        "Invalid binary mul operation for {:?} and {:?}",
1248                        obj, other_obj
1249                    )
1250                    .into(),
1251                )),
1252            })
1253        })
1254    }
1255
1256    pub fn binary_div(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1257        self.with_data(|obj| {
1258            other.with_data(|other_obj| match (obj, other_obj) {
1259                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1260                    if *i2 == 0 {
1261                        return Err(RuntimeError::InvalidOperation("Division by zero".into()));
1262                    }
1263                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 / i2)))
1264                }
1265                (OnionObject::Float(f1), OnionObject::Float(f2)) => {
1266                    Ok(OnionStaticObject::new(OnionObject::Float(f1 / f2)))
1267                }
1268                (OnionObject::Integer(i1), OnionObject::Float(f2)) => {
1269                    Ok(OnionStaticObject::new(OnionObject::Float(*i1 as f64 / f2)))
1270                }
1271                (OnionObject::Float(f1), OnionObject::Integer(i2)) => {
1272                    Ok(OnionStaticObject::new(OnionObject::Float(f1 / *i2 as f64)))
1273                }
1274                (OnionObject::Custom(c1), _) => c1.binary_div(other_obj),
1275                _ => Err(RuntimeError::InvalidOperation(
1276                    format!(
1277                        "Invalid binary div operation for {:?} and {:?}",
1278                        obj, other_obj
1279                    )
1280                    .into(),
1281                )),
1282            })
1283        })
1284    }
1285
1286    pub fn binary_mod(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1287        self.with_data(|obj| {
1288            other.with_data(|other_obj| match (obj, other_obj) {
1289                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1290                    if *i2 == 0 {
1291                        return Err(RuntimeError::InvalidOperation("Division by zero".into()));
1292                    }
1293                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 % i2)))
1294                }
1295                (OnionObject::Float(f1), OnionObject::Float(f2)) => {
1296                    Ok(OnionStaticObject::new(OnionObject::Float(f1 % f2)))
1297                }
1298                (OnionObject::Integer(i1), OnionObject::Float(f2)) => {
1299                    Ok(OnionStaticObject::new(OnionObject::Float(*i1 as f64 % f2)))
1300                }
1301                (OnionObject::Float(f1), OnionObject::Integer(i2)) => {
1302                    Ok(OnionStaticObject::new(OnionObject::Float(f1 % *i2 as f64)))
1303                }
1304                (OnionObject::Custom(c1), _) => c1.binary_mod(other_obj),
1305                _ => Err(RuntimeError::InvalidOperation(
1306                    format!(
1307                        "Invalid binary mod operation for {:?} and {:?}",
1308                        obj, other_obj
1309                    )
1310                    .into(),
1311                )),
1312            })
1313        })
1314    }
1315
1316    pub fn binary_pow(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1317        self.with_data(|obj| {
1318            other.with_data(|other_obj| match (obj, other_obj) {
1319                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => Ok(OnionStaticObject::new(
1320                    OnionObject::Integer(i1.pow(*i2 as u32)),
1321                )),
1322                (OnionObject::Float(f1), OnionObject::Float(f2)) => {
1323                    Ok(OnionStaticObject::new(OnionObject::Float(f1.powf(*f2))))
1324                }
1325                (OnionObject::Integer(i1), OnionObject::Float(f2)) => Ok(OnionStaticObject::new(
1326                    OnionObject::Float((*i1 as f64).powf(*f2)),
1327                )),
1328                (OnionObject::Float(f1), OnionObject::Integer(i2)) => Ok(OnionStaticObject::new(
1329                    OnionObject::Float(f1.powi(*i2 as i32)),
1330                )),
1331                (OnionObject::Custom(c1), _) => c1.binary_pow(other_obj),
1332                _ => Err(RuntimeError::InvalidOperation(
1333                    format!(
1334                        "Invalid binary pow operation for {:?} and {:?}",
1335                        obj, other_obj
1336                    )
1337                    .into(),
1338                )),
1339            })
1340        })
1341    }
1342
1343    pub fn binary_and(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1344        self.with_data(|obj| {
1345            other.with_data(|other_obj| match (obj, other_obj) {
1346                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1347                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 & i2)))
1348                }
1349                (OnionObject::Boolean(f1), OnionObject::Boolean(f2)) => {
1350                    Ok(OnionStaticObject::new(OnionObject::Boolean(*f1 && *f2)))
1351                }
1352                (OnionObject::Custom(c1), _) => c1.binary_and(other_obj),
1353                _ => Err(RuntimeError::InvalidOperation(
1354                    format!(
1355                        "Invalid binary and operation for {:?} and {:?}",
1356                        obj, other_obj
1357                    )
1358                    .into(),
1359                )),
1360            })
1361        })
1362    }
1363
1364    pub fn binary_or(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1365        self.with_data(|obj| {
1366            other.with_data(|other_obj| match (obj, other_obj) {
1367                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1368                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 | i2)))
1369                }
1370                (OnionObject::Boolean(f1), OnionObject::Boolean(f2)) => {
1371                    Ok(OnionStaticObject::new(OnionObject::Boolean(*f1 || *f2)))
1372                }
1373                (OnionObject::Custom(c1), _) => c1.binary_or(other_obj),
1374                _ => Err(RuntimeError::InvalidOperation(
1375                    format!(
1376                        "Invalid binary or operation for {:?} and {:?}",
1377                        obj, other_obj
1378                    )
1379                    .into(),
1380                )),
1381            })
1382        })
1383    }
1384
1385    pub fn binary_xor(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1386        self.with_data(|obj| {
1387            other.with_data(|other_obj| match (obj, other_obj) {
1388                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1389                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 ^ i2)))
1390                }
1391                (OnionObject::Custom(c1), _) => c1.binary_xor(other_obj),
1392                _ => Err(RuntimeError::InvalidOperation(
1393                    format!(
1394                        "Invalid binary xor operation for {:?} and {:?}",
1395                        obj, other_obj
1396                    )
1397                    .into(),
1398                )),
1399            })
1400        })
1401    }
1402
1403    pub fn binary_shl(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1404        self.with_data(|obj| {
1405            other.with_data(|other_obj| match (obj, other_obj) {
1406                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1407                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 << i2)))
1408                }
1409                (OnionObject::Custom(c1), _) => c1.binary_shl(other_obj),
1410                _ => Err(RuntimeError::InvalidOperation(
1411                    format!(
1412                        "Invalid binary shl operation for {:?} and {:?}",
1413                        obj, other_obj
1414                    )
1415                    .into(),
1416                )),
1417            })
1418        })
1419    }
1420
1421    pub fn binary_shr(&self, other: &Self) -> Result<OnionStaticObject, RuntimeError> {
1422        self.with_data(|obj| {
1423            other.with_data(|other_obj| match (obj, other_obj) {
1424                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => {
1425                    Ok(OnionStaticObject::new(OnionObject::Integer(i1 >> i2)))
1426                }
1427                (OnionObject::Custom(c1), _) => c1.binary_shr(other_obj),
1428                _ => Err(RuntimeError::InvalidOperation(
1429                    format!(
1430                        "Invalid binary shr operation for {:?} and {:?}",
1431                        obj, other_obj
1432                    )
1433                    .into(),
1434                )),
1435            })
1436        })
1437    }
1438
1439    pub fn binary_eq(&self, other: &Self) -> Result<bool, RuntimeError> {
1440        self.equals(other)
1441    }
1442
1443    pub fn binary_lt(&self, other: &Self) -> Result<bool, RuntimeError> {
1444        self.with_data(|obj| {
1445            other.with_data(|other_obj| match (obj, other_obj) {
1446                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => Ok(i1 < i2),
1447                (OnionObject::Float(f1), OnionObject::Float(f2)) => Ok(f1 < f2),
1448                (OnionObject::Integer(i1), OnionObject::Float(f2)) => Ok((*i1 as f64) < *f2),
1449                (OnionObject::Float(f1), OnionObject::Integer(i2)) => Ok(*f1 < *i2 as f64),
1450                (OnionObject::Custom(c1), _) => c1.binary_lt(other_obj),
1451                _ => Err(RuntimeError::InvalidOperation(
1452                    format!(
1453                        "Invalid binary lt operation for {:?} and {:?}",
1454                        obj, other_obj
1455                    )
1456                    .into(),
1457                )),
1458            })
1459        })
1460    }
1461
1462    pub fn binary_gt(&self, other: &Self) -> Result<bool, RuntimeError> {
1463        self.with_data(|obj| {
1464            other.with_data(|other_obj| match (obj, other_obj) {
1465                (OnionObject::Integer(i1), OnionObject::Integer(i2)) => Ok(i1 > i2),
1466                (OnionObject::Float(f1), OnionObject::Float(f2)) => Ok(f1 > f2),
1467                (OnionObject::Integer(i1), OnionObject::Float(f2)) => Ok((*i1 as f64) > *f2),
1468                (OnionObject::Float(f1), OnionObject::Integer(i2)) => Ok(*f1 > *i2 as f64),
1469                (OnionObject::Custom(c1), _) => c1.binary_gt(other_obj),
1470                _ => Err(RuntimeError::InvalidOperation(
1471                    format!(
1472                        "Invalid binary gt operation for {:?} and {:?}",
1473                        obj, other_obj
1474                    )
1475                    .into(),
1476                )),
1477            })
1478        })
1479    }
1480
1481    pub fn unary_neg(&self) -> Result<OnionStaticObject, RuntimeError> {
1482        self.with_data(|obj| match obj {
1483            OnionObject::Integer(i) => Ok(OnionStaticObject::new(OnionObject::Integer(-i))),
1484            OnionObject::Float(f) => Ok(OnionStaticObject::new(OnionObject::Float(-f))),
1485            OnionObject::Custom(custom) => custom.unary_neg(),
1486            _ => Err(RuntimeError::InvalidOperation(
1487                format!("Invalid unary neg operation for {:?}", obj).into(),
1488            )),
1489        })
1490    }
1491
1492    pub fn unary_plus(&self) -> Result<OnionStaticObject, RuntimeError> {
1493        self.with_data(|obj| match obj {
1494            OnionObject::Integer(i) => Ok(OnionStaticObject::new(OnionObject::Integer(i.abs()))),
1495            OnionObject::Float(f) => Ok(OnionStaticObject::new(OnionObject::Float(f.abs()))),
1496            OnionObject::Custom(custom) => custom.unary_plus(),
1497            _ => Err(RuntimeError::InvalidOperation(
1498                format!("Invalid unary plus operation for {:?}", obj).into(),
1499            )),
1500        })
1501    }
1502
1503    pub fn unary_not(&self) -> Result<OnionStaticObject, RuntimeError> {
1504        self.with_data(|obj| match obj {
1505            OnionObject::Boolean(b) => Ok(OnionStaticObject::new(OnionObject::Boolean(!b))),
1506            OnionObject::Integer(i) => Ok(OnionStaticObject::new(OnionObject::Integer(!i))),
1507            OnionObject::Custom(custom) => custom.unary_not(),
1508            _ => Err(RuntimeError::InvalidOperation(
1509                format!("Invalid unary not operation for {:?}", obj).into(),
1510            )),
1511        })
1512    }
1513
1514    pub fn with_attribute<F, R>(&self, key: &OnionObject, f: &F) -> Result<R, RuntimeError>
1515    where
1516        F: Fn(&OnionObject) -> Result<R, RuntimeError>,
1517    {
1518        self.with_data(|obj| match obj {
1519            OnionObject::Integer(_) => {
1520                if let OnionObject::String(key_str) = key {
1521                    match key_str.as_ref() {
1522                        "int" => {
1523                            let converter = wrap_native_function(
1524                                LambdaParameter::Multiple(Box::new([])),
1525                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1526                                obj,
1527                                "converter::int",
1528                                OnionKeyPool::create(vec![]),
1529                                &native_int_converter,
1530                            );
1531                            return f(converter.weak());
1532                        }
1533                        "float" => {
1534                            let converter = wrap_native_function(
1535                                LambdaParameter::Multiple(Box::new([])),
1536                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1537                                obj,
1538                                "converter::float",
1539                                OnionKeyPool::create(vec![]),
1540                                &native_float_converter,
1541                            );
1542                            return f(converter.weak());
1543                        }
1544                        "string" => {
1545                            let converter = wrap_native_function(
1546                                LambdaParameter::Multiple(Box::new([])),
1547                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1548                                obj,
1549                                "converter::string",
1550                                OnionKeyPool::create(vec![]),
1551                                &native_string_converter,
1552                            );
1553                            return f(converter.weak());
1554                        }
1555                        "bool" => {
1556                            let converter = wrap_native_function(
1557                                LambdaParameter::Multiple(Box::new([])),
1558                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1559                                obj,
1560                                "converter::bool",
1561                                OnionKeyPool::create(vec![]),
1562                                &native_bool_converter,
1563                            );
1564                            return f(converter.weak());
1565                        }
1566                        "bytes" => {
1567                            let converter = wrap_native_function(
1568                                LambdaParameter::Multiple(Box::new([])),
1569                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1570                                obj,
1571                                "converter::bytes",
1572                                OnionKeyPool::create(vec![]),
1573                                &native_bytes_converter,
1574                            );
1575                            return f(converter.weak());
1576                        }
1577                        _ => {}
1578                    }
1579                }
1580                Err(RuntimeError::InvalidOperation(
1581                    format!(
1582                        "Attribute '{}' not found for Integer",
1583                        match key {
1584                            OnionObject::String(s) => s.as_ref(),
1585                            _ => "<non-string>",
1586                        }
1587                    )
1588                    .into(),
1589                ))
1590            }
1591            OnionObject::Float(_) => {
1592                if let OnionObject::String(key_str) = key {
1593                    match key_str.as_ref() {
1594                        "int" => {
1595                            let converter = wrap_native_function(
1596                                LambdaParameter::Multiple(Box::new([])),
1597                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1598                                obj,
1599                                "converter::int",
1600                                OnionKeyPool::create(vec![]),
1601                                &native_int_converter,
1602                            );
1603                            return f(converter.weak());
1604                        }
1605                        "float" => {
1606                            let converter = wrap_native_function(
1607                                LambdaParameter::Multiple(Box::new([])),
1608                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1609                                obj,
1610                                "converter::float",
1611                                OnionKeyPool::create(vec![]),
1612                                &native_float_converter,
1613                            );
1614                            return f(converter.weak());
1615                        }
1616                        "string" => {
1617                            let converter = wrap_native_function(
1618                                LambdaParameter::Multiple(Box::new([])),
1619                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1620                                obj,
1621                                "converter::string",
1622                                OnionKeyPool::create(vec![]),
1623                                &native_string_converter,
1624                            );
1625                            return f(converter.weak());
1626                        }
1627                        "bool" => {
1628                            let converter = wrap_native_function(
1629                                LambdaParameter::Multiple(Box::new([])),
1630                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1631                                obj,
1632                                "converter::bool",
1633                                OnionKeyPool::create(vec![]),
1634                                &native_bool_converter,
1635                            );
1636                            return f(converter.weak());
1637                        }
1638                        "bytes" => {
1639                            let converter = wrap_native_function(
1640                                LambdaParameter::Multiple(Box::new([])),
1641                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1642                                obj,
1643                                "converter::bytes",
1644                                OnionKeyPool::create(vec![]),
1645                                &native_bytes_converter,
1646                            );
1647                            return f(converter.weak());
1648                        }
1649                        _ => {}
1650                    }
1651                }
1652                Err(RuntimeError::InvalidOperation(
1653                    format!(
1654                        "Attribute '{}' not found for Float",
1655                        match key {
1656                            OnionObject::String(s) => s.as_ref(),
1657                            _ => "<non-string>",
1658                        }
1659                    )
1660                    .into(),
1661                ))
1662            }
1663            OnionObject::Boolean(_) => {
1664                if let OnionObject::String(key_str) = key {
1665                    match key_str.as_ref() {
1666                        "int" => {
1667                            let converter = wrap_native_function(
1668                                LambdaParameter::Multiple(Box::new([])),
1669                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1670                                obj,
1671                                "converter::int",
1672                                OnionKeyPool::create(vec![]),
1673                                &native_int_converter,
1674                            );
1675                            return f(converter.weak());
1676                        }
1677                        "float" => {
1678                            let converter = wrap_native_function(
1679                                LambdaParameter::Multiple(Box::new([])),
1680                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1681                                obj,
1682                                "converter::float",
1683                                OnionKeyPool::create(vec![]),
1684                                &native_float_converter,
1685                            );
1686                            return f(converter.weak());
1687                        }
1688                        "string" => {
1689                            let converter = wrap_native_function(
1690                                LambdaParameter::Multiple(Box::new([])),
1691                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1692                                obj,
1693                                "converter::string",
1694                                OnionKeyPool::create(vec![]),
1695                                &native_string_converter,
1696                            );
1697                            return f(converter.weak());
1698                        }
1699                        "bool" => {
1700                            let converter = wrap_native_function(
1701                                LambdaParameter::Multiple(Box::new([])),
1702                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1703                                obj,
1704                                "converter::bool",
1705                                OnionKeyPool::create(vec![]),
1706                                &native_bool_converter,
1707                            );
1708                            return f(converter.weak());
1709                        }
1710                        "bytes" => {
1711                            let converter = wrap_native_function(
1712                                LambdaParameter::Multiple(Box::new([])),
1713                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1714                                obj,
1715                                "converter::bytes",
1716                                OnionKeyPool::create(vec![]),
1717                                &native_bytes_converter,
1718                            );
1719                            return f(converter.weak());
1720                        }
1721                        _ => {}
1722                    }
1723                }
1724                Err(RuntimeError::InvalidOperation(
1725                    format!(
1726                        "Attribute '{}' not found for Boolean",
1727                        match key {
1728                            OnionObject::String(s) => s.as_ref(),
1729                            _ => "<non-string>",
1730                        }
1731                    )
1732                    .into(),
1733                ))
1734            }
1735            OnionObject::Tuple(tuple) => {
1736                // 先检查原型链/自定义属性
1737                if let Ok(result) = tuple.with_attribute(key, f) {
1738                    return Ok(result);
1739                }
1740
1741                // 再检查native方法
1742                if let OnionObject::String(key_str) = key {
1743                    match key_str.as_ref() {
1744                        "int" => {
1745                            let converter = wrap_native_function(
1746                                LambdaParameter::Multiple(Box::new([])),
1747                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1748                                obj,
1749                                "converter::int",
1750                                OnionKeyPool::create(vec![]),
1751                                &native_int_converter,
1752                            );
1753                            return f(converter.weak());
1754                        }
1755                        "float" => {
1756                            let converter = wrap_native_function(
1757                                LambdaParameter::Multiple(Box::new([])),
1758                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1759                                obj,
1760                                "converter::float",
1761                                OnionKeyPool::create(vec![]),
1762                                &native_float_converter,
1763                            );
1764                            return f(converter.weak());
1765                        }
1766                        "string" => {
1767                            let converter = wrap_native_function(
1768                                LambdaParameter::Multiple(Box::new([])),
1769                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1770                                obj,
1771                                "converter::string",
1772                                OnionKeyPool::create(vec![]),
1773                                &native_string_converter,
1774                            );
1775                            return f(converter.weak());
1776                        }
1777                        "bool" => {
1778                            let converter = wrap_native_function(
1779                                LambdaParameter::Multiple(Box::new([])),
1780                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1781                                obj,
1782                                "converter::bool",
1783                                OnionKeyPool::create(vec![]),
1784                                &native_bool_converter,
1785                            );
1786                            return f(converter.weak());
1787                        }
1788                        "bytes" => {
1789                            let converter = wrap_native_function(
1790                                LambdaParameter::Multiple(Box::new([])),
1791                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1792                                obj,
1793                                "converter::bytes",
1794                                OnionKeyPool::create(vec![]),
1795                                &native_bytes_converter,
1796                            );
1797                            return f(converter.weak());
1798                        }
1799                        "length" => {
1800                            let length_method = wrap_native_function(
1801                                LambdaParameter::Multiple(Box::new([])),
1802                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1803                                obj,
1804                                "builtin::length",
1805                                OnionKeyPool::create(vec![]),
1806                                &native_length_method,
1807                            );
1808                            return f(length_method.weak());
1809                        }
1810                        "elements" => {
1811                            let elements_method = wrap_native_function(
1812                                LambdaParameter::Multiple(Box::new([])),
1813                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1814                                obj,
1815                                "builtin::elements",
1816                                OnionKeyPool::create(vec![]),
1817                                &native_elements_method,
1818                            );
1819                            return f(elements_method.weak());
1820                        }
1821                        _ => {}
1822                    }
1823                }
1824                Err(RuntimeError::InvalidOperation(
1825                    format!(
1826                        "Attribute '{}' not found for Tuple",
1827                        match key {
1828                            OnionObject::String(s) => s.as_ref(),
1829                            _ => "<non-string>",
1830                        }
1831                    )
1832                    .into(),
1833                ))
1834            }
1835            OnionObject::Pair(pair) => pair.with_attribute(key, f),
1836            OnionObject::Lambda(lambda) => lambda.0.with_attribute(key, f),
1837            OnionObject::LazySet(lazy_set) => lazy_set.with_attribute(key, f),
1838            OnionObject::String(_) => {
1839                if let OnionObject::String(key_str) = key {
1840                    match key_str.as_ref() {
1841                        "int" => {
1842                            let converter = wrap_native_function(
1843                                LambdaParameter::Multiple(Box::new([])),
1844                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1845                                obj,
1846                                "converter::int",
1847                                OnionKeyPool::create(vec![]),
1848                                &native_int_converter,
1849                            );
1850                            return f(converter.weak());
1851                        }
1852                        "float" => {
1853                            let converter = wrap_native_function(
1854                                LambdaParameter::Multiple(Box::new([])),
1855                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1856                                obj,
1857                                "converter::float",
1858                                OnionKeyPool::create(vec![]),
1859                                &native_float_converter,
1860                            );
1861                            return f(converter.weak());
1862                        }
1863                        "string" => {
1864                            let converter = wrap_native_function(
1865                                LambdaParameter::Multiple(Box::new([])),
1866                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1867                                obj,
1868                                "converter::string",
1869                                OnionKeyPool::create(vec![]),
1870                                &native_string_converter,
1871                            );
1872                            return f(converter.weak());
1873                        }
1874                        "bool" => {
1875                            let converter = wrap_native_function(
1876                                LambdaParameter::Multiple(Box::new([])),
1877                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1878                                obj,
1879                                "converter::bool",
1880                                OnionKeyPool::create(vec![]),
1881                                &native_bool_converter,
1882                            );
1883                            return f(converter.weak());
1884                        }
1885                        "bytes" => {
1886                            let converter = wrap_native_function(
1887                                LambdaParameter::Multiple(Box::new([])),
1888                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1889                                obj,
1890                                "converter::bytes",
1891                                OnionKeyPool::create(vec![]),
1892                                &native_bytes_converter,
1893                            );
1894                            return f(converter.weak());
1895                        }
1896                        "length" => {
1897                            let length_method = wrap_native_function(
1898                                LambdaParameter::Multiple(Box::new([])),
1899                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1900                                obj,
1901                                "builtin::length",
1902                                OnionKeyPool::create(vec![]),
1903                                &native_length_method,
1904                            );
1905                            return f(length_method.weak());
1906                        }
1907                        "elements" => {
1908                            let elements_method = wrap_native_function(
1909                                LambdaParameter::Multiple(Box::new([])),
1910                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1911                                obj,
1912                                "builtin::elements",
1913                                OnionKeyPool::create(vec![]),
1914                                &native_elements_method,
1915                            );
1916                            return f(elements_method.weak());
1917                        }
1918                        _ => {}
1919                    }
1920                }
1921                Err(RuntimeError::InvalidOperation(
1922                    format!(
1923                        "Attribute '{}' not found for String",
1924                        match key {
1925                            OnionObject::String(s) => s.as_ref(),
1926                            _ => "<non-string>",
1927                        }
1928                    )
1929                    .into(),
1930                ))
1931            }
1932            OnionObject::Bytes(_) => {
1933                if let OnionObject::String(key_str) = key {
1934                    match key_str.as_ref() {
1935                        "int" => {
1936                            let converter = wrap_native_function(
1937                                LambdaParameter::Multiple(Box::new([])),
1938                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1939                                obj,
1940                                "converter::int",
1941                                OnionKeyPool::create(vec![]),
1942                                &native_int_converter,
1943                            );
1944                            return f(converter.weak());
1945                        }
1946                        "float" => {
1947                            let converter = wrap_native_function(
1948                                LambdaParameter::Multiple(Box::new([])),
1949                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1950                                obj,
1951                                "converter::float",
1952                                OnionKeyPool::create(vec![]),
1953                                &native_float_converter,
1954                            );
1955                            return f(converter.weak());
1956                        }
1957                        "string" => {
1958                            let converter = wrap_native_function(
1959                                LambdaParameter::Multiple(Box::new([])),
1960                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1961                                obj,
1962                                "converter::string",
1963                                OnionKeyPool::create(vec![]),
1964                                &native_string_converter,
1965                            );
1966                            return f(converter.weak());
1967                        }
1968                        "bool" => {
1969                            let converter = wrap_native_function(
1970                                LambdaParameter::Multiple(Box::new([])),
1971                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1972                                obj,
1973                                "converter::bool",
1974                                OnionKeyPool::create(vec![]),
1975                                &native_bool_converter,
1976                            );
1977                            return f(converter.weak());
1978                        }
1979                        "bytes" => {
1980                            let converter = wrap_native_function(
1981                                LambdaParameter::Multiple(Box::new([])),
1982                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1983                                obj,
1984                                "converter::bytes",
1985                                OnionKeyPool::create(vec![]),
1986                                &native_bytes_converter,
1987                            );
1988                            return f(converter.weak());
1989                        }
1990                        "length" => {
1991                            let length_method = wrap_native_function(
1992                                LambdaParameter::Multiple(Box::new([])),
1993                                OnionFastMap::new(OnionKeyPool::create(vec![])),
1994                                obj,
1995                                "builtin::length",
1996                                OnionKeyPool::create(vec![]),
1997                                &native_length_method,
1998                            );
1999                            return f(length_method.weak());
2000                        }
2001                        "elements" => {
2002                            let elements_method = wrap_native_function(
2003                                LambdaParameter::Multiple(Box::new([])),
2004                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2005                                obj,
2006                                "builtin::elements",
2007                                OnionKeyPool::create(vec![]),
2008                                &native_elements_method,
2009                            );
2010                            return f(elements_method.weak());
2011                        }
2012                        _ => {}
2013                    }
2014                }
2015                Err(RuntimeError::InvalidOperation(
2016                    format!(
2017                        "Attribute '{}' not found for Bytes",
2018                        match key {
2019                            OnionObject::String(s) => s.as_ref(),
2020                            _ => "<non-string>",
2021                        }
2022                    )
2023                    .into(),
2024                ))
2025            }
2026            OnionObject::Range(_, _) => {
2027                if let OnionObject::String(key_str) = key {
2028                    match key_str.as_ref() {
2029                        "int" => {
2030                            let converter = wrap_native_function(
2031                                LambdaParameter::Multiple(Box::new([])),
2032                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2033                                obj,
2034                                "converter::int",
2035                                OnionKeyPool::create(vec![]),
2036                                &native_int_converter,
2037                            );
2038                            return f(converter.weak());
2039                        }
2040                        "float" => {
2041                            let converter = wrap_native_function(
2042                                LambdaParameter::Multiple(Box::new([])),
2043                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2044                                obj,
2045                                "converter::float",
2046                                OnionKeyPool::create(vec![]),
2047                                &native_float_converter,
2048                            );
2049                            return f(converter.weak());
2050                        }
2051                        "string" => {
2052                            let converter = wrap_native_function(
2053                                LambdaParameter::Multiple(Box::new([])),
2054                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2055                                obj,
2056                                "converter::string",
2057                                OnionKeyPool::create(vec![]),
2058                                &native_string_converter,
2059                            );
2060                            return f(converter.weak());
2061                        }
2062                        "bool" => {
2063                            let converter = wrap_native_function(
2064                                LambdaParameter::Multiple(Box::new([])),
2065                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2066                                obj,
2067                                "converter::bool",
2068                                OnionKeyPool::create(vec![]),
2069                                &native_bool_converter,
2070                            );
2071                            return f(converter.weak());
2072                        }
2073                        "bytes" => {
2074                            let converter = wrap_native_function(
2075                                LambdaParameter::Multiple(Box::new([])),
2076                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2077                                obj,
2078                                "converter::bytes",
2079                                OnionKeyPool::create(vec![]),
2080                                &native_bytes_converter,
2081                            );
2082                            return f(converter.weak());
2083                        }
2084                        "length" => {
2085                            let length_method = wrap_native_function(
2086                                LambdaParameter::Multiple(Box::new([])),
2087                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2088                                obj,
2089                                "builtin::length",
2090                                OnionKeyPool::create(vec![]),
2091                                &native_length_method,
2092                            );
2093                            return f(length_method.weak());
2094                        }
2095                        "elements" => {
2096                            let elements_method = wrap_native_function(
2097                                LambdaParameter::Multiple(Box::new([])),
2098                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2099                                obj,
2100                                "builtin::elements",
2101                                OnionKeyPool::create(vec![]),
2102                                &native_elements_method,
2103                            );
2104                            return f(elements_method.weak());
2105                        }
2106                        _ => {}
2107                    }
2108                }
2109                Err(RuntimeError::InvalidOperation(
2110                    format!(
2111                        "Attribute '{}' not found for Range",
2112                        match key {
2113                            OnionObject::String(s) => s.as_ref(),
2114                            _ => "<non-string>",
2115                        }
2116                    )
2117                    .into(),
2118                ))
2119            }
2120            OnionObject::Null => {
2121                if let OnionObject::String(key_str) = key {
2122                    match key_str.as_ref() {
2123                        "string" => {
2124                            let converter = wrap_native_function(
2125                                LambdaParameter::Multiple(Box::new([])),
2126                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2127                                obj,
2128                                "converter::string",
2129                                OnionKeyPool::create(vec![]),
2130                                &native_string_converter,
2131                            );
2132                            return f(converter.weak());
2133                        }
2134                        "bool" => {
2135                            let converter = wrap_native_function(
2136                                LambdaParameter::Multiple(Box::new([])),
2137                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2138                                obj,
2139                                "converter::bool",
2140                                OnionKeyPool::create(vec![]),
2141                                &native_bool_converter,
2142                            );
2143                            return f(converter.weak());
2144                        }
2145                        _ => {}
2146                    }
2147                }
2148                Err(RuntimeError::InvalidOperation(
2149                    format!(
2150                        "Attribute '{}' not found for null",
2151                        match key {
2152                            OnionObject::String(s) => s.as_ref(),
2153                            _ => "<non-string>",
2154                        }
2155                    )
2156                    .into(),
2157                ))
2158            }
2159            OnionObject::Undefined(_) => {
2160                if let OnionObject::String(key_str) = key {
2161                    match key_str.as_ref() {
2162                        "string" => {
2163                            let converter = wrap_native_function(
2164                                LambdaParameter::Multiple(Box::new([])),
2165                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2166                                obj,
2167                                "converter::string",
2168                                OnionKeyPool::create(vec![]),
2169                                &native_string_converter,
2170                            );
2171                            return f(converter.weak());
2172                        }
2173                        "bool" => {
2174                            let converter = wrap_native_function(
2175                                LambdaParameter::Multiple(Box::new([])),
2176                                OnionFastMap::new(OnionKeyPool::create(vec![])),
2177                                obj,
2178                                "converter::bool",
2179                                OnionKeyPool::create(vec![]),
2180                                &native_bool_converter,
2181                            );
2182                            return f(converter.weak());
2183                        }
2184                        _ => {}
2185                    }
2186                }
2187                Err(RuntimeError::InvalidOperation(
2188                    format!(
2189                        "Attribute '{}' not found for undefined",
2190                        match key {
2191                            OnionObject::String(s) => s.as_ref(),
2192                            _ => "<non-string>",
2193                        }
2194                    )
2195                    .into(),
2196                ))
2197            }
2198            OnionObject::Custom(custom) => {
2199                let mut result: Result<R, RuntimeError> = Err(RuntimeError::InvalidOperation(
2200                    "Custom with_attribute not called".into(),
2201                ));
2202                let mut closure = |obj: &OnionObject| -> Result<(), RuntimeError> {
2203                    result = f(obj);
2204                    Ok(())
2205                };
2206                custom.with_attribute(key, &mut closure)?;
2207                result
2208            }
2209            _ => Err(RuntimeError::InvalidOperation(
2210                format!("with_attribute() not supported for {:?}", self).into(),
2211            )),
2212        })
2213    }
2214    
2215    pub fn apply(&self, value: &OnionObject) -> Result<OnionStaticObject, RuntimeError> {
2216        self.with_data(|obj| {
2217            value.with_data(|value| match obj {
2218                OnionObject::Tuple(tuple) => {
2219                    match value {
2220                        OnionObject::Integer(i) => {
2221                            // 单索引访问
2222                            let elements = tuple.get_elements();
2223                            if (*i as usize) < elements.len() {
2224                                Ok(OnionStaticObject::new(elements[*i as usize].clone()))
2225                            } else {
2226                                Err(RuntimeError::InvalidOperation(
2227                                    "Index out of bounds for tuple".into(),
2228                                ))
2229                            }
2230                        }
2231                        OnionObject::Range(start, end) => {
2232                            // 切片访问
2233                            let elements = tuple.get_elements();
2234                            let len = elements.len() as i64;
2235                            let start_idx = (*start).max(0).min(len) as usize;
2236                            let end_idx = (*end).max(0).min(len) as usize;
2237
2238                            if start_idx <= end_idx {
2239                                let sliced: Vec<OnionObject> =
2240                                    elements[start_idx..end_idx].to_vec();
2241                                Ok(OnionStaticObject::new(OnionObject::Tuple(
2242                                    OnionTuple::new(sliced).into(),
2243                                )))
2244                            } else {
2245                                Ok(OnionStaticObject::new(OnionObject::Tuple(
2246                                    OnionTuple::new(vec![]).into(),
2247                                )))
2248                            }
2249                        }
2250                        _ => Err(RuntimeError::InvalidType(
2251                            "Tuple apply() expects Integer (index) or Range (slice)".into(),
2252                        )),
2253                    }
2254                }
2255                OnionObject::String(s) => {
2256                    match value {
2257                        OnionObject::Integer(i) => {
2258                            // 单字符访问
2259                            if *i < 0 || *i >= s.chars().count() as i64 {
2260                                return Err(RuntimeError::InvalidOperation(
2261                                    format!("Index out of bounds for String: {}", s).into(),
2262                                ));
2263                            }
2264                            Ok(OnionStaticObject::new(OnionObject::String(Arc::from(
2265                                s.chars().nth(*i as usize).unwrap().to_string(),
2266                            ))))
2267                        }
2268                        OnionObject::Range(start, end) => {
2269                            // 字符串切片
2270                            let chars: Vec<char> = s.chars().collect();
2271                            let len = chars.len() as i64;
2272                            let start_idx = (*start).max(0).min(len) as usize;
2273                            let end_idx = (*end).max(0).min(len) as usize;
2274
2275                            if start_idx <= end_idx {
2276                                let sliced: String = chars[start_idx..end_idx].iter().collect();
2277                                Ok(OnionStaticObject::new(OnionObject::String(Arc::from(
2278                                    sliced,
2279                                ))))
2280                            } else {
2281                                Ok(OnionStaticObject::new(OnionObject::String(Arc::from(""))))
2282                            }
2283                        }
2284                        _ => Err(RuntimeError::InvalidType(
2285                            "String apply() expects Integer (index) or Range (slice)".into(),
2286                        )),
2287                    }
2288                }
2289                OnionObject::Bytes(b) => {
2290                    match value {
2291                        OnionObject::Integer(i) => {
2292                            // 单字节访问
2293                            if *i < 0 || *i >= b.len() as i64 {
2294                                return Err(RuntimeError::InvalidOperation(
2295                                    format!("Index out of bounds for Bytes: {:?}", b).into(),
2296                                ));
2297                            }
2298                            Ok(OnionStaticObject::new(OnionObject::Bytes(Arc::from(vec![
2299                                b[*i as usize],
2300                            ]))))
2301                        }
2302                        OnionObject::Range(start, end) => {
2303                            // 字节切片
2304                            let len = b.len() as i64;
2305                            let start_idx = (*start).max(0).min(len) as usize;
2306                            let end_idx = (*end).max(0).min(len) as usize;
2307
2308                            if start_idx <= end_idx {
2309                                let sliced = &b[start_idx..end_idx];
2310                                Ok(OnionStaticObject::new(OnionObject::Bytes(Arc::from(
2311                                    sliced,
2312                                ))))
2313                            } else {
2314                                Ok(OnionStaticObject::new(OnionObject::Bytes(Arc::from(
2315                                    vec![],
2316                                ))))
2317                            }
2318                        }
2319                        _ => Err(RuntimeError::InvalidType(
2320                            "Bytes apply() expects Integer (index) or Range (slice)".into(),
2321                        )),
2322                    }
2323                }
2324                OnionObject::Custom(custom) => custom.apply(value),
2325                _ => Err(RuntimeError::InvalidOperation(
2326                    format!("apply() not supported for {:?}", obj).into(),
2327                )),
2328            })
2329        })
2330    }
2331
2332    pub fn key_of(&self) -> Result<OnionStaticObject, RuntimeError> {
2333        self.with_data(|obj| match obj {
2334            OnionObject::Pair(pair) => Ok(pair.get_key().stabilize()),
2335            OnionObject::Lambda(lambda) => Ok(lambda.0.get_parameter().to_onion()),
2336            OnionObject::LazySet(set) => Ok(set.get_container().stabilize()),
2337            OnionObject::Custom(custom) => custom.key_of(),
2338            _ => Err(RuntimeError::InvalidOperation(
2339                format!("key_of() not supported for {:?}", obj).into(),
2340            )),
2341        })
2342    }
2343
2344    pub fn value_of(&self) -> Result<OnionStaticObject, RuntimeError> {
2345        self.with_data(|obj| match obj {
2346            OnionObject::Pair(pair) => Ok(pair.get_value().stabilize()),
2347            OnionObject::LazySet(set) => Ok(set.get_filter().stabilize()),
2348            OnionObject::Undefined(s) => Ok(OnionStaticObject::new(OnionObject::String(
2349                Arc::from(s.as_ref().map(|o| o.as_ref()).unwrap_or_else(|| "")),
2350            ))),
2351            OnionObject::Custom(custom) => custom.value_of(),
2352            _ => Err(RuntimeError::InvalidOperation(
2353                format!("value_of() not supported for {:?}", obj).into(),
2354            )),
2355        })
2356    }
2357
2358    pub fn type_of(&self) -> Result<String, RuntimeError> {
2359        self.with_data(|obj| match obj {
2360            OnionObject::Integer(_) => Ok("Integer".to_string()),
2361            OnionObject::Float(_) => Ok("Float".to_string()),
2362            OnionObject::String(_) => Ok("String".to_string()),
2363            OnionObject::Bytes(_) => Ok("Bytes".to_string()),
2364            OnionObject::Boolean(_) => Ok("Boolean".to_string()),
2365            OnionObject::Null => Ok("Null".to_string()),
2366            OnionObject::Undefined(_) => Ok("Undefined".to_string()),
2367            OnionObject::Tuple(_) => Ok("Tuple".to_string()),
2368            OnionObject::Pair(_) => Ok("Pair".to_string()),
2369            OnionObject::LazySet(_) => Ok("LazySet".to_string()),
2370            OnionObject::InstructionPackage(_) => Ok("InstructionPackage".to_string()),
2371            OnionObject::Lambda(_) => Ok("Lambda".to_string()),
2372            OnionObject::Custom(custom) => custom.type_of(),
2373            _ => Err(RuntimeError::InvalidOperation(
2374                format!("type_of() not supported for {:?}", obj).into(),
2375            )),
2376        })
2377    }
2378
2379    #[inline(always)]
2380    pub fn copy(&self) -> Result<OnionStaticObject, RuntimeError> {
2381        self.with_data(|obj| Ok(obj.stabilize()))
2382    }
2383}
2384
2385#[derive(Clone)]
2386/// GC 强引用存储策略枚举。
2387///
2388/// 根据对象的复杂性选择不同的引用存储策略,优化内存使用和性能。
2389///
2390/// # 变体说明
2391/// - `None`: 无需额外引用(基础类型如 Integer, String)
2392/// - `Single`: 单个强引用(如 Mut 对象)
2393/// - `Multiple`: 多个强引用(复杂对象如 Tuple, Lambda)
2394///
2395/// # 设计考虑
2396/// 这种分层设计避免了为简单对象分配不必要的 Vec,
2397/// 同时为复杂对象提供了灵活的引用管理。
2398pub enum GCArcStorage {
2399    None,
2400    Single(GCArc<OnionObjectCell>),
2401    Multiple(Arc<Vec<GCArc<OnionObjectCell>>>),
2402}
2403
2404// impl GCArcStorage {
2405//     #[inline(always)]
2406//     pub fn from_vec(v: Vec<GCArc<OnionObjectCell>>) -> Self {
2407//         match v.len() {
2408//             0 => Self::None,
2409//             1 => Self::Single(v[0].clone()),
2410//             _ => Self::Multiple(v),
2411//         }
2412//     }
2413// }
2414
2415#[derive(Clone)]
2416/// Onion 静态对象封装。
2417///
2418/// 稳定化的对象封装,用于跨函数调用、长期存储和序列化。
2419/// 通过持有必要的强引用来确保对象在使用期间不被 GC 回收。
2420///
2421/// # 设计目的
2422/// - **跨边界传递**: 在函数调用、模块间传递对象
2423/// - **长期存储**: 作为常量、全局变量等存储
2424/// - **GC 稳定性**: 确保对象在使用期间不被回收
2425/// - **序列化支持**: 提供对象的稳定表示
2426///
2427/// # 内部结构
2428/// - `obj`: 实际的对象数据
2429/// - `_arcs`: GC 强引用存储,防止对象被回收
2430///
2431/// # GC 策略
2432/// 根据对象类型采用不同的 GC 策略:
2433/// - **基础类型**: 无需额外引用(如 Integer, String 等)
2434/// - **Mut 类型**: 持有单个强引用
2435/// - **复杂类型**: 持有多个强引用(如 Tuple, Lambda 等)
2436///
2437/// # 关键方法
2438/// - `new()`: 创建静态对象并自动设置 GC 引用
2439/// - `weak()`: 获取内部对象的弱引用
2440/// - `mutablize()`: 转换为可变对象
2441/// - `immutablize()`: 从可变对象中提取值
2442pub struct OnionStaticObject {
2443    _arcs: GCArcStorage,
2444    obj: OnionObject,
2445}
2446
2447impl Default for OnionStaticObject {
2448    fn default() -> Self {
2449        OnionStaticObject {
2450            obj: OnionObject::Undefined(None),
2451            _arcs: GCArcStorage::None,
2452        }
2453    }
2454}
2455
2456impl Debug for OnionStaticObject {
2457    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2458        write!(f, "OnionStaticObject({:?})", self.obj)
2459    }
2460}
2461
2462impl Display for OnionStaticObject {
2463    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2464        write!(f, "OnionStaticObject({:?})", self.obj)
2465    }
2466}
2467
2468impl OnionStaticObject {
2469    #[inline(always)]
2470    pub fn new(obj: OnionObject) -> Self {
2471        let arcs = match &obj {
2472            OnionObject::Mut(obj) => match obj.upgrade() {
2473                None => GCArcStorage::None,
2474                Some(arc) => GCArcStorage::Single(arc),
2475            },
2476            OnionObject::Boolean(_)
2477            | OnionObject::Integer(_)
2478            | OnionObject::Float(_)
2479            | OnionObject::String(_)
2480            | OnionObject::Bytes(_)
2481            | OnionObject::Null
2482            | OnionObject::Undefined(_)
2483            | OnionObject::Range(_, _)
2484            | OnionObject::InstructionPackage(_) => GCArcStorage::None,
2485            _ => {
2486                let mut arcs = vec![];
2487                obj.upgrade(&mut arcs);
2488                match arcs.len() {
2489                    0 => GCArcStorage::None,
2490                    1 => GCArcStorage::Single(arcs[0].clone()),
2491                    _ => GCArcStorage::Multiple(Arc::new(arcs)),
2492                }
2493            }
2494        };
2495        OnionStaticObject {
2496            obj: obj,
2497            _arcs: arcs,
2498        }
2499    }
2500
2501    #[inline(always)]
2502    pub fn weak(&self) -> &OnionObject {
2503        &self.obj
2504    }
2505
2506    #[inline(always)]
2507    /// 将值装箱成可变容器,严格遵循幂等律的情况下,Cell里不可能出现Mut对象。
2508    /// 也就是说,mut mut x和mut x是等价的。
2509    pub fn mutablize(self, gc: &mut GC<OnionObjectCell>) -> OnionStaticObject {
2510        match self.weak() {
2511            OnionObject::Mut(_) => self,
2512            v => v.clone().mutablize(gc),
2513        }
2514    }
2515
2516    #[inline(always)]
2517    /// 将值从可变容器中卸载,严格遵循幂等律
2518    /// 也就是说,const const x和const x是等价的。
2519    pub fn immutablize(self) -> Result<OnionStaticObject, RuntimeError> {
2520        match self.weak() {
2521            OnionObject::Mut(v) => match v.upgrade() {
2522                None => Err(RuntimeError::BrokenReference),
2523                Some(arc) => match arc.as_ref().0.read() {
2524                    Ok(data) => Ok(OnionStaticObject::new(data.clone())),
2525                    Err(_) => Err(RuntimeError::BrokenReference),
2526                },
2527            },
2528            _ => Ok(self),
2529        }
2530    }
2531}
2532
2533/// 解包对象的宏,简化错误处理。
2534#[macro_export]
2535macro_rules! unwrap_object {
2536    ($obj:expr, $variant:path) => {
2537        match $obj {
2538            $variant(o) => Ok(o),
2539            _ => Err(RuntimeError::InvalidType(
2540                format!("Expected {}, found {:?}", stringify!($variant), $obj).into(),
2541            )),
2542        }
2543    };
2544}
2545
2546#[cfg(test)]
2547mod tests {
2548    use super::*;
2549    use std::time::Instant;
2550
2551    #[test]
2552    fn test_detailed_memory_sizes() {
2553        println!("详细内存分析:");
2554        println!(
2555            "OnionObjectCell: {} bytes",
2556            std::mem::size_of::<OnionObjectCell>()
2557        );
2558        println!("OnionObject: {} bytes", std::mem::size_of::<OnionObject>());
2559        println!(
2560            "OnionStaticObject: {} bytes",
2561            std::mem::size_of::<OnionStaticObject>()
2562        );
2563        println!(
2564            "GCArcStorage: {} bytes",
2565            std::mem::size_of::<GCArcStorage>()
2566        );
2567        println!(
2568            "GCArc<OnionObjectCell>: {} bytes",
2569            std::mem::size_of::<GCArc<OnionObjectCell>>()
2570        );
2571        println!("Arc<String>: {} bytes", std::mem::size_of::<Arc<String>>());
2572        println!(
2573            "Arc<Vec<u8>>: {} bytes",
2574            std::mem::size_of::<Arc<Vec<u8>>>()
2575        );
2576        println!(
2577            "GCArcWeak<OnionObjectCell>: {} bytes",
2578            std::mem::size_of::<GCArcWeak<OnionObjectCell>>()
2579        );
2580        println!("OnionTuple: {} bytes", std::mem::size_of::<OnionTuple>());
2581        println!("OnionPair: {} bytes", std::mem::size_of::<OnionPair>());
2582        println!(
2583            "OnionLazySet: {} bytes",
2584            std::mem::size_of::<OnionLazySet>()
2585        );
2586    }
2587
2588    #[test]
2589    fn benchmark_realistic_vm_operations() {
2590        println!("真实VM操作性能测试 (使用OnionStaticObject + clone):");
2591
2592        // 模拟VM中的整数运算
2593        let start = Instant::now();
2594        let mut result_sum = 0i64;
2595
2596        for i in 0..5_000_000 {
2597            // 创建OnionStaticObject(模拟从栈或常量池加载)
2598            let obj1 = OnionObject::Integer(i).stabilize();
2599            let obj2 = OnionObject::Integer(i + 1).stabilize();
2600
2601            // 通过with_data访问(模拟VM的实际访问模式)
2602            let result = obj1.weak().with_data(|data1| {
2603                obj2.weak().with_data(|data2| {
2604                    // 模拟binary_add操作
2605                    match (data1, data2) {
2606                        (OnionObject::Integer(a), OnionObject::Integer(b)) => {
2607                            Ok(OnionObject::Integer(a + b).stabilize())
2608                        }
2609                        _ => Err(RuntimeError::InvalidOperation("Type error".into())),
2610                    }
2611                })
2612            });
2613
2614            if let Ok(sum) = result {
2615                // 提取结果值(模拟VM获取计算结果)
2616                if let Ok(val) = sum.weak().with_data(|data| match data {
2617                    OnionObject::Integer(v) => Ok(*v),
2618                    _ => Err(RuntimeError::InvalidType("Not integer".into())),
2619                }) {
2620                    result_sum += val;
2621                }
2622            }
2623        }
2624
2625        let duration = start.elapsed();
2626        println!("500万次VM风格整数运算: {:.2}s", duration.as_secs_f64());
2627        println!("每秒操作数: {:.0}", 5_000_000.0 / duration.as_secs_f64());
2628        println!("结果校验: {}", result_sum);
2629    }
2630
2631    #[test]
2632    fn benchmark_vm_style_arithmetic() {
2633        println!("VM风格算术运算性能测试:");
2634
2635        let start = Instant::now();
2636        let mut final_result = 0i64;
2637
2638        for i in 0..2_000_000 {
2639            // 创建操作数
2640            let left = OnionObject::Integer(i).stabilize();
2641            let right = OnionObject::Integer(i + 1).stabilize();
2642
2643            // 使用实际的binary_add方法
2644            if let Ok(result) = left
2645                .weak()
2646                .with_data(|l_data| right.weak().with_data(|r_data| l_data.binary_add(r_data)))
2647            {
2648                // 继续进行乘法运算
2649                let multiplier = OnionObject::Integer(2).stabilize();
2650                if let Ok(mul_result) = result.weak().with_data(|add_data| {
2651                    multiplier
2652                        .weak()
2653                        .with_data(|mul_data| add_data.binary_mul(mul_data))
2654                }) {
2655                    // 提取最终结果
2656                    if let Ok(val) = mul_result.weak().with_data(|data| data.to_integer()) {
2657                        final_result += val;
2658                    }
2659                }
2660            }
2661        }
2662
2663        let duration = start.elapsed();
2664        println!("200万次复合运算: {:.2}s", duration.as_secs_f64());
2665        println!("每秒操作数: {:.0}", 2_000_000.0 / duration.as_secs_f64());
2666        println!("最终结果: {}", final_result);
2667    }
2668
2669    #[test]
2670    fn benchmark_object_creation_overhead() {
2671        println!("对象创建开销测试:");
2672
2673        // 测试OnionStaticObject创建性能
2674        let start = Instant::now();
2675        let mut objects = Vec::with_capacity(1_000_000);
2676
2677        for i in 0..1_000_000 {
2678            let obj = OnionObject::Integer(i).stabilize();
2679            objects.push(obj);
2680        }
2681
2682        let creation_time = start.elapsed();
2683        println!(
2684            "100万个OnionStaticObject创建: {:.2}s",
2685            creation_time.as_secs_f64()
2686        );
2687
2688        // 测试访问性能
2689        let start = Instant::now();
2690        let mut sum = 0i64;
2691
2692        for obj in &objects {
2693            if let Ok(val) = obj.weak().with_data(|data| data.to_integer()) {
2694                sum += val;
2695            }
2696        }
2697
2698        let access_time = start.elapsed();
2699        println!("100万次对象访问: {:.2}s", access_time.as_secs_f64());
2700        println!("访问校验和: {}", sum);
2701
2702        // 测试克隆性能
2703        let start = Instant::now();
2704        let mut cloned_objects = Vec::with_capacity(objects.len());
2705
2706        for obj in &objects[..100_000] {
2707            // 只测试10万个避免内存不足
2708            cloned_objects.push(obj.clone());
2709        }
2710
2711        let clone_time = start.elapsed();
2712        println!("10万个对象克隆: {:.2}s", clone_time.as_secs_f64());
2713    }
2714
2715    #[test]
2716    fn benchmark_string_operations_realistic() {
2717        println!("真实字符串操作性能测试:");
2718
2719        let start = Instant::now();
2720        let mut total_length = 0usize;
2721
2722        for i in 0..500_000 {
2723            // 创建字符串对象
2724            let str_obj = OnionObject::String(Arc::from(format!("string_{}", i))).stabilize();
2725
2726            // 获取字符串长度(模拟len()操作)
2727            if let Ok(len_obj) = str_obj.weak().with_data(|data| data.len()) {
2728                if let Ok(length) = len_obj.weak().with_data(|data| data.to_integer()) {
2729                    total_length += length as usize;
2730                }
2731            }
2732
2733            // 字符串拼接操作
2734            let suffix = OnionObject::String(Arc::from("_suffix".to_string())).stabilize();
2735            if let Ok(concat_result) = str_obj.weak().with_data(|str_data| {
2736                suffix
2737                    .weak()
2738                    .with_data(|suffix_data| str_data.binary_add(suffix_data))
2739            }) {
2740                // 模拟使用拼接结果
2741                if let Ok(concat_str) = concat_result
2742                    .weak()
2743                    .with_data(|data| data.to_string(&mut vec![]))
2744                {
2745                    total_length += concat_str.len();
2746                }
2747            }
2748        }
2749
2750        let duration = start.elapsed();
2751        println!("50万次字符串操作: {:.2}s", duration.as_secs_f64());
2752        println!("每秒操作数: {:.0}", 500_000.0 / duration.as_secs_f64());
2753        println!("总字符串长度: {}", total_length);
2754    }
2755
2756    #[test]
2757    fn benchmark_refcell_overhead() {
2758        println!("RefCell开销分析:");
2759
2760        // 测试直接访问vs RefCell访问的性能差异
2761        let direct_integers: Vec<i64> = (0..1_000_000).collect();
2762        let wrapped_integers: Vec<OnionStaticObject> = (0..1_000_000)
2763            .map(|i| OnionObject::Integer(i).stabilize())
2764            .collect();
2765
2766        // 直接访问基准
2767        let start = Instant::now();
2768        let mut sum1 = 0i64;
2769        for &val in &direct_integers {
2770            sum1 += val * 2;
2771        }
2772        let direct_time = start.elapsed();
2773
2774        // RefCell访问
2775        let start = Instant::now();
2776        let mut sum2 = 0i64;
2777        for obj in &wrapped_integers {
2778            if let Ok(val) = obj.weak().with_data(|data| match data {
2779                OnionObject::Integer(i) => Ok(*i),
2780                _ => Err(RuntimeError::InvalidType("Not integer".into())),
2781            }) {
2782                sum2 += val * 2;
2783            }
2784        }
2785        let refcell_time = start.elapsed();
2786
2787        println!("直接访问100万个i64: {:.2}s", direct_time.as_secs_f64());
2788        println!(
2789            "RefCell访问100万个OnionObject: {:.2}s",
2790            refcell_time.as_secs_f64()
2791        );
2792        println!(
2793            "RefCell开销倍数: {:.1}x",
2794            refcell_time.as_secs_f64() / direct_time.as_secs_f64()
2795        );
2796        println!("校验: {} vs {}", sum1, sum2);
2797    }
2798}