1#![macro_use]
6
7#[cfg(feature = "async")]
8use crate::channel::Channel;
9use crate::ffi::Ffi;
10use crate::gc::GcContainer;
11use crate::instruction::{Instruction, OpIndex, ValueType};
12use crate::metadata::*;
13use crate::stack::Stack;
14use crate::value::*;
15
16#[cfg(feature = "serde_borsh")]
17use borsh::{
18 maybestd::io::Result as BorshResult, maybestd::io::Write as BorshWrite, BorshDeserialize,
19 BorshSerialize,
20};
21use go_parser::{Map, MapIter, PiggyVecKey};
22use std::any::Any;
23use std::borrow::Cow;
24use std::cell::{Cell, Ref, RefCell, RefMut};
25use std::cmp::Ordering;
26use std::fmt::{self, Debug, Display, Write};
27use std::hash::{Hash, Hasher};
28use std::marker::PhantomData;
29use std::ops::Range;
30use std::rc::{Rc, Weak};
31use std::{panic, ptr, str};
32
33pub type GosMap = Map<GosValue, GosValue>;
37
38pub type GosMapIter<'a> = MapIter<'a, GosValue, GosValue>;
39
40#[derive(Debug)]
41pub struct MapObj {
42 map: RefCell<GosMap>,
43}
44
45impl MapObj {
46 #[inline]
47 pub fn new() -> MapObj {
48 Self::with_data(Map::new())
49 }
50
51 #[inline]
52 pub fn with_data(data: GosMap) -> MapObj {
53 MapObj {
54 map: RefCell::new(data),
55 }
56 }
57
58 #[inline]
59 pub fn insert(&self, key: GosValue, val: GosValue) -> Option<GosValue> {
60 self.borrow_data_mut().insert(key, val)
61 }
62
63 #[inline]
64 pub fn get(&self, key: &GosValue) -> Option<GosValue> {
65 let borrow = self.borrow_data();
66 let val = borrow.get(key);
67 match val {
68 Some(v) => Some(v.clone()),
69 None => None,
70 }
71 }
72
73 #[inline]
74 pub fn delete(&self, key: &GosValue) {
75 let mut mref = self.borrow_data_mut();
76 mref.remove(key);
77 }
78
79 #[inline]
80 pub fn len(&self) -> usize {
81 self.borrow_data().len()
82 }
83
84 #[inline]
85 pub fn borrow_data_mut(&self) -> RefMut<GosMap> {
86 self.map.borrow_mut()
87 }
88
89 #[inline]
90 pub fn borrow_data(&self) -> Ref<GosMap> {
91 self.map.borrow()
92 }
93
94 #[inline]
95 pub fn clone_inner(&self) -> RefCell<GosMap> {
96 self.map.clone()
97 }
98}
99
100impl Clone for MapObj {
101 fn clone(&self) -> Self {
102 MapObj {
103 map: self.map.clone(),
104 }
105 }
106}
107
108impl PartialEq for MapObj {
109 fn eq(&self, _other: &MapObj) -> bool {
110 unreachable!()
111 }
112}
113
114impl Eq for MapObj {}
115
116impl Display for MapObj {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 f.write_str("map[")?;
119 for (i, kv) in self.map.borrow().iter().enumerate() {
120 if i > 0 {
121 f.write_char(' ')?;
122 }
123 let v: &GosValue = &kv.1;
124 write!(f, "{}:{}", kv.0, v)?
125 }
126 f.write_char(']')
127 }
128}
129
130pub trait Element: Clone + Hash + Debug {
135 fn from_value(val: GosValue) -> Self;
136
137 fn into_value(self, t: ValueType) -> GosValue;
138
139 fn set_value(&self, val: &GosValue);
140
141 fn need_gc() -> bool {
142 false
143 }
144
145 fn copy_or_clone_slice(dst: &mut [Self], src: &[Self]) {
146 dst.clone_from_slice(src)
147 }
148}
149
150#[derive(Clone, PartialEq, Eq, Debug, PartialOrd, Ord)]
151pub struct GosElem {
152 cell: RefCell<GosValue>,
153}
154
155impl GosElem {
156 pub fn ref_sub_one(&self) {
158 self.cell.borrow().ref_sub_one();
159 }
160
161 pub fn mark_dirty(&self, queue: &mut RCQueue) {
163 self.cell.borrow().mark_dirty(queue);
164 }
165
166 pub fn borrow(&self) -> Ref<GosValue> {
167 self.cell.borrow()
168 }
169
170 pub fn borrow_mut(&self) -> RefMut<GosValue> {
171 self.cell.borrow_mut()
172 }
173}
174
175impl std::fmt::Display for GosElem {
176 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
177 std::fmt::Display::fmt(&self.cell.borrow(), f)
178 }
179}
180
181impl Hash for GosElem {
182 fn hash<H: Hasher>(&self, state: &mut H) {
183 self.cell.borrow().hash(state)
184 }
185}
186
187impl Element for GosElem {
188 #[inline]
189 fn from_value(val: GosValue) -> Self {
190 GosElem {
191 cell: RefCell::new(val),
192 }
193 }
194
195 #[inline]
196 fn into_value(self, t: ValueType) -> GosValue {
197 let v = self.cell.into_inner();
198 assert!(v.typ() == t);
199 v
200 }
201
202 #[inline]
203 fn set_value(&self, val: &GosValue) {
204 self.cell.replace(val.clone());
205 }
206
207 #[inline]
208 fn need_gc() -> bool {
209 true
210 }
211}
212
213#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
215#[derive(Clone, PartialEq, Eq, Debug, PartialOrd, Ord)]
216pub struct CellElem<T>
217where
218 T: Copy + PartialEq,
219{
220 pub cell: Cell<T>,
221}
222
223impl<T> CellElem<T>
224where
225 T: Copy + PartialEq,
226{
227 #[inline]
228 pub fn into_inner(self) -> T {
229 self.cell.into_inner()
230 }
231
232 #[inline]
233 pub fn slice_into_inner<U>(inner_slice: &[Self]) -> &[U] {
234 assert!(core::mem::size_of::<T>() == core::mem::size_of::<U>());
235 unsafe { std::mem::transmute(inner_slice) }
236 }
237
238 #[inline]
239 pub fn slice_into_inner_mut<U>(inner_slice: &mut [Self]) -> &mut [U] {
240 assert!(core::mem::size_of::<T>() == core::mem::size_of::<U>());
241 unsafe { std::mem::transmute(inner_slice) }
242 }
243
244 #[inline]
245 pub fn slice_ref_into_inner<U>(inner_slice: Ref<[Self]>) -> Ref<[U]> {
246 assert!(core::mem::size_of::<T>() == core::mem::size_of::<U>());
247 unsafe { std::mem::transmute(inner_slice) }
248 }
249
250 #[inline]
251 pub fn slice_ref_into_inner_mut<U>(inner_slice: RefMut<[Self]>) -> RefMut<[U]> {
252 assert!(core::mem::size_of::<T>() == core::mem::size_of::<U>());
253 unsafe { std::mem::transmute(inner_slice) }
254 }
255
256 #[inline]
257 fn clone_slice(dst: &mut [Self], src: &[Self]) {
258 let d: &mut [T] = Self::slice_into_inner_mut(dst);
259 let s: &[T] = &Self::slice_into_inner(src);
260 d.copy_from_slice(s)
261 }
262}
263
264pub trait CellData: Copy + PartialEq + Hash + Debug {
265 fn from_value(val: &GosValue) -> Self;
266
267 fn into_value(self, t: ValueType) -> GosValue;
268}
269
270macro_rules! impl_cell_data {
271 ($typ:ty, $as:tt, $value_type:tt, $new:tt) => {
272 impl CellData for $typ {
273 fn from_value(val: &GosValue) -> Self {
274 *val.$as()
275 }
276
277 fn into_value(self, t: ValueType) -> GosValue {
278 GosValue::new(t, ValueData::$new(self))
279 }
280 }
281 };
282}
283
284impl_cell_data!(u8, as_uint8, Uint8, new_uint8);
285impl_cell_data!(u16, as_uint16, Uint16, new_uint16);
286impl_cell_data!(u32, as_uint32, Uint32, new_uint32);
287impl_cell_data!(u64, as_uint64, Uint64, new_uint64);
288impl_cell_data!(usize, as_uint, Uint, new_uint);
289
290pub type Elem8 = CellElem<u8>;
291pub type Elem16 = CellElem<u16>;
292pub type Elem32 = CellElem<u32>;
293pub type Elem64 = CellElem<u64>;
294pub type ElemWord = CellElem<usize>;
295
296pub type AnyElem = CellElem<u8>;
299
300impl<T> Hash for CellElem<T>
301where
302 T: CellData,
303{
304 fn hash<H: Hasher>(&self, state: &mut H) {
305 let d = self.cell.get();
306 d.hash(state)
307 }
308}
309
310impl<T> Element for CellElem<T>
311where
312 T: CellData,
313{
314 #[inline]
315 fn from_value(val: GosValue) -> Self {
316 CellElem {
317 cell: Cell::new(T::from_value(&val)),
318 }
319 }
320
321 #[inline]
322 fn into_value(self, t: ValueType) -> GosValue {
323 self.cell.get().into_value(t)
324 }
325
326 #[inline]
327 fn set_value(&self, val: &GosValue) {
328 self.cell.set(T::from_value(val));
329 }
330
331 #[inline]
332 fn copy_or_clone_slice(dst: &mut [Self], src: &[Self]) {
333 Self::clone_slice(dst, src)
334 }
335}
336
337pub struct ArrayObj<T> {
338 vec: RefCell<Vec<T>>,
339}
340
341pub type GosArrayObj = ArrayObj<GosElem>;
342
343impl<T> ArrayObj<T>
344where
345 T: Element,
346{
347 pub(crate) fn with_size(
348 size: usize,
349 cap: usize,
350 val: &GosValue,
351 gcos: &GcContainer,
352 ) -> ArrayObj<T> {
353 assert!(cap >= size);
354 let mut v = Vec::with_capacity(cap);
355 for _ in 0..size {
356 v.push(T::from_value(val.copy_semantic(gcos)))
357 }
358 ArrayObj {
359 vec: RefCell::new(v),
360 }
361 }
362
363 pub fn with_data(data: Vec<GosValue>) -> ArrayObj<T> {
364 ArrayObj {
365 vec: RefCell::new(data.into_iter().map(|x| T::from_value(x)).collect()),
366 }
367 }
368
369 pub fn with_raw_data(data: Vec<T>) -> ArrayObj<T> {
370 ArrayObj {
371 vec: RefCell::new(data),
372 }
373 }
374
375 #[inline(always)]
376 pub fn len(&self) -> usize {
377 self.borrow_data().len()
378 }
379
380 #[inline(always)]
381 pub fn borrow_data_mut(&self) -> std::cell::RefMut<Vec<T>> {
382 self.vec.borrow_mut()
383 }
384
385 #[inline(always)]
386 pub fn borrow_data(&self) -> std::cell::Ref<Vec<T>> {
387 self.vec.borrow()
388 }
389
390 #[inline]
391 pub fn as_rust_slice(&self) -> Ref<[T]> {
392 Ref::map(self.borrow_data(), |x| &x[..])
393 }
394
395 #[inline]
396 pub fn as_rust_slice_mut(&self) -> RefMut<[T]> {
397 RefMut::map(self.borrow_data_mut(), |x| &mut x[..])
398 }
399
400 #[inline(always)]
401 pub fn index_elem(&self, i: usize) -> T {
402 self.borrow_data()[i].clone()
403 }
404
405 #[inline(always)]
406 pub fn get(&self, i: usize, t: ValueType) -> RuntimeResult<GosValue> {
407 if i >= self.len() {
408 return Err(format!("index {} out of range", i).to_owned().into());
409 }
410 Ok(self.borrow_data()[i].clone().into_value(t))
411 }
412
413 #[inline(always)]
414 pub fn set(&self, i: usize, val: &GosValue) -> RuntimeResult<()> {
415 if i >= self.len() {
416 return Err(format!("index {} out of range", i).to_owned().into());
417 }
418 Ok(self.borrow_data()[i].set_value(&val))
419 }
420
421 #[inline]
422 pub fn size_of_data(&self) -> usize {
423 std::mem::size_of::<T>() * self.len()
424 }
425}
426
427impl<T> ArrayObj<CellElem<T>>
428where
429 T: CellData,
430{
431 #[inline]
432 pub fn as_raw_slice<U>(&self) -> Ref<[U]> {
433 CellElem::<T>::slice_ref_into_inner(self.as_rust_slice())
434 }
435
436 #[inline]
437 pub fn as_raw_slice_mut<U>(&self) -> RefMut<[U]> {
438 CellElem::<T>::slice_ref_into_inner_mut(self.as_rust_slice_mut())
439 }
440}
441
442impl<T> Hash for ArrayObj<T>
443where
444 T: Element,
445{
446 fn hash<H: Hasher>(&self, state: &mut H) {
447 for e in self.borrow_data().iter() {
448 e.hash(state);
449 }
450 }
451}
452
453impl<T> Eq for ArrayObj<T> where T: Element + PartialEq {}
454
455impl<T> PartialEq for ArrayObj<T>
456where
457 T: Element + PartialEq,
458{
459 fn eq(&self, b: &ArrayObj<T>) -> bool {
460 if self.borrow_data().len() != b.borrow_data().len() {
461 return false;
462 }
463 let bdata = b.borrow_data();
464 for (i, e) in self.borrow_data().iter().enumerate() {
465 if e != bdata.get(i).unwrap() {
466 return false;
467 }
468 }
469 true
470 }
471}
472
473impl<T> PartialOrd for ArrayObj<T>
474where
475 T: Element + PartialEq + Ord,
476{
477 #[inline]
478 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
479 Some(self.cmp(other))
480 }
481}
482
483impl<T> Ord for ArrayObj<T>
484where
485 T: Element + PartialEq + Ord,
486{
487 fn cmp(&self, other: &Self) -> Ordering {
488 let a = self.borrow_data();
489 let b = other.borrow_data();
490 let order = a.len().cmp(&b.len());
491 if order != Ordering::Equal {
492 return order;
493 }
494 for (i, elem) in self.borrow_data().iter().enumerate() {
495 let order = elem.cmp(&b[i]);
496 if order != Ordering::Equal {
497 return order;
498 }
499 }
500
501 Ordering::Equal
502 }
503}
504
505impl<T> Clone for ArrayObj<T>
506where
507 T: Element + PartialEq,
508{
509 fn clone(&self) -> Self {
510 ArrayObj {
511 vec: RefCell::new(self.borrow_data().iter().map(|x| x.clone()).collect()),
512 }
513 }
514}
515
516#[derive(Clone)]
520pub struct SliceObj<T> {
521 array: GosValue,
522 begin: Cell<usize>,
523 end: Cell<usize>,
524 cap_end: Cell<usize>,
526 phantom: PhantomData<T>,
527}
528
529pub type GosSliceObj = SliceObj<GosElem>;
530
531impl<T> SliceObj<T>
532where
533 T: Element,
534{
535 pub fn with_array(arr: GosValue, begin: isize, end: isize) -> RuntimeResult<SliceObj<T>> {
536 let len = arr.as_array::<T>().0.len();
537 let (bi, ei, cap) = SliceObj::<T>::check_indices(0, len, len, begin, end, -1)?;
538 Ok(SliceObj {
539 begin: Cell::from(bi),
540 end: Cell::from(ei),
541 cap_end: Cell::from(cap),
542 array: arr,
543 phantom: PhantomData,
544 })
545 }
546
547 #[must_use]
549 #[inline]
550 pub fn array(&self) -> &GosValue {
551 &self.array
552 }
553
554 #[inline(always)]
555 pub fn array_obj(&self) -> &ArrayObj<T> {
556 &self.array.as_array::<T>().0
557 }
558
559 #[inline(always)]
560 pub fn begin(&self) -> usize {
561 self.begin.get()
562 }
563
564 #[inline(always)]
565 pub fn end(&self) -> usize {
566 self.end.get()
567 }
568
569 #[inline(always)]
570 pub fn len(&self) -> usize {
571 self.end() - self.begin()
572 }
573
574 #[inline(always)]
575 pub fn cap(&self) -> usize {
576 self.cap_end.get() - self.begin()
577 }
578
579 #[inline(always)]
580 pub fn range(&self) -> Range<usize> {
581 self.begin.get()..self.end.get()
582 }
583
584 #[inline]
585 pub fn as_rust_slice(&self) -> Ref<[T]> {
586 Ref::map(self.borrow_all_data(), |x| {
587 &x[self.begin.get()..self.end.get()]
588 })
589 }
590
591 #[inline]
592 pub fn as_rust_slice_mut(&self) -> RefMut<[T]> {
593 RefMut::map(self.borrow_all_data_mut(), |x| {
594 &mut x[self.begin.get()..self.end.get()]
595 })
596 }
597
598 #[inline]
599 pub fn sharing_with(&self, other: &SliceObj<T>) -> bool {
600 self.array.as_addr() == other.array.as_addr()
601 }
602
603 #[inline]
605 pub fn get_array_equivalent(&self, i: usize) -> (&GosValue, usize) {
606 (self.array(), self.begin() + i)
607 }
608
609 #[inline(always)]
610 pub fn index_elem(&self, i: usize) -> T {
611 self.array_obj().index_elem(self.begin() + i)
612 }
613
614 #[inline(always)]
615 pub fn get(&self, i: usize, t: ValueType) -> RuntimeResult<GosValue> {
616 self.array_obj().get(self.begin() + i, t)
617 }
618
619 #[inline(always)]
620 pub fn set(&self, i: usize, val: &GosValue) -> RuntimeResult<()> {
621 self.array_obj().set(i, val)
622 }
623
624 #[inline]
625 pub fn push(&mut self, val: GosValue) {
626 let mut data = self.borrow_all_data_mut();
627 if data.len() == self.len() {
628 data.push(T::from_value(val))
629 } else {
630 data[self.end()] = T::from_value(val);
631 }
632 drop(data);
633 *self.end.get_mut() += 1;
634 if self.cap_end.get() < self.end.get() {
635 *self.cap_end.get_mut() += 1;
636 }
637 }
638
639 #[inline]
640 pub fn append(&mut self, other: &SliceObj<T>) {
641 let mut data = self.borrow_all_data_mut();
642 let new_end = self.end() + other.len();
643 let after_end_len = data.len() - self.end();
644 let sharing = self.sharing_with(other);
645 if after_end_len <= other.len() {
646 data.truncate(self.end());
647 if !sharing {
648 data.extend_from_slice(&other.as_rust_slice());
649 } else {
650 data.extend_from_within(other.range());
651 }
652 } else {
653 if !sharing {
654 T::copy_or_clone_slice(&mut data[self.end()..new_end], &other.as_rust_slice());
655 } else {
656 let cloned = data[other.range()].to_vec();
657 T::copy_or_clone_slice(&mut data[self.end()..new_end], &cloned);
658 }
659 }
660 drop(data);
661 *self.end.get_mut() = new_end;
662 if self.cap_end.get() < self.end.get() {
663 *self.cap_end.get_mut() = self.end.get();
664 }
665 }
666
667 #[inline]
668 pub fn copy_from(&self, other: &SliceObj<T>) -> usize {
669 let other_range = other.range();
670 let (left, right) = match self.len() >= other.len() {
671 true => (self.begin()..self.begin() + other.len(), other_range),
672 false => (
673 self.begin()..self.end(),
674 other_range.start..other_range.start + self.len(),
675 ),
676 };
677 let len = left.len();
678 let sharing = self.sharing_with(other);
679 let data = &mut self.borrow_all_data_mut();
680 if !sharing {
681 T::copy_or_clone_slice(&mut data[left], &other.borrow_all_data()[right]);
682 } else {
683 let cloned = data[right].to_vec();
684 T::copy_or_clone_slice(&mut data[left], &cloned);
685 }
686 len
687 }
688
689 #[inline]
690 pub fn slice(&self, begin: isize, end: isize, max: isize) -> RuntimeResult<SliceObj<T>> {
691 let (bi, ei, cap) = SliceObj::<T>::check_indices(
692 self.begin(),
693 self.len(),
694 self.cap_end.get(),
695 begin,
696 end,
697 max,
698 )?;
699 Ok(SliceObj {
700 begin: Cell::from(bi),
701 end: Cell::from(ei),
702 cap_end: Cell::from(cap),
703 array: self.array.clone(),
704 phantom: PhantomData,
705 })
706 }
707
708 #[inline]
709 pub fn swap(&self, i: usize, j: usize) -> RuntimeResult<()> {
710 let len = self.len();
711 if i >= len {
712 Err(format!("index {} out of range", i).into())
713 } else if j >= len {
714 Err(format!("index {} out of range", j).into())
715 } else {
716 self.borrow_all_data_mut()
717 .swap(i + self.begin(), j + self.begin());
718 Ok(())
719 }
720 }
721
722 #[inline]
723 fn borrow_all_data_mut(&self) -> std::cell::RefMut<Vec<T>> {
724 self.array_obj().borrow_data_mut()
725 }
726
727 #[inline]
728 fn borrow_all_data(&self) -> std::cell::Ref<Vec<T>> {
729 self.array_obj().borrow_data()
730 }
731
732 #[inline]
733 fn check_indices(
734 this_begin: usize,
735 this_len: usize,
736 this_cap: usize,
737 begin: isize,
738 end: isize,
739 max: isize,
740 ) -> RuntimeResult<(usize, usize, usize)> {
741 let bi = this_begin + begin as usize;
742 if bi > this_cap {
743 return Err(format!("index {} out of range", begin).to_owned().into());
744 }
745
746 let cap = if max < 0 {
747 this_cap
748 } else {
749 let val = max as usize;
750 if val > this_cap {
751 return Err(format!("index {} out of range", max).to_owned().into());
752 }
753 val
754 };
755
756 let ei = if end < 0 {
757 this_len
758 } else {
759 let val = this_begin + end as usize;
760 if val < bi || val > cap {
761 return Err(format!("index {} out of range", end).to_owned().into());
762 }
763 val
764 };
765
766 Ok((bi, ei, cap))
767 }
768}
769
770impl<T> SliceObj<CellElem<T>>
771where
772 T: CellData,
773{
774 #[inline]
775 pub fn as_raw_slice<U>(&self) -> Ref<[U]> {
776 CellElem::<T>::slice_ref_into_inner(self.as_rust_slice())
777 }
778
779 #[inline]
780 pub fn as_raw_slice_mut<U>(&self) -> RefMut<[U]> {
781 CellElem::<T>::slice_ref_into_inner_mut(self.as_rust_slice_mut())
782 }
783}
784
785impl<T> PartialEq for SliceObj<T> {
786 fn eq(&self, _other: &SliceObj<T>) -> bool {
787 unreachable!() }
789}
790
791impl<T> Eq for SliceObj<T> {}
792
793pub type SliceIter<'a, T> = std::slice::Iter<'a, T>;
794
795pub type SliceEnumIter<'a, T> = std::iter::Enumerate<SliceIter<'a, T>>;
796
797pub type StringIter<'a> = std::str::Chars<'a>;
801
802pub type StringEnumIter<'a> = std::iter::Enumerate<StringIter<'a>>;
803
804pub type StringObj = SliceObj<Elem8>;
805
806impl StringObj {
807 #[inline]
808 pub fn with_str(s: &str) -> StringObj {
809 let buf: Vec<Elem8> = unsafe { std::mem::transmute(s.as_bytes().to_vec()) };
810 Self::with_buf(buf)
811 }
812
813 #[inline]
814 fn with_buf(buf: Vec<Elem8>) -> StringObj {
815 let arr = GosValue::new_non_gc_array(ArrayObj::with_raw_data(buf), ValueType::Uint8);
816 SliceObj::with_array(arr, 0, -1).unwrap()
817 }
818
819 #[inline]
823 pub fn as_str(&self) -> Ref<str> {
824 unsafe { std::mem::transmute(self.as_rust_slice()) }
825 }
826
827 #[inline]
828 pub fn index(&self, i: usize) -> RuntimeResult<GosValue> {
829 self.get(i, ValueType::Uint8)
830 }
831
832 #[inline]
833 pub fn index_elem_u8(&self, i: usize) -> u8 {
834 self.index_elem(i).into_inner()
835 }
836
837 #[inline]
838 pub fn add(&self, other: &StringObj) -> StringObj {
839 let mut buf = self.as_rust_slice().to_vec();
840 buf.extend_from_slice(&other.as_rust_slice());
841 Self::with_buf(buf)
842 }
843}
844
845#[derive(Clone, Debug)]
849pub struct StructObj {
850 fields: RefCell<Vec<GosValue>>,
851}
852
853impl StructObj {
854 pub fn new(fields: Vec<GosValue>) -> StructObj {
855 StructObj {
856 fields: RefCell::new(fields),
857 }
858 }
859
860 #[inline]
861 pub fn borrow_fields(&self) -> Ref<Vec<GosValue>> {
862 self.fields.borrow()
863 }
864
865 #[inline]
866 pub fn borrow_fields_mut(&self) -> RefMut<Vec<GosValue>> {
867 self.fields.borrow_mut()
868 }
869}
870
871impl Eq for StructObj {}
872
873impl PartialEq for StructObj {
874 #[inline]
875 fn eq(&self, other: &StructObj) -> bool {
876 let other_fields = other.borrow_fields();
877 for (i, f) in self.borrow_fields().iter().enumerate() {
878 if f != &other_fields[i] {
879 return false;
880 }
881 }
882 return true;
883 }
884}
885
886impl PartialOrd for StructObj {
887 #[inline]
888 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
889 Some(self.cmp(other))
890 }
891}
892
893impl Ord for StructObj {
895 fn cmp(&self, other: &Self) -> Ordering {
896 let other_fields = other.borrow_fields();
897 for (i, f) in self.borrow_fields().iter().enumerate() {
898 let order = f.cmp(&other_fields[i]);
899 if order != Ordering::Equal {
900 return order;
901 }
902 }
903 Ordering::Equal
904 }
905}
906
907impl Hash for StructObj {
908 #[inline]
909 fn hash<H: Hasher>(&self, state: &mut H) {
910 for f in self.borrow_fields().iter() {
911 f.hash(state)
912 }
913 }
914}
915
916impl Display for StructObj {
917 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
918 f.write_char('{')?;
919 for (i, fld) in self.borrow_fields().iter().enumerate() {
920 if i > 0 {
921 f.write_char(' ')?;
922 }
923 write!(f, "{}", fld)?
924 }
925 f.write_char('}')
926 }
927}
928
929#[derive(Clone, Debug)]
933pub struct UnderlyingFfi {
934 pub ffi_obj: Rc<dyn Ffi>,
935 pub meta: Meta,
936}
937
938impl UnderlyingFfi {
939 pub fn new(ffi_obj: Rc<dyn Ffi>, meta: Meta) -> UnderlyingFfi {
940 UnderlyingFfi { ffi_obj, meta }
941 }
942}
943
944#[derive(Clone, Debug)]
947pub enum IfaceBinding {
948 Struct(Rc<RefCell<MethodDesc>>, Option<Vec<OpIndex>>),
949 Iface(usize, Option<Vec<OpIndex>>),
950}
951
952#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
953#[derive(Clone, Debug)]
954pub enum Binding4Runtime {
955 Struct(FunctionKey, bool, Option<Vec<OpIndex>>),
956 Iface(usize, Option<Vec<OpIndex>>),
957}
958
959impl From<IfaceBinding> for Binding4Runtime {
960 fn from(item: IfaceBinding) -> Binding4Runtime {
961 match item {
962 IfaceBinding::Struct(f, indices) => {
963 let md = f.borrow();
964 Binding4Runtime::Struct(md.func.unwrap(), md.pointer_recv, indices)
965 }
966 IfaceBinding::Iface(a, b) => Binding4Runtime::Iface(a, b),
967 }
968 }
969}
970
971#[derive(Clone, Debug)]
972pub enum InterfaceObj {
973 Gos(GosValue, Option<(Meta, Vec<Binding4Runtime>)>),
980 Ffi(UnderlyingFfi),
981}
982
983impl InterfaceObj {
984 pub fn with_value(val: GosValue, meta: Option<(Meta, Vec<Binding4Runtime>)>) -> InterfaceObj {
985 InterfaceObj::Gos(val, meta)
986 }
987
988 #[inline]
989 pub fn underlying_value(&self) -> Option<&GosValue> {
990 match self {
991 Self::Gos(v, _) => Some(v),
992 _ => None,
993 }
994 }
995
996 #[inline]
997 pub fn equals_value(&self, val: &GosValue) -> bool {
998 match self.underlying_value() {
999 Some(v) => v == val,
1000 None => false,
1001 }
1002 }
1003
1004 pub fn ref_sub_one(&self) {
1006 match self {
1007 Self::Gos(v, _) => v.ref_sub_one(),
1008 _ => {}
1009 };
1010 }
1011
1012 pub fn mark_dirty(&self, queue: &mut RCQueue) {
1014 match self {
1015 Self::Gos(v, _) => v.mark_dirty(queue),
1016 _ => {}
1017 };
1018 }
1019}
1020
1021impl Eq for InterfaceObj {}
1022
1023impl PartialEq for InterfaceObj {
1024 #[inline]
1025 fn eq(&self, other: &Self) -> bool {
1026 match (self, other) {
1027 (Self::Gos(x, _), Self::Gos(y, _)) => x == y,
1028 (Self::Ffi(x), Self::Ffi(y)) => Rc::ptr_eq(&x.ffi_obj, &y.ffi_obj),
1029 _ => false,
1030 }
1031 }
1032}
1033
1034impl PartialOrd for InterfaceObj {
1035 #[inline]
1036 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1037 Some(self.cmp(other))
1038 }
1039}
1040
1041impl Ord for InterfaceObj {
1042 fn cmp(&self, other: &Self) -> Ordering {
1043 match (self, other) {
1044 (Self::Gos(x, _), Self::Gos(y, _)) => {
1045 let xt = x.typ();
1046 let yt = y.typ();
1047 if xt == yt {
1048 x.cmp(y)
1049 } else {
1050 xt.cmp(&yt)
1051 }
1052 }
1053 (Self::Ffi(x), Self::Ffi(y)) => Rc::as_ptr(&x.ffi_obj).cmp(&Rc::as_ptr(&y.ffi_obj)),
1054 (Self::Gos(_, _), Self::Ffi(_)) => Ordering::Greater,
1055 (Self::Ffi(_), Self::Gos(_, _)) => Ordering::Less,
1056 }
1057 }
1058}
1059
1060impl Hash for InterfaceObj {
1061 #[inline]
1062 fn hash<H: Hasher>(&self, state: &mut H) {
1063 match self {
1064 Self::Gos(v, _) => v.hash(state),
1065 Self::Ffi(ffi) => Rc::as_ptr(&ffi.ffi_obj).hash(state),
1066 }
1067 }
1068}
1069
1070impl Display for InterfaceObj {
1071 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1072 match self {
1073 Self::Gos(v, _) => write!(f, "{}", v),
1074 Self::Ffi(ffi) => write!(f, "<ffi>{:?}", ffi.ffi_obj),
1075 }
1076 }
1077}
1078
1079#[cfg(feature = "async")]
1082#[derive(Clone, Debug)]
1083pub struct ChannelObj {
1084 pub recv_zero: GosValue,
1085 pub chan: Channel,
1086}
1087
1088#[cfg(feature = "async")]
1089impl ChannelObj {
1090 pub fn new(cap: usize, recv_zero: GosValue) -> ChannelObj {
1091 ChannelObj {
1092 chan: Channel::new(cap),
1093 recv_zero: recv_zero,
1094 }
1095 }
1096
1097 pub fn with_chan(chan: Channel, recv_zero: GosValue) -> ChannelObj {
1098 ChannelObj {
1099 chan: chan,
1100 recv_zero: recv_zero,
1101 }
1102 }
1103
1104 #[inline]
1105 pub fn len(&self) -> usize {
1106 self.chan.len()
1107 }
1108
1109 #[inline]
1110 pub fn cap(&self) -> usize {
1111 self.chan.cap()
1112 }
1113
1114 #[inline]
1115 pub fn close(&self) {
1116 self.chan.close()
1117 }
1118
1119 pub async fn send(&self, v: &GosValue) -> RuntimeResult<()> {
1120 self.chan.send(v).await
1121 }
1122
1123 pub async fn recv(&self) -> Option<GosValue> {
1124 self.chan.recv().await
1125 }
1126}
1127
1128#[derive(Debug, Clone)]
1140pub enum PointerObj {
1141 UpVal(UpValue),
1142 SliceMember(GosValue, OpIndex),
1143 StructField(GosValue, OpIndex),
1144 PkgMember(PackageKey, OpIndex),
1145}
1146
1147impl PointerObj {
1148 #[inline]
1149 pub fn new_closed_up_value(val: &GosValue) -> PointerObj {
1150 PointerObj::UpVal(UpValue::new_closed(val.clone()))
1151 }
1152
1153 #[inline]
1154 pub fn new_slice_member(
1155 val: GosValue,
1156 i: OpIndex,
1157 t: ValueType,
1158 t_elem: ValueType,
1159 ) -> RuntimeResult<PointerObj> {
1160 PointerObj::new_slice_member_internal(val, i, t, &ArrCaller::get_slow(t_elem))
1161 }
1162
1163 #[inline]
1164 pub(crate) fn new_array_member_internal(
1165 val: GosValue,
1166 i: OpIndex,
1167 caller: &Box<dyn Dispatcher>,
1168 ) -> RuntimeResult<PointerObj> {
1169 let slice = GosValue::slice_array(val, 0, -1, caller)?;
1170 Ok(PointerObj::SliceMember(slice, i))
1172 }
1173
1174 #[inline]
1175 pub(crate) fn new_slice_member_internal(
1176 val: GosValue,
1177 i: OpIndex,
1178 t: ValueType,
1179 caller: &Box<dyn Dispatcher>,
1180 ) -> RuntimeResult<PointerObj> {
1181 match t {
1182 ValueType::Array => PointerObj::new_array_member_internal(val, i, caller),
1183 ValueType::Slice => match val.is_nil() {
1184 false => Ok(PointerObj::SliceMember(val, i)),
1185 true => Err("access nil value".to_owned().into()),
1186 },
1187 _ => unreachable!(),
1188 }
1189 }
1190
1191 #[inline]
1192 pub fn deref(&self, stack: &Stack, pkgs: &PackageObjs) -> RuntimeResult<GosValue> {
1193 match self {
1194 PointerObj::UpVal(uv) => Ok(uv.value(stack).into_owned()),
1195 PointerObj::SliceMember(s, index) => s.caller_slow().slice_get(s, *index as usize),
1196 PointerObj::StructField(s, index) => {
1197 Ok(s.as_struct().0.borrow_fields()[*index as usize].clone())
1198 }
1199 PointerObj::PkgMember(pkg, index) => Ok(pkgs[*pkg].member(*index).clone()),
1200 }
1201 }
1202
1203 #[inline]
1206 pub fn cast(
1207 &self,
1208 new_type: ValueType,
1209 stack: &Stack,
1210 pkgs: &PackageObjs,
1211 ) -> RuntimeResult<PointerObj> {
1212 let val = self.deref(stack, pkgs)?;
1213 let val = val.cast(new_type);
1214 Ok(PointerObj::new_closed_up_value(&val))
1215 }
1216
1217 pub fn set_pointee(
1219 &self,
1220 val: &GosValue,
1221 stack: &mut Stack,
1222 pkgs: &PackageObjs,
1223 gcc: &GcContainer,
1224 ) -> RuntimeResult<()> {
1225 match self {
1226 PointerObj::UpVal(uv) => uv.set_value(val.copy_semantic(gcc), stack),
1227 PointerObj::SliceMember(s, index) => {
1228 s.caller_slow()
1229 .slice_set(s, &val.copy_semantic(gcc), *index as usize)?;
1230 }
1231 PointerObj::StructField(s, index) => {
1232 let target: &mut GosValue =
1233 &mut s.as_struct().0.borrow_fields_mut()[*index as usize];
1234 *target = val.copy_semantic(gcc);
1235 }
1236 PointerObj::PkgMember(p, index) => {
1237 let target: &mut GosValue = &mut pkgs[*p].member_mut(*index);
1238 *target = val.copy_semantic(gcc);
1239 }
1240 }
1241 Ok(())
1242 }
1243
1244 pub(crate) fn ref_sub_one(&self) {
1246 match &self {
1247 PointerObj::UpVal(uv) => uv.ref_sub_one(),
1248 PointerObj::SliceMember(s, _) => {
1249 let rc = &s.as_gos_slice().unwrap().1;
1250 rc.set(rc.get() - 1);
1251 }
1252 PointerObj::StructField(s, _) => {
1253 let rc = &s.as_struct().1;
1254 rc.set(rc.get() - 1);
1255 }
1256 _ => {}
1257 };
1258 }
1259
1260 pub(crate) fn mark_dirty(&self, queue: &mut RCQueue) {
1262 match &self {
1263 PointerObj::UpVal(uv) => uv.mark_dirty(queue),
1264 PointerObj::SliceMember(s, _) => {
1265 rcount_mark_and_queue(&s.as_gos_slice().unwrap().1, queue)
1266 }
1267 PointerObj::StructField(s, _) => rcount_mark_and_queue(&s.as_struct().1, queue),
1268 _ => {}
1269 };
1270 }
1271
1272 #[inline]
1273 fn order(&self) -> usize {
1274 match self {
1275 Self::UpVal(_) => 0,
1276 Self::SliceMember(_, _) => 1,
1277 Self::StructField(_, _) => 2,
1278 Self::PkgMember(_, _) => 3,
1279 }
1280 }
1281}
1282
1283impl Eq for PointerObj {}
1284
1285impl PartialEq for PointerObj {
1286 #[inline]
1287 fn eq(&self, other: &PointerObj) -> bool {
1288 match (self, other) {
1289 (Self::UpVal(x), Self::UpVal(y)) => x == y,
1290 (Self::SliceMember(x, ix), Self::SliceMember(y, iy)) => {
1291 x.as_addr() == y.as_addr() && ix == iy
1292 }
1293 (Self::StructField(x, ix), Self::StructField(y, iy)) => {
1294 x.as_addr() == y.as_addr() && ix == iy
1295 }
1296 (Self::PkgMember(ka, ix), Self::PkgMember(kb, iy)) => ka == kb && ix == iy,
1297 _ => false,
1298 }
1299 }
1300}
1301
1302impl Hash for PointerObj {
1303 fn hash<H: Hasher>(&self, state: &mut H) {
1304 match self {
1305 Self::UpVal(x) => x.hash(state),
1306 Self::SliceMember(s, index) => {
1307 s.as_addr().hash(state);
1308 index.hash(state);
1309 }
1310 Self::StructField(s, index) => {
1311 s.as_addr().hash(state);
1312 index.hash(state);
1313 }
1314 Self::PkgMember(p, index) => {
1315 p.hash(state);
1316 index.hash(state);
1317 }
1318 }
1319 }
1320}
1321
1322impl PartialOrd for PointerObj {
1323 #[inline]
1324 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1325 Some(self.cmp(other))
1326 }
1327}
1328
1329impl Ord for PointerObj {
1330 fn cmp(&self, other: &Self) -> Ordering {
1331 match (self, other) {
1332 (Self::UpVal(x), Self::UpVal(y)) => x.cmp(&y),
1333 (Self::SliceMember(x, ix), Self::SliceMember(y, iy)) => {
1334 x.as_addr().cmp(&y.as_addr()).then(ix.cmp(&iy))
1335 }
1336 (Self::StructField(x, ix), Self::StructField(y, iy)) => {
1337 x.as_addr().cmp(&y.as_addr()).then(ix.cmp(&iy))
1338 }
1339 (Self::PkgMember(ka, ix), Self::PkgMember(kb, iy)) => ka.cmp(&kb).then(ix.cmp(&iy)),
1340 _ => self.order().cmp(&other.order()),
1341 }
1342 }
1343}
1344
1345impl Display for PointerObj {
1346 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1347 match self {
1348 Self::UpVal(uv) => write!(f, "{:p}", Rc::as_ptr(&uv.inner)),
1349 Self::SliceMember(s, i) => write!(f, "{:p}i{}", s.as_addr(), i),
1350 Self::StructField(s, i) => write!(f, "{:p}i{}", s.as_addr(), i),
1351 Self::PkgMember(p, i) => write!(f, "{:x}i{}", p.as_usize(), i),
1352 }
1353 }
1354}
1355
1356pub trait UnsafePtr {
1360 fn as_any(&self) -> &dyn Any;
1362
1363 fn eq(&self, _: &dyn UnsafePtr) -> bool {
1364 panic!("implement your own eq for your type");
1365 }
1366
1367 fn ref_sub_one(&self) {}
1369
1370 fn mark_dirty(&self, _: &mut RCQueue) {}
1372
1373 fn can_make_cycle(&self) -> bool {
1375 false
1376 }
1377
1378 fn break_cycle(&self) {}
1380}
1381
1382impl std::fmt::Debug for dyn UnsafePtr {
1383 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1384 write!(f, "{}", "unsafe pointer")
1385 }
1386}
1387
1388#[derive(Debug, Clone)]
1390pub struct PointerHandle {
1391 ptr: PointerObj,
1392}
1393
1394impl UnsafePtr for PointerHandle {
1395 fn as_any(&self) -> &dyn Any {
1396 self
1397 }
1398
1399 fn eq(&self, other: &dyn UnsafePtr) -> bool {
1400 let a = self.as_any().downcast_ref::<PointerHandle>();
1401 let b = other.as_any().downcast_ref::<PointerHandle>();
1402 match b {
1403 Some(h) => h.ptr == a.unwrap().ptr,
1404 None => false,
1405 }
1406 }
1407
1408 fn ref_sub_one(&self) {
1410 self.ptr.ref_sub_one()
1411 }
1412
1413 fn mark_dirty(&self, q: &mut RCQueue) {
1415 self.ptr.mark_dirty(q)
1416 }
1417}
1418
1419impl PointerHandle {
1420 pub fn new(ptr: &GosValue) -> GosValue {
1421 match ptr.as_pointer() {
1422 Some(p) => {
1423 let handle = PointerHandle { ptr: p.clone() };
1424 GosValue::new_unsafe_ptr(Rc::new(handle))
1425 }
1426 None => GosValue::new_nil(ValueType::UnsafePtr),
1427 }
1428 }
1429
1430 pub fn ptr(&self) -> &PointerObj {
1432 &self.ptr
1433 }
1434}
1435
1436#[derive(Debug, Clone)]
1437pub struct UnsafePtrObj {
1438 ptr: Rc<dyn UnsafePtr>,
1439}
1440
1441impl UnsafePtrObj {
1442 pub fn new(ptr: Rc<dyn UnsafePtr>) -> UnsafePtrObj {
1443 UnsafePtrObj { ptr }
1444 }
1445
1446 pub fn ptr(&self) -> &dyn UnsafePtr {
1448 &*self.ptr
1449 }
1450
1451 pub fn as_rust_ptr(&self) -> *const dyn UnsafePtr {
1452 &*self.ptr
1453 }
1454
1455 pub fn downcast_ref<T: Any>(&self) -> RuntimeResult<&T> {
1456 self.ptr
1457 .as_any()
1458 .downcast_ref::<T>()
1459 .ok_or("Unexpected unsafe pointer type".to_owned().into())
1460 }
1461}
1462
1463impl Eq for UnsafePtrObj {}
1464
1465impl PartialEq for UnsafePtrObj {
1466 #[inline]
1467 fn eq(&self, other: &UnsafePtrObj) -> bool {
1468 self.ptr.eq(other.ptr())
1469 }
1470}
1471
1472impl Display for UnsafePtrObj {
1473 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1474 write!(f, "{:p}", &*self.ptr as *const dyn UnsafePtr)
1475 }
1476}
1477#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
1481#[derive(Clone)]
1482pub struct ValueDesc {
1483 pub func: FunctionKey,
1484 pub index: OpIndex,
1485 pub typ: ValueType,
1486 pub is_local: bool,
1487 #[cfg_attr(feature = "serde_borsh", borsh_skip)]
1488 pub stack: Weak<RefCell<Stack>>,
1489 #[cfg_attr(feature = "serde_borsh", borsh_skip)]
1490 pub stack_base: OpIndex,
1491}
1492
1493impl Eq for ValueDesc {}
1494
1495impl PartialEq for ValueDesc {
1496 #[inline]
1497 fn eq(&self, other: &ValueDesc) -> bool {
1498 self.stack_base + self.index == other.stack_base + other.index
1499 && self.stack.ptr_eq(&other.stack)
1500 }
1501}
1502
1503impl ValueDesc {
1504 pub fn new(func: FunctionKey, index: OpIndex, typ: ValueType, is_local: bool) -> ValueDesc {
1505 ValueDesc {
1506 func,
1507 index,
1508 typ,
1509 is_local,
1510 stack: Weak::new(),
1511 stack_base: 0,
1512 }
1513 }
1514
1515 #[inline]
1516 pub fn clone_with_stack(&self, stack: Weak<RefCell<Stack>>, stack_base: OpIndex) -> ValueDesc {
1517 ValueDesc {
1518 func: self.func,
1519 index: self.index,
1520 typ: self.typ,
1521 is_local: self.is_local,
1522 stack: stack,
1523 stack_base: stack_base,
1524 }
1525 }
1526
1527 #[inline]
1528 pub fn abs_index(&self) -> OpIndex {
1529 self.stack_base + self.index
1530 }
1531
1532 #[inline]
1533 pub fn load<'a>(&self, stack: &'a Stack) -> Cow<'a, GosValue> {
1534 let index = self.abs_index();
1535 let uv_stack = self.stack.upgrade().unwrap();
1536 if ptr::eq(uv_stack.as_ptr(), stack) {
1537 Cow::Borrowed(stack.get(index))
1538 } else {
1539 Cow::Owned(uv_stack.borrow().get(index).clone())
1540 }
1541 }
1542
1543 #[inline]
1544 pub fn store(&self, val: GosValue, stack: &mut Stack) {
1545 let index = self.abs_index();
1546 let uv_stack = self.stack.upgrade().unwrap();
1547 if ptr::eq(uv_stack.as_ptr(), stack) {
1548 stack.set(index, val);
1549 } else {
1550 uv_stack.borrow_mut().set(index, val);
1551 }
1552 }
1553}
1554
1555impl std::fmt::Debug for ValueDesc {
1556 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1557 f.debug_struct("ValueDesc")
1558 .field("type", &self.typ)
1559 .field("is_local", &self.is_local)
1560 .field("index", &self.abs_index())
1561 .field("stack", &self.stack.as_ptr())
1562 .finish()
1563 }
1564}
1565
1566#[derive(Clone, PartialEq, Eq)]
1567pub enum UpValueState {
1568 Open(ValueDesc), Closed(GosValue),
1572}
1573
1574impl std::fmt::Debug for UpValueState {
1575 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1576 match &self {
1577 Self::Open(desc) => write!(f, "UpValue::Open( {:#?} )", desc),
1578 Self::Closed(v) => write!(f, "UpValue::Closed( {:#018x} )", v.data().as_uint()),
1579 }
1580 }
1581}
1582
1583#[derive(Clone, Debug)]
1584pub struct UpValue {
1585 pub inner: Rc<RefCell<UpValueState>>,
1586}
1587
1588impl UpValue {
1589 pub fn new(d: ValueDesc) -> UpValue {
1590 UpValue {
1591 inner: Rc::new(RefCell::new(UpValueState::Open(d))),
1592 }
1593 }
1594
1595 pub fn new_closed(v: GosValue) -> UpValue {
1596 UpValue {
1597 inner: Rc::new(RefCell::new(UpValueState::Closed(v))),
1598 }
1599 }
1600
1601 pub fn is_open(&self) -> bool {
1602 match &self.inner.borrow() as &UpValueState {
1603 UpValueState::Open(_) => true,
1604 UpValueState::Closed(_) => false,
1605 }
1606 }
1607
1608 pub fn downgrade(&self) -> WeakUpValue {
1609 WeakUpValue {
1610 inner: Rc::downgrade(&self.inner),
1611 }
1612 }
1613
1614 pub fn desc(&self) -> ValueDesc {
1615 let r: &UpValueState = &self.inner.borrow();
1616 match r {
1617 UpValueState::Open(d) => d.clone(),
1618 _ => unreachable!(),
1619 }
1620 }
1621
1622 pub fn close(&self, val: GosValue) {
1623 *self.inner.borrow_mut() = UpValueState::Closed(val);
1624 }
1625
1626 pub fn value<'a>(&self, stack: &'a Stack) -> Cow<'a, GosValue> {
1627 match &self.inner.borrow() as &UpValueState {
1628 UpValueState::Open(desc) => desc.load(stack),
1629 UpValueState::Closed(val) => Cow::Owned(val.clone()),
1630 }
1631 }
1632
1633 pub fn set_value(&self, val: GosValue, stack: &mut Stack) {
1634 match &mut self.inner.borrow_mut() as &mut UpValueState {
1635 UpValueState::Open(desc) => desc.store(val, stack),
1636 UpValueState::Closed(v) => {
1637 *v = val;
1638 }
1639 }
1640 }
1641
1642 pub fn ref_sub_one(&self) {
1644 let state: &UpValueState = &self.inner.borrow();
1645 if let UpValueState::Closed(uvs) = state {
1646 uvs.ref_sub_one()
1647 }
1648 }
1649
1650 pub fn mark_dirty(&self, queue: &mut RCQueue) {
1652 let state: &UpValueState = &self.inner.borrow();
1653 if let UpValueState::Closed(uvs) = state {
1654 uvs.mark_dirty(queue)
1655 }
1656 }
1657}
1658
1659impl Eq for UpValue {}
1660
1661impl PartialEq for UpValue {
1662 #[inline]
1663 fn eq(&self, b: &UpValue) -> bool {
1664 let state_a: &UpValueState = &self.inner.borrow();
1665 let state_b: &UpValueState = &b.inner.borrow();
1666 match (state_a, state_b) {
1667 (UpValueState::Closed(_), UpValueState::Closed(_)) => Rc::ptr_eq(&self.inner, &b.inner),
1668 (UpValueState::Open(da), UpValueState::Open(db)) => {
1669 da.abs_index() == db.abs_index() && Weak::ptr_eq(&da.stack, &db.stack)
1670 }
1671 _ => false,
1672 }
1673 }
1674}
1675
1676impl Hash for UpValue {
1677 #[inline]
1678 fn hash<H: Hasher>(&self, state: &mut H) {
1679 let b: &UpValueState = &self.inner.borrow();
1680 match b {
1681 UpValueState::Open(desc) => desc.abs_index().hash(state),
1682 UpValueState::Closed(_) => Rc::as_ptr(&self.inner).hash(state),
1683 }
1684 }
1685}
1686
1687impl PartialOrd for UpValue {
1688 #[inline]
1689 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1690 Some(self.cmp(other))
1691 }
1692}
1693
1694impl Ord for UpValue {
1695 fn cmp(&self, b: &Self) -> Ordering {
1696 let state_a: &UpValueState = &self.inner.borrow();
1697 let state_b: &UpValueState = &b.inner.borrow();
1698 match (state_a, state_b) {
1699 (UpValueState::Closed(_), UpValueState::Closed(_)) => {
1700 Rc::as_ptr(&self.inner).cmp(&Rc::as_ptr(&b.inner))
1701 }
1702 (UpValueState::Open(da), UpValueState::Open(db)) => da
1703 .abs_index()
1704 .cmp(&db.abs_index())
1705 .then(Weak::as_ptr(&da.stack).cmp(&Weak::as_ptr(&db.stack))),
1706 (UpValueState::Open(_), UpValueState::Closed(_)) => Ordering::Greater,
1707 (UpValueState::Closed(_), UpValueState::Open(_)) => Ordering::Less,
1708 }
1709 }
1710}
1711
1712#[cfg(feature = "serde_borsh")]
1713impl BorshSerialize for UpValue {
1714 fn serialize<W: BorshWrite>(&self, writer: &mut W) -> BorshResult<()> {
1715 match &self.inner.borrow() as &UpValueState {
1716 UpValueState::Open(uv) => uv,
1717 UpValueState::Closed(_) => unreachable!(),
1718 }
1719 .serialize(writer)
1720 }
1721}
1722
1723#[cfg(feature = "serde_borsh")]
1724impl BorshDeserialize for UpValue {
1725 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> BorshResult<Self> {
1726 let uv = ValueDesc::deserialize_reader(reader)?;
1727 Ok(Self::new(uv))
1728 }
1729}
1730
1731#[derive(Clone, Debug)]
1732pub struct WeakUpValue {
1733 pub inner: Weak<RefCell<UpValueState>>,
1734}
1735
1736impl WeakUpValue {
1737 pub fn upgrade(&self) -> Option<UpValue> {
1738 Weak::upgrade(&self.inner).map(|x| UpValue { inner: x })
1739 }
1740}
1741
1742#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
1743#[derive(Clone, Debug)]
1744pub struct GosClosureObj {
1745 pub func: FunctionKey,
1746 pub uvs: Option<Map<usize, UpValue>>,
1747 #[cfg_attr(feature = "serde_borsh", borsh_skip)]
1748 pub recv: Option<GosValue>,
1749 pub meta: Meta,
1750}
1751
1752impl GosClosureObj {
1753 fn new(
1754 func: FunctionKey,
1755 up_ptrs: Option<&Vec<ValueDesc>>,
1756 recv: Option<GosValue>,
1757 meta: Meta,
1758 ) -> GosClosureObj {
1759 let uvs = up_ptrs.map(|uv| {
1760 uv.iter()
1761 .enumerate()
1762 .filter(|(_, x)| !x.is_local)
1763 .map(|(i, x)| (i, UpValue::new(x.clone())))
1764 .collect()
1765 });
1766 GosClosureObj {
1767 func,
1768 uvs,
1769 recv,
1770 meta,
1771 }
1772 }
1773}
1774
1775#[derive(Clone, Debug)]
1776pub struct FfiClosureObj {
1777 pub ffi: Rc<dyn Ffi>,
1778 pub func_name: String,
1779 pub is_async: bool,
1780 pub meta: Meta,
1781}
1782
1783#[derive(Clone, Debug)]
1784pub enum ClosureObj {
1785 Gos(GosClosureObj),
1786 Ffi(FfiClosureObj),
1787}
1788
1789impl ClosureObj {
1790 pub fn new_gos(
1791 func: FunctionKey,
1792 up_ptrs: Option<&Vec<ValueDesc>>,
1793 recv: Option<GosValue>,
1794 meta: Meta,
1795 ) -> ClosureObj {
1796 ClosureObj::Gos(GosClosureObj::new(func, up_ptrs, recv, meta))
1797 }
1798
1799 pub fn gos_from_func(
1800 func: FunctionKey,
1801 fobjs: &FunctionObjs,
1802 recv: Option<GosValue>,
1803 ) -> ClosureObj {
1804 let func_val = &fobjs[func];
1805 let uvs = if func_val.up_ptrs.is_empty() {
1806 None
1807 } else {
1808 Some(&func_val.up_ptrs)
1809 };
1810 ClosureObj::Gos(GosClosureObj::new(func, uvs, recv, func_val.meta))
1811 }
1812
1813 #[inline]
1814 pub fn new_ffi(ffi: FfiClosureObj) -> ClosureObj {
1815 ClosureObj::Ffi(ffi)
1816 }
1817
1818 #[inline]
1819 pub fn as_gos(&self) -> &GosClosureObj {
1820 match self {
1821 Self::Gos(c) => c,
1822 _ => unreachable!(),
1823 }
1824 }
1825
1826 pub fn ref_sub_one(&self) {
1828 match self {
1829 Self::Gos(obj) => {
1830 if let Some(uvs) = &obj.uvs {
1831 for (_, v) in uvs.iter() {
1832 v.ref_sub_one()
1833 }
1834 }
1835 if let Some(recv) = &obj.recv {
1836 recv.ref_sub_one()
1837 }
1838 }
1839 Self::Ffi(_) => {}
1840 }
1841 }
1842
1843 pub fn mark_dirty(&self, queue: &mut RCQueue) {
1845 match self {
1846 Self::Gos(obj) => {
1847 if let Some(uvs) = &obj.uvs {
1848 for (_, v) in uvs.iter() {
1849 v.mark_dirty(queue)
1850 }
1851 }
1852 if let Some(recv) = &obj.recv {
1853 recv.mark_dirty(queue)
1854 }
1855 }
1856 Self::Ffi(_) => {}
1857 }
1858 }
1859}
1860
1861#[derive(Clone, Debug)]
1867pub struct PackageObj {
1868 name: String,
1869 members: Vec<RefCell<GosValue>>, member_indices: Map<String, OpIndex>,
1871 init_funcs: Vec<GosValue>,
1872 var_mapping: RefCell<Option<Map<OpIndex, OpIndex>>>,
1874}
1875
1876impl PackageObj {
1877 pub fn new(name: String) -> PackageObj {
1878 PackageObj {
1879 name,
1880 members: vec![],
1881 member_indices: Map::new(),
1882 init_funcs: vec![],
1883 var_mapping: RefCell::new(Some(Map::new())),
1884 }
1885 }
1886
1887 pub fn name(&self) -> &str {
1888 &self.name
1889 }
1890
1891 pub fn add_member(&mut self, name: String, val: GosValue) -> OpIndex {
1892 self.members.push(RefCell::new(val));
1893 let index = (self.members.len() - 1) as OpIndex;
1894 self.member_indices.insert(name, index);
1895 index as OpIndex
1896 }
1897
1898 pub fn add_var_mapping(&mut self, name: String, fn_index: OpIndex) -> OpIndex {
1899 let index = *self.member_index(&name).unwrap();
1900 self.var_mapping
1901 .borrow_mut()
1902 .as_mut()
1903 .unwrap()
1904 .insert(fn_index, index);
1905 index
1906 }
1907
1908 pub fn add_init_func(&mut self, func: GosValue) {
1909 self.init_funcs.push(func);
1910 }
1911
1912 pub fn member_indices(&self) -> &Map<String, OpIndex> {
1913 &self.member_indices
1914 }
1915
1916 pub fn member_index(&self, name: &str) -> Option<&OpIndex> {
1917 self.member_indices.get(name)
1918 }
1919
1920 pub fn inited(&self) -> bool {
1921 self.var_mapping.borrow().is_none()
1922 }
1923
1924 #[inline]
1925 pub fn member(&self, i: OpIndex) -> Ref<GosValue> {
1926 self.members[i as usize].borrow()
1927 }
1928
1929 #[inline]
1930 pub fn member_mut(&self, i: OpIndex) -> RefMut<GosValue> {
1931 self.members[i as usize].borrow_mut()
1932 }
1933
1934 #[inline]
1935 pub fn init_func(&self, i: OpIndex) -> Option<&GosValue> {
1936 self.init_funcs.get(i as usize)
1937 }
1938
1939 #[inline]
1940 pub fn init_vars(&self, vals: Vec<GosValue>) {
1941 let mut borrow = self.var_mapping.borrow_mut();
1942 let mapping = borrow.as_ref().unwrap();
1943 for (i, v) in vals.into_iter().enumerate() {
1944 let vi = mapping[&(i as OpIndex)];
1945 *self.member_mut(vi) = v;
1946 }
1947 *borrow = None;
1948 }
1949}
1950
1951#[cfg(feature = "serde_borsh")]
1952impl BorshSerialize for PackageObj {
1953 fn serialize<W: BorshWrite>(&self, writer: &mut W) -> BorshResult<()> {
1954 self.name.serialize(writer)?;
1955 let members: Vec<GosValue> = self
1956 .members
1957 .iter()
1958 .map(|x| x.clone().into_inner())
1959 .collect();
1960 members.serialize(writer)?;
1961 self.member_indices.serialize(writer)?;
1962 self.init_funcs.serialize(writer)?;
1963 self.var_mapping.borrow().serialize(writer)
1964 }
1965}
1966
1967#[cfg(feature = "serde_borsh")]
1968impl BorshDeserialize for PackageObj {
1969 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> BorshResult<Self> {
1970 let name = String::deserialize_reader(reader)?;
1971 let members = Vec::<GosValue>::deserialize_reader(reader)?
1972 .into_iter()
1973 .map(|x| RefCell::new(x))
1974 .collect();
1975 let member_indices = Map::<String, OpIndex>::deserialize_reader(reader)?;
1976 let init_funcs = Vec::<GosValue>::deserialize_reader(reader)?;
1977 let var_mapping =
1978 RefCell::new(Option::<Map<OpIndex, OpIndex>>::deserialize_reader(reader)?);
1979 Ok(PackageObj {
1980 name,
1981 members,
1982 member_indices,
1983 init_funcs,
1984 var_mapping,
1985 })
1986 }
1987}
1988
1989#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
1993#[derive(Eq, PartialEq, Copy, Clone, Debug)]
1994pub enum FuncFlag {
1995 Default,
1996 PkgCtor,
1997 HasDefer,
1998}
1999
2000#[cfg_attr(feature = "serde_borsh", derive(BorshDeserialize, BorshSerialize))]
2002#[derive(Clone, Debug)]
2003pub struct FunctionObj {
2004 pub package: PackageKey,
2005 pub meta: Meta,
2006 pub flag: FuncFlag,
2007 pub param_count: OpIndex,
2008 pub max_write_index: OpIndex,
2009 pub ret_zeros: Vec<GosValue>,
2010
2011 pub code: Vec<Instruction>,
2012 #[cfg_attr(
2013 all(feature = "serde_borsh", not(feature = "instruction_pos")),
2014 borsh_skip
2015 )]
2016 pub pos: Vec<Option<u32>>,
2017 pub up_ptrs: Vec<ValueDesc>,
2018 pub local_zeros: Vec<GosValue>,
2019}
2020
2021impl FunctionObj {
2022 pub fn new(
2023 package: PackageKey,
2024 meta: Meta,
2025 metas: &MetadataObjs,
2026 gcc: &GcContainer,
2027 flag: FuncFlag,
2028 ) -> FunctionObj {
2029 let s = &metas[meta.key].as_signature();
2030 let ret_zeros = s.results.iter().map(|m| m.zero(metas, gcc)).collect();
2031 let mut param_count = s.recv.map_or(0, |_| 1);
2032 param_count += s.params.len() as OpIndex;
2033 FunctionObj {
2034 package,
2035 meta,
2036 flag,
2037 param_count,
2038 max_write_index: 0,
2039 ret_zeros,
2040 code: Vec::new(),
2041 pos: Vec::new(),
2042 up_ptrs: Vec::new(),
2043 local_zeros: Vec::new(),
2044 }
2045 }
2046
2047 #[inline]
2048 pub fn param_count(&self) -> OpIndex {
2049 self.param_count
2050 }
2051
2052 #[inline]
2053 pub fn local_count(&self) -> OpIndex {
2054 self.local_zeros.len() as OpIndex
2055 }
2056
2057 #[inline]
2058 pub fn ret_count(&self) -> OpIndex {
2059 self.ret_zeros.len() as OpIndex
2060 }
2061
2062 #[inline]
2063 pub fn is_ctor(&self) -> bool {
2064 self.flag == FuncFlag::PkgCtor
2065 }
2066}