onion_vm/types/
object.rs

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