1#![allow(dead_code)]
6
7pub use crate::bytecode::*;
8#[cfg(feature = "async")]
9use crate::channel::Channel;
10pub(crate) use crate::dispatcher::*;
11use crate::gc::GcContainer;
12pub use crate::instruction::*;
13pub use crate::metadata::*;
14pub use crate::objects::*;
15#[cfg(feature = "serde_borsh")]
16use borsh::{
17 maybestd::io::Result as BorshResult, maybestd::io::Write as BorshWrite, BorshDeserialize,
18 BorshSerialize,
19};
20#[cfg(feature = "serde_borsh")]
21use std::io::{Error, ErrorKind};
22
23use ordered_float;
24use std::cell::Cell;
25use std::cmp::Ordering;
26use std::collections::VecDeque;
27use std::convert::From;
28use std::fmt::{self, Debug, Display, Write};
29use std::hash::{Hash, Hasher};
30use std::num::Wrapping;
31use std::ptr;
32use std::rc::Rc;
33use std::result;
34
35pub type F32 = ordered_float::OrderedFloat<f32>;
36pub type F64 = ordered_float::OrderedFloat<f64>;
37pub type IRC = i32;
38pub type RCount = Cell<IRC>;
39pub type RCQueue = VecDeque<IRC>;
40
41#[inline]
42pub(crate) fn rcount_mark_and_queue(rc: &RCount, queue: &mut RCQueue) {
43 let i = rc.get();
44 if i <= 0 {
45 queue.push_back(i);
46 rc.set(1);
47 }
48}
49
50fn ref_ptr_eq<T>(x: Option<&T>, y: Option<&T>) -> bool {
51 match (x, y) {
52 (Some(a), Some(b)) => a as *const T == b as *const T,
53 (None, None) => true,
54 _ => false,
55 }
56}
57
58macro_rules! nil_err_str {
59 () => {
60 "access nil value".to_owned().into()
61 };
62}
63
64macro_rules! union_op_wrap {
65 ($a:ident, $b:ident, $name:tt, $op:tt) => {
66 ValueData {
67 $name: (Wrapping($a.$name) $op Wrapping($b.$name)).0,
68 }
69 };
70}
71
72macro_rules! union_op {
73 ($a:ident, $b:ident, $name:tt, $op:tt) => {
74 ValueData {
75 $name: $a.$name $op $b.$name,
76 }
77 };
78}
79
80macro_rules! union_shift {
81 ($a:ident, $b:ident, $name:tt, $op:tt) => {
82 ValueData {
83 $name: $a.$name.$op(*$b).unwrap_or(0),
84 }
85 };
86}
87
88macro_rules! union_cmp {
89 ($a:ident, $b:ident, $name:tt, $op:tt) => {
90 $a.$name $op $b.$name
91 };
92}
93
94macro_rules! binary_op_int_float_str {
95 ($t:ident, $a:ident, $b:ident, $op:tt) => {
96 match $t {
97 ValueType::Int => union_op_wrap!($a, $b, int, $op),
98 ValueType::Int8 => union_op_wrap!($a, $b, int8, $op),
99 ValueType::Int16 => union_op_wrap!($a, $b, int16, $op),
100 ValueType::Int32 => union_op_wrap!($a, $b, int32, $op),
101 ValueType::Int64 => union_op_wrap!($a, $b, int64, $op),
102 ValueType::Uint => union_op_wrap!($a, $b, uint, $op),
103 ValueType::UintPtr => union_op_wrap!($a, $b, uint_ptr, $op),
104 ValueType::Uint8 => union_op_wrap!($a, $b, uint8, $op),
105 ValueType::Uint16 => union_op_wrap!($a, $b, uint16, $op),
106 ValueType::Uint32 => union_op_wrap!($a, $b, uint32, $op),
107 ValueType::Uint64 => union_op_wrap!($a, $b, uint64, $op),
108 ValueType::Float32 => union_op!($a, $b, float32, $op),
109 ValueType::Float64 => union_op!($a, $b, float64, $op),
110 ValueType::String => $a.add_str($b),
111 _ => unreachable!(),
112 }
113 };
114}
115
116macro_rules! binary_op_int_no_wrap {
117 ($t:ident, $a:ident, $b:ident, $op:tt) => {
118 match $t {
119 ValueType::Int => union_op!($a, $b, int, $op),
120 ValueType::Int8 => union_op!($a, $b, int8, $op),
121 ValueType::Int16 => union_op!($a, $b, int16, $op),
122 ValueType::Int32 => union_op!($a, $b, int32, $op),
123 ValueType::Int64 => union_op!($a, $b, int64, $op),
124 ValueType::Uint => union_op!($a, $b, uint, $op),
125 ValueType::UintPtr => union_op!($a, $b, uint_ptr, $op),
126 ValueType::Uint8 => union_op!($a, $b, uint8, $op),
127 ValueType::Uint16 => union_op!($a, $b, uint16, $op),
128 ValueType::Uint32 => union_op!($a, $b, uint32, $op),
129 ValueType::Uint64 => union_op!($a, $b, uint64, $op),
130 _ => unreachable!(),
131 }
132 };
133}
134
135macro_rules! cmp_bool_int_float {
136 ($t:ident, $a:ident, $b:ident, $op:tt) => {
137 match $t {
138 ValueType::Bool => union_cmp!($a, $b, boolean, $op),
139 ValueType::Int => union_cmp!($a, $b, int, $op),
140 ValueType::Int8 => union_cmp!($a, $b, int8, $op),
141 ValueType::Int16 => union_cmp!($a, $b, int16, $op),
142 ValueType::Int32 => union_cmp!($a, $b, int32, $op),
143 ValueType::Int64 => union_cmp!($a, $b, int64, $op),
144 ValueType::Uint => union_cmp!($a, $b, uint, $op),
145 ValueType::UintPtr => union_cmp!($a, $b, uint_ptr, $op),
146 ValueType::Uint8 => union_cmp!($a, $b, uint8, $op),
147 ValueType::Uint16 => union_cmp!($a, $b, uint16, $op),
148 ValueType::Uint32 => union_cmp!($a, $b, uint32, $op),
149 ValueType::Uint64 => union_cmp!($a, $b, uint64, $op),
150 ValueType::Float32 => union_cmp!($a, $b, float32, $op),
151 ValueType::Float64 => union_cmp!($a, $b, float64, $op),
152 _ => unreachable!(),
153 }
154 };
155}
156
157macro_rules! cmp_int_float {
158 ($t:ident, $a:ident, $b:ident, $op:tt) => {
159 match $t {
160 ValueType::Int => union_cmp!($a, $b, int, $op),
161 ValueType::Int8 => union_cmp!($a, $b, int8, $op),
162 ValueType::Int16 => union_cmp!($a, $b, int16, $op),
163 ValueType::Int32 => union_cmp!($a, $b, int32, $op),
164 ValueType::Int64 => union_cmp!($a, $b, int64, $op),
165 ValueType::Uint => union_cmp!($a, $b, uint, $op),
166 ValueType::UintPtr => union_cmp!($a, $b, uint_ptr, $op),
167 ValueType::Uint8 => union_cmp!($a, $b, uint8, $op),
168 ValueType::Uint16 => union_cmp!($a, $b, uint16, $op),
169 ValueType::Uint32 => union_cmp!($a, $b, uint32, $op),
170 ValueType::Uint64 => union_cmp!($a, $b, uint64, $op),
171 ValueType::Float32 => union_cmp!($a, $b, float32, $op),
172 ValueType::Float64 => union_cmp!($a, $b, float64, $op),
173 _ => unreachable!(),
174 }
175 };
176}
177
178macro_rules! shift_int {
179 ($t:ident, $a:ident, $b:ident, $op:tt) => {
180 match $t {
181 ValueType::Int => union_shift!($a, $b, int, $op),
182 ValueType::Int8 => union_shift!($a, $b, int8, $op),
183 ValueType::Int16 => union_shift!($a, $b, int16, $op),
184 ValueType::Int32 => union_shift!($a, $b, int32, $op),
185 ValueType::Int64 => union_shift!($a, $b, int64, $op),
186 ValueType::Uint => union_shift!($a, $b, uint, $op),
187 ValueType::UintPtr => union_shift!($a, $b, uint_ptr, $op),
188 ValueType::Uint8 => union_shift!($a, $b, uint8, $op),
189 ValueType::Uint16 => union_shift!($a, $b, uint16, $op),
190 ValueType::Uint32 => union_shift!($a, $b, uint32, $op),
191 ValueType::Uint64 => union_shift!($a, $b, uint64, $op),
192 _ => unreachable!(),
193 }
194 };
195}
196
197macro_rules! convert_to_int {
198 ($val:expr, $vt:expr, $d_type:tt, $typ:tt) => {{
199 unsafe {
200 match $vt {
201 ValueType::Uint => $val.$d_type = $val.uint as $typ,
202 ValueType::UintPtr => $val.$d_type = $val.uint_ptr as $typ,
203 ValueType::Uint8 => $val.$d_type = $val.uint8 as $typ,
204 ValueType::Uint16 => $val.$d_type = $val.uint16 as $typ,
205 ValueType::Uint32 => $val.$d_type = $val.uint32 as $typ,
206 ValueType::Uint64 => $val.$d_type = $val.uint64 as $typ,
207 ValueType::Int => $val.$d_type = $val.int as $typ,
208 ValueType::Int8 => $val.$d_type = $val.int8 as $typ,
209 ValueType::Int16 => $val.$d_type = $val.int16 as $typ,
210 ValueType::Int32 => $val.$d_type = $val.int32 as $typ,
211 ValueType::Int64 => $val.$d_type = $val.int64 as $typ,
212 ValueType::Float32 => $val.$d_type = f32::from($val.float32) as $typ,
213 ValueType::Float64 => $val.$d_type = f64::from($val.float64) as $typ,
214 _ => unreachable!(),
215 }
216 }
217 }};
218}
219
220macro_rules! convert_to_float {
221 ($val:expr, $vt:expr, $d_type:tt, $f_type:tt, $typ:tt) => {{
222 unsafe {
223 match $vt {
224 ValueType::Uint => $val.$d_type = $f_type::from($val.uint as $typ),
225 ValueType::UintPtr => $val.$d_type = $f_type::from($val.uint_ptr as $typ),
226 ValueType::Uint8 => $val.$d_type = $f_type::from($val.uint8 as $typ),
227 ValueType::Uint16 => $val.$d_type = $f_type::from($val.uint16 as $typ),
228 ValueType::Uint32 => $val.$d_type = $f_type::from($val.uint32 as $typ),
229 ValueType::Uint64 => $val.$d_type = $f_type::from($val.uint64 as $typ),
230 ValueType::Int => $val.$d_type = $f_type::from($val.int as $typ),
231 ValueType::Int8 => $val.$d_type = $f_type::from($val.int8 as $typ),
232 ValueType::Int16 => $val.$d_type = $f_type::from($val.int16 as $typ),
233 ValueType::Int32 => $val.$d_type = $f_type::from($val.int32 as $typ),
234 ValueType::Int64 => $val.$d_type = $f_type::from($val.int64 as $typ),
235 ValueType::Float32 => $val.$d_type = $f_type::from(f32::from($val.float32) as $typ),
236 ValueType::Float64 => $val.$d_type = $f_type::from(f64::from($val.float64) as $typ),
237 _ => unreachable!(),
238 }
239 }
240 }};
241}
242
243#[derive(Debug)]
244pub struct RuntimeError(String);
245
246impl RuntimeError {
247 pub fn new(msg: String) -> RuntimeError {
248 RuntimeError(msg)
249 }
250
251 pub fn as_str(&self) -> &str {
252 &self.0
253 }
254}
255
256impl std::fmt::Display for RuntimeError {
257 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258 write!(f, "{}", self.0)
259 }
260}
261
262impl std::error::Error for RuntimeError {}
263
264impl std::convert::From<String> for RuntimeError {
265 fn from(msg: String) -> Self {
266 Self(msg)
267 }
268}
269
270pub type RuntimeResult<T> = result::Result<T, RuntimeError>;
271
272pub(crate) type OptionBox<T> = Option<Box<T>>;
273
274pub(crate) type OptionRc<T> = Option<Rc<T>>;
275
276#[derive(Debug, Clone, Copy)]
277pub struct Complex64 {
278 pub r: F32,
279 pub i: F32,
280}
281
282#[derive(Debug, Clone, Copy)]
283pub struct Complex128 {
284 pub r: F64,
285 pub i: F64,
286}
287
288pub trait AsPrimitive<T>
289where
290 T: 'static,
291{
292 fn as_(&self) -> T;
294}
295
296pub(crate) union ValueData {
303 untyped_nil: *const usize,
305 boolean: bool,
306 int: isize,
307 int8: i8,
308 int16: i16,
309 int32: i32,
310 int64: i64,
311 uint: usize,
312 uint_ptr: usize,
313 uint8: u8,
314 uint16: u16,
315 uint32: u32,
316 uint64: u64,
317 float32: F32,
318 float64: F64,
319 complex64: Complex64,
320 function: FunctionKey,
321 package: PackageKey,
322 metadata: *mut Meta, complex128: *mut Complex128,
324 string: *const StringObj,
325 array: *const (GosArrayObj, RCount),
326 structure: *const (StructObj, RCount),
327 pointer: *mut PointerObj,
328 unsafe_ptr: *mut UnsafePtrObj,
329 closure: *const (ClosureObj, RCount),
330 slice: *const (GosSliceObj, RCount),
331 map: *const (MapObj, RCount),
332 interface: *const InterfaceObj,
333 #[cfg(feature = "async")]
334 channel: *const ChannelObj,
335}
336
337impl ValueData {
338 #[inline]
339 fn new_nil(t: ValueType) -> ValueData {
340 match t {
341 ValueType::Pointer => ValueData {
342 pointer: ptr::null_mut(),
343 },
344 ValueType::UnsafePtr => ValueData {
345 unsafe_ptr: ptr::null_mut(),
346 },
347 ValueType::Closure => ValueData {
348 closure: ptr::null(),
349 },
350 ValueType::Slice => ValueData { slice: ptr::null() },
351 ValueType::Map => ValueData { map: ptr::null() },
352 ValueType::Interface => ValueData {
353 interface: ptr::null(),
354 },
355 #[cfg(feature = "async")]
356 ValueType::Channel => ValueData {
357 channel: ptr::null(),
358 },
359 ValueType::Void => ValueData {
360 untyped_nil: ptr::null(),
361 },
362 _ => unreachable!(),
363 }
364 }
365
366 #[inline]
367 pub(crate) fn new_bool(b: bool) -> ValueData {
368 ValueData { boolean: b }
369 }
370
371 #[inline]
372 pub(crate) fn new_int(i: isize) -> ValueData {
373 ValueData { int: i }
374 }
375
376 #[inline]
377 pub(crate) fn new_int8(i: i8) -> ValueData {
378 ValueData { int8: i }
379 }
380
381 #[inline]
382 pub(crate) fn new_int16(i: i16) -> ValueData {
383 ValueData { int16: i }
384 }
385
386 #[inline]
387 pub(crate) fn new_int32(i: i32) -> ValueData {
388 ValueData { int32: i }
389 }
390
391 #[inline]
392 pub(crate) fn new_int64(i: i64) -> ValueData {
393 ValueData { int64: i }
394 }
395
396 #[inline]
397 pub(crate) fn new_uint(u: usize) -> ValueData {
398 ValueData { uint: u }
399 }
400
401 #[inline]
402 pub(crate) fn new_uint_ptr(u: usize) -> ValueData {
403 ValueData { uint_ptr: u }
404 }
405
406 #[inline]
407 pub(crate) fn new_uint8(u: u8) -> ValueData {
408 ValueData { uint8: u }
409 }
410
411 #[inline]
412 pub(crate) fn new_uint16(u: u16) -> ValueData {
413 ValueData { uint16: u }
414 }
415
416 #[inline]
417 pub(crate) fn new_uint32(u: u32) -> ValueData {
418 ValueData { uint32: u }
419 }
420
421 #[inline]
422 pub(crate) fn new_uint64(u: u64) -> ValueData {
423 ValueData { uint64: u }
424 }
425
426 #[inline]
427 pub(crate) fn new_float32(f: F32) -> ValueData {
428 ValueData { float32: f }
429 }
430
431 #[inline]
432 pub(crate) fn new_float64(f: F64) -> ValueData {
433 ValueData { float64: f }
434 }
435
436 #[inline]
437 pub(crate) fn new_complex64(r: F32, i: F32) -> ValueData {
438 ValueData {
439 complex64: Complex64 { r: r, i: i },
440 }
441 }
442
443 #[inline]
444 pub(crate) fn new_function(f: FunctionKey) -> ValueData {
445 ValueData { function: f }
446 }
447
448 #[inline]
449 pub(crate) fn new_package(p: PackageKey) -> ValueData {
450 ValueData { package: p }
451 }
452
453 #[inline]
454 pub(crate) fn as_bool(&self) -> &bool {
455 unsafe { &self.boolean }
456 }
457
458 #[inline]
459 pub(crate) fn as_int(&self) -> &isize {
460 unsafe { &self.int }
461 }
462
463 #[inline]
464 pub(crate) fn as_int8(&self) -> &i8 {
465 unsafe { &self.int8 }
466 }
467
468 #[inline]
469 pub(crate) fn as_int16(&self) -> &i16 {
470 unsafe { &self.int16 }
471 }
472
473 #[inline]
474 pub(crate) fn as_int32(&self) -> &i32 {
475 unsafe { &self.int32 }
476 }
477
478 #[inline]
479 pub(crate) fn as_int64(&self) -> &i64 {
480 unsafe { &self.int64 }
481 }
482
483 #[inline]
484 pub(crate) fn as_uint(&self) -> &usize {
485 unsafe { &self.uint }
486 }
487
488 #[inline]
489 pub(crate) fn as_uint_ptr(&self) -> &usize {
490 unsafe { &self.uint_ptr }
491 }
492
493 #[inline]
494 pub(crate) fn as_uint8(&self) -> &u8 {
495 unsafe { &self.uint8 }
496 }
497
498 #[inline]
499 pub(crate) fn as_uint16(&self) -> &u16 {
500 unsafe { &self.uint16 }
501 }
502
503 #[inline]
504 pub(crate) fn as_uint32(&self) -> &u32 {
505 unsafe { &self.uint32 }
506 }
507
508 #[inline]
509 pub(crate) fn as_uint64(&self) -> &u64 {
510 unsafe { &self.uint64 }
511 }
512
513 #[inline]
514 pub(crate) fn as_float32(&self) -> &F32 {
515 unsafe { &self.float32 }
516 }
517
518 #[inline]
519 pub(crate) fn as_float64(&self) -> &F64 {
520 unsafe { &self.float64 }
521 }
522
523 #[inline]
524 pub(crate) fn as_complex64(&self) -> &Complex64 {
525 unsafe { &self.complex64 }
526 }
527
528 #[inline]
529 pub(crate) fn as_function(&self) -> &FunctionKey {
530 unsafe { &self.function }
531 }
532
533 #[inline]
534 pub(crate) fn as_package(&self) -> &PackageKey {
535 unsafe { &self.package }
536 }
537
538 #[inline]
539 pub(crate) fn as_metadata(&self) -> &Meta {
540 unsafe { self.metadata.as_ref().unwrap() }
541 }
542
543 #[inline]
544 pub(crate) fn as_complex128(&self) -> &Complex128 {
545 unsafe { &self.complex128.as_ref().unwrap() }
546 }
547
548 #[inline]
549 pub(crate) fn as_string(&self) -> &StringObj {
550 unsafe { &self.string.as_ref().unwrap() }
551 }
552
553 #[inline]
554 pub(crate) fn as_gos_array(&self) -> &(GosArrayObj, RCount) {
555 unsafe { &self.array.as_ref().unwrap() }
556 }
557
558 #[inline]
559 pub(crate) fn as_array<T>(&self) -> &(ArrayObj<T>, RCount) {
560 unsafe {
561 let p: *const (ArrayObj<T>, RCount) = std::mem::transmute(self.array);
562 &p.as_ref().unwrap()
563 }
564 }
565
566 #[inline]
567 pub(crate) fn as_struct(&self) -> &(StructObj, RCount) {
568 unsafe { &self.structure.as_ref().unwrap() }
569 }
570
571 #[inline]
572 pub(crate) fn as_pointer(&self) -> Option<&PointerObj> {
573 unsafe { self.pointer.as_ref() }
574 }
575
576 #[inline]
577 pub(crate) fn as_unsafe_ptr(&self) -> Option<&UnsafePtrObj> {
578 unsafe { self.unsafe_ptr.as_ref() }
579 }
580
581 #[inline]
582 pub(crate) fn as_closure(&self) -> Option<&(ClosureObj, RCount)> {
583 unsafe { self.closure.as_ref() }
584 }
585
586 #[inline]
587 pub(crate) fn as_slice<T>(&self) -> Option<&(SliceObj<T>, RCount)> {
588 unsafe {
589 let p: *const (SliceObj<T>, RCount) = std::mem::transmute(self.array);
590 p.as_ref()
591 }
592 }
593
594 #[inline]
595 pub(crate) fn as_map(&self) -> Option<&(MapObj, RCount)> {
596 unsafe { self.map.as_ref() }
597 }
598
599 #[inline]
600 pub(crate) fn as_interface(&self) -> Option<&InterfaceObj> {
601 unsafe { self.interface.as_ref() }
602 }
603
604 #[cfg(feature = "async")]
605 #[inline]
606 pub(crate) fn as_channel(&self) -> Option<&ChannelObj> {
607 unsafe { self.channel.as_ref() }
608 }
609
610 #[inline]
611 pub(crate) fn as_addr(&self) -> *const usize {
612 unsafe { self.untyped_nil }
613 }
614
615 #[inline]
616 pub(crate) fn int32_as(i: i32, t: ValueType) -> ValueData {
617 match t {
618 ValueType::Int => ValueData { int: i as isize },
619 ValueType::Int8 => ValueData { int8: i as i8 },
620 ValueType::Int16 => ValueData { int16: i as i16 },
621 ValueType::Int32 => ValueData { int32: i as i32 },
622 ValueType::Int64 => ValueData { int64: i as i64 },
623 ValueType::Uint => ValueData { uint: i as usize },
624 ValueType::UintPtr => ValueData {
625 uint_ptr: i as usize,
626 },
627 ValueType::Uint8 => ValueData { uint8: i as u8 },
628 ValueType::Uint16 => ValueData { uint16: i as u16 },
629 ValueType::Uint32 => ValueData { uint32: i as u32 },
630 ValueType::Uint64 => ValueData { uint64: i as u64 },
631 ValueType::Float32 => ValueData {
632 float32: F32::from(i as f32),
633 },
634 ValueType::Float64 => ValueData {
635 float64: F64::from(i as f64),
636 },
637 _ => unreachable!(),
638 }
639 }
640
641 #[inline]
642 pub(crate) fn as_index(&self, t: ValueType) -> usize {
643 match t {
644 ValueType::Int => *self.as_int() as usize,
645 ValueType::Int8 => *self.as_int8() as usize,
646 ValueType::Int16 => *self.as_int16() as usize,
647 ValueType::Int32 => *self.as_int32() as usize,
648 ValueType::Int64 => *self.as_int64() as usize,
649 ValueType::Uint => *self.as_uint() as usize,
650 ValueType::Uint8 => *self.as_uint8() as usize,
651 ValueType::Uint16 => *self.as_uint16() as usize,
652 ValueType::Uint32 => *self.as_uint32() as usize,
653 ValueType::Uint64 => *self.as_uint64() as usize,
654 _ => unreachable!(),
655 }
656 }
657
658 #[inline]
659 pub(crate) fn add_str(&self, b: &ValueData) -> ValueData {
660 let s = self.as_string().add(b.as_string());
661 ValueData::new_string(s)
662 }
663
664 #[inline]
665 pub(crate) fn cast_copyable(&self, from: ValueType, to: ValueType) -> ValueData {
666 let mut v = unsafe { self.copy_non_ptr() };
667 match to {
668 ValueType::Int => convert_to_int!(&mut v, from, int, isize),
669 ValueType::Int8 => convert_to_int!(&mut v, from, int8, i8),
670 ValueType::Int16 => convert_to_int!(&mut v, from, int16, i16),
671 ValueType::Int32 => convert_to_int!(&mut v, from, int32, i32),
672 ValueType::Int64 => convert_to_int!(&mut v, from, int64, i64),
673 ValueType::Uint => convert_to_int!(&mut v, from, uint, usize),
674 ValueType::UintPtr => convert_to_int!(&mut v, from, uint_ptr, usize),
675 ValueType::Uint8 => convert_to_int!(&mut v, from, uint8, u8),
676 ValueType::Uint16 => convert_to_int!(&mut v, from, uint16, u16),
677 ValueType::Uint32 => convert_to_int!(&mut v, from, uint32, u32),
678 ValueType::Uint64 => convert_to_int!(&mut v, from, uint64, u64),
679 ValueType::Float32 => convert_to_float!(&mut v, from, float32, F32, f32),
680 ValueType::Float64 => convert_to_float!(&mut v, from, float64, F64, f64),
681 _ => unreachable!(),
682 }
683 v
684 }
685
686 #[inline]
687 pub(crate) fn unary_negate(&self, t: ValueType) -> ValueData {
688 let mut v = unsafe { self.copy_non_ptr() };
689 match t {
690 ValueType::Int => v.int = -unsafe { self.int },
691 ValueType::Int8 => v.int8 = -unsafe { self.int8 },
692 ValueType::Int16 => v.int16 = -unsafe { self.int16 },
693 ValueType::Int32 => v.int32 = -unsafe { self.int32 },
694 ValueType::Int64 => v.int64 = -unsafe { self.int64 },
695 ValueType::Float32 => v.float32 = -unsafe { self.float32 },
696 ValueType::Float64 => v.float64 = -unsafe { self.float64 },
697 ValueType::Uint => v.uint = unsafe { (!0) ^ self.uint } + 1,
698 ValueType::Uint8 => v.uint8 = unsafe { (!0) ^ self.uint8 } + 1,
699 ValueType::Uint16 => v.uint16 = unsafe { (!0) ^ self.uint16 } + 1,
700 ValueType::Uint32 => v.uint32 = unsafe { (!0) ^ self.uint32 } + 1,
701 ValueType::Uint64 => v.uint64 = unsafe { (!0) ^ self.uint64 } + 1,
702 _ => unreachable!(),
703 };
704 v
705 }
706
707 #[inline]
708 pub(crate) fn unary_xor(&self, t: ValueType) -> ValueData {
709 let mut v = unsafe { self.copy_non_ptr() };
710 match t {
711 ValueType::Uint => v.uint = unsafe { (!0) ^ self.uint },
712 ValueType::Uint8 => v.uint8 = unsafe { (!0) ^ self.uint8 },
713 ValueType::Uint16 => v.uint16 = unsafe { (!0) ^ self.uint16 },
714 ValueType::Uint32 => v.uint32 = unsafe { (!0) ^ self.uint32 },
715 ValueType::Uint64 => v.uint64 = unsafe { (!0) ^ self.uint64 },
716 ValueType::Int => v.int = unsafe { -1 ^ self.int },
717 ValueType::Int8 => v.int8 = unsafe { -1 ^ self.int8 },
718 ValueType::Int16 => v.int16 = unsafe { -1 ^ self.int16 },
719 ValueType::Int32 => v.int32 = unsafe { -1 ^ self.int32 },
720 ValueType::Int64 => v.int64 = unsafe { -1 ^ self.int64 },
721 _ => unreachable!(),
722 }
723 v
724 }
725
726 #[inline]
727 pub(crate) fn logical_not(&self, t: ValueType) -> ValueData {
728 debug_assert!(t == ValueType::Bool);
729 let mut v = unsafe { self.copy_non_ptr() };
730 v.boolean = unsafe { !self.boolean };
731 v
732 }
733
734 #[inline]
735 pub(crate) fn inc(&self, t: ValueType) -> ValueData {
736 let mut v = unsafe { self.copy_non_ptr() };
737 match t {
738 ValueType::Int => v.int = unsafe { self.int } + 1,
739 ValueType::Int8 => v.int8 = unsafe { self.int8 } + 1,
740 ValueType::Int16 => v.int16 = unsafe { self.int16 } + 1,
741 ValueType::Int32 => v.int32 = unsafe { self.int32 } + 1,
742 ValueType::Int64 => v.int64 = unsafe { self.int64 } + 1,
743 ValueType::Float32 => v.float32 = unsafe { self.float32 } + 1.0,
744 ValueType::Float64 => v.float64 = unsafe { self.float64 } + 1.0,
745 ValueType::Uint => v.uint = unsafe { self.uint } + 1,
746 ValueType::Uint8 => v.uint8 = unsafe { self.uint8 } + 1,
747 ValueType::Uint16 => v.uint16 = unsafe { self.uint16 } + 1,
748 ValueType::Uint32 => v.uint32 = unsafe { self.uint32 } + 1,
749 ValueType::Uint64 => v.uint64 = unsafe { self.uint64 } + 1,
750 _ => unreachable!(),
751 };
752 v
753 }
754
755 #[inline]
756 pub(crate) fn dec(&self, t: ValueType) -> ValueData {
757 let mut v = unsafe { self.copy_non_ptr() };
758 match t {
759 ValueType::Int => v.int = unsafe { self.int } - 1,
760 ValueType::Int8 => v.int8 = unsafe { self.int8 } - 1,
761 ValueType::Int16 => v.int16 = unsafe { self.int16 } - 1,
762 ValueType::Int32 => v.int32 = unsafe { self.int32 } - 1,
763 ValueType::Int64 => v.int64 = unsafe { self.int64 } - 1,
764 ValueType::Float32 => v.float32 = unsafe { self.float32 } - 1.0,
765 ValueType::Float64 => v.float64 = unsafe { self.float64 } - 1.0,
766 ValueType::Uint => v.uint = unsafe { self.uint } - 1,
767 ValueType::Uint8 => v.uint8 = unsafe { self.uint8 } - 1,
768 ValueType::Uint16 => v.uint16 = unsafe { self.uint16 } - 1,
769 ValueType::Uint32 => v.uint32 = unsafe { self.uint32 } - 1,
770 ValueType::Uint64 => v.uint64 = unsafe { self.uint64 } - 1,
771 _ => unreachable!(),
772 };
773 v
774 }
775
776 #[inline]
777 pub(crate) fn binary_op_add(&self, b: &ValueData, t: ValueType) -> ValueData {
778 unsafe { binary_op_int_float_str!(t, self, b, +) }
779 }
780
781 #[inline]
782 pub(crate) fn binary_op_sub(&self, b: &ValueData, t: ValueType) -> ValueData {
783 unsafe { binary_op_int_float_str!(t, self, b, -) }
784 }
785
786 #[inline]
787 pub(crate) fn binary_op_mul(&self, b: &ValueData, t: ValueType) -> ValueData {
788 unsafe { binary_op_int_float_str!(t, self, b, *) }
789 }
790
791 #[inline]
792 pub(crate) fn binary_op_quo(&self, b: &ValueData, t: ValueType) -> ValueData {
793 unsafe { binary_op_int_float_str!(t, self, b, /) }
794 }
795
796 #[inline]
797 pub(crate) fn binary_op_rem(&self, b: &ValueData, t: ValueType) -> ValueData {
798 unsafe { binary_op_int_no_wrap!(t, self, b, %) }
799 }
800
801 #[inline]
802 pub(crate) fn binary_op_and(&self, b: &ValueData, t: ValueType) -> ValueData {
803 unsafe { binary_op_int_no_wrap!(t, self, b, &) }
804 }
805
806 #[inline]
807 pub(crate) fn binary_op_or(&self, b: &ValueData, t: ValueType) -> ValueData {
808 unsafe { binary_op_int_no_wrap!(t, self, b, |) }
809 }
810
811 #[inline]
812 pub(crate) fn binary_op_xor(&self, b: &ValueData, t: ValueType) -> ValueData {
813 unsafe { binary_op_int_no_wrap!(t, self, b, ^) }
814 }
815
816 #[inline]
817 pub(crate) fn binary_op_shl(&self, b: &u32, t: ValueType) -> ValueData {
818 unsafe { shift_int!(t, self, b, checked_shl) }
819 }
820
821 #[inline]
822 pub(crate) fn binary_op_shr(&self, b: &u32, t: ValueType) -> ValueData {
823 unsafe { shift_int!(t, self, b, checked_shr) }
824 }
825
826 #[inline]
827 pub(crate) fn binary_op_and_not(&self, b: &ValueData, t: ValueType) -> ValueData {
828 unsafe {
829 match t {
830 ValueType::Int => ValueData {
831 int: self.int & !b.int,
832 },
833 ValueType::Int8 => ValueData {
834 int8: self.int8 & !b.int8,
835 },
836 ValueType::Int16 => ValueData {
837 int16: self.int16 & !b.int16,
838 },
839 ValueType::Int32 => ValueData {
840 int32: self.int32 & !b.int32,
841 },
842 ValueType::Int64 => ValueData {
843 int64: self.int64 & !b.int64,
844 },
845 ValueType::Uint => ValueData {
846 uint: self.uint & !b.uint,
847 },
848 ValueType::Uint8 => ValueData {
849 uint8: self.uint8 & !b.uint8,
850 },
851 ValueType::Uint16 => ValueData {
852 uint16: self.uint16 & !b.uint16,
853 },
854 ValueType::Uint32 => ValueData {
855 uint32: self.uint32 & !b.uint32,
856 },
857 ValueType::Uint64 => ValueData {
858 uint64: self.uint64 & !b.uint64,
859 },
860 _ => unreachable!(),
861 }
862 }
863 }
864
865 #[inline]
866 pub(crate) fn compare_eql(&self, b: &ValueData, t: ValueType) -> bool {
867 unsafe { cmp_bool_int_float!(t, self, b, ==) }
868 }
869
870 #[inline]
871 pub(crate) fn compare_neq(&self, b: &ValueData, t: ValueType) -> bool {
872 unsafe { cmp_bool_int_float!(t, self, b, !=) }
873 }
874
875 #[inline]
876 pub(crate) fn compare_lss(&self, b: &ValueData, t: ValueType) -> bool {
877 unsafe { cmp_int_float!(t, self, b, <) }
878 }
879
880 #[inline]
881 pub(crate) fn compare_gtr(&self, b: &ValueData, t: ValueType) -> bool {
882 unsafe { cmp_int_float!(t, self, b, >) }
883 }
884
885 #[inline]
886 pub(crate) fn compare_leq(&self, b: &ValueData, t: ValueType) -> bool {
887 unsafe { cmp_int_float!(t, self, b, <=) }
888 }
889
890 #[inline]
891 pub(crate) fn compare_geq(&self, b: &ValueData, t: ValueType) -> bool {
892 unsafe { cmp_int_float!(t, self, b, >=) }
893 }
894
895 #[inline]
896 pub(crate) fn rc(&self, t: ValueType) -> Option<&Cell<IRC>> {
897 match t {
898 ValueType::Array => Some(&self.as_gos_array().1),
899 ValueType::Closure => self.as_closure().map(|x| &x.1),
900 ValueType::Map => self.as_map().map(|x| &x.1),
901 ValueType::Struct => Some(&self.as_struct().1),
902 _ => unreachable!(),
903 }
904 }
905
906 #[inline]
907 pub(crate) unsafe fn copy_non_ptr(&self) -> ValueData {
908 self.copy()
909 }
910
911 #[inline]
912 fn from_metadata(m: Box<Meta>) -> ValueData {
913 ValueData {
914 metadata: Box::into_raw(m),
915 }
916 }
917
918 #[inline]
919 fn from_complex128(c: Box<Complex128>) -> ValueData {
920 ValueData {
921 complex128: Box::into_raw(c),
922 }
923 }
924
925 #[inline]
926 fn from_string(s: Rc<StringObj>) -> ValueData {
927 ValueData {
928 string: Rc::into_raw(s),
929 }
930 }
931
932 #[inline]
933 fn from_array<T>(rc: Rc<(ArrayObj<T>, RCount)>) -> ValueData {
934 let p = Rc::into_raw(rc);
935 ValueData {
936 slice: unsafe { std::mem::transmute(p) },
937 }
938 }
939
940 #[inline]
941 fn from_struct(s: Rc<(StructObj, RCount)>) -> ValueData {
942 ValueData {
943 structure: Rc::into_raw(s),
944 }
945 }
946
947 #[inline]
948 fn from_pointer(p: OptionBox<PointerObj>) -> ValueData {
949 ValueData {
950 pointer: p.map_or(ptr::null_mut(), |x| Box::into_raw(x)),
951 }
952 }
953
954 #[inline]
955 fn from_unsafe_ptr(p: OptionBox<UnsafePtrObj>) -> ValueData {
956 ValueData {
957 unsafe_ptr: p.map_or(ptr::null_mut(), |x| Box::into_raw(x)),
958 }
959 }
960
961 #[inline]
962 fn from_closure(cls: OptionRc<(ClosureObj, RCount)>) -> ValueData {
963 ValueData {
964 closure: cls.map_or(ptr::null(), |x| Rc::into_raw(x)),
965 }
966 }
967
968 #[inline]
969 fn from_slice<T>(s: OptionRc<(SliceObj<T>, RCount)>) -> ValueData {
970 s.map_or(ValueData { slice: ptr::null() }, |x| {
971 let p = Rc::into_raw(x);
972 ValueData {
973 slice: unsafe { std::mem::transmute(p) },
974 }
975 })
976 }
977
978 #[inline]
979 fn from_map(m: OptionRc<(MapObj, RCount)>) -> ValueData {
980 ValueData {
981 map: m.map_or(ptr::null(), |x| Rc::into_raw(x)),
982 }
983 }
984
985 #[inline]
986 fn from_interface(i: OptionRc<InterfaceObj>) -> ValueData {
987 ValueData {
988 interface: i.map_or(ptr::null(), |x| Rc::into_raw(x)),
989 }
990 }
991
992 #[cfg(feature = "async")]
993 #[inline]
994 fn from_channel(c: OptionRc<ChannelObj>) -> ValueData {
995 ValueData {
996 channel: c.map_or(ptr::null(), |x| Rc::into_raw(x)),
997 }
998 }
999
1000 #[inline]
1001 fn new_metadata(m: Meta) -> ValueData {
1002 ValueData::from_metadata(Box::new(m))
1003 }
1004
1005 #[inline]
1006 fn new_complex128(r: F64, i: F64) -> ValueData {
1007 ValueData::from_complex128(Box::new(Complex128 { r, i }))
1008 }
1009
1010 #[inline]
1011 fn new_string(s: StringObj) -> ValueData {
1012 ValueData::from_string(Rc::new(s))
1013 }
1014
1015 #[inline]
1016 fn new_array<T>(arr: ArrayObj<T>, gcc: &GcContainer) -> ValueData
1017 where
1018 T: Element,
1019 {
1020 let rc = Rc::new((arr, Cell::new(0)));
1021 if T::need_gc() {
1022 gcc.add_array(&ValueData::from_array(rc.clone()).into_array::<GosElem>());
1023 }
1024 ValueData::from_array(rc)
1025 }
1026
1027 #[inline]
1028 fn new_non_gc_array<T>(arr: ArrayObj<T>) -> ValueData
1029 where
1030 T: Element,
1031 {
1032 debug_assert!(!T::need_gc());
1033 let rc = Rc::new((arr, Cell::new(0)));
1034 ValueData::from_array(rc)
1035 }
1036
1037 #[inline]
1038 fn new_struct(obj: StructObj, gcc: &GcContainer) -> ValueData {
1039 let s = Rc::new((obj, Cell::new(0)));
1040 gcc.add_struct(&s);
1041 ValueData::from_struct(s)
1042 }
1043
1044 #[inline]
1045 fn new_pointer(obj: PointerObj) -> ValueData {
1046 ValueData::from_pointer(Some(Box::new(obj)))
1047 }
1048
1049 #[inline]
1050 fn new_unsafe_ptr(p: Rc<dyn UnsafePtr>) -> ValueData {
1051 ValueData::from_unsafe_ptr(Some(Box::new(UnsafePtrObj::new(p))))
1052 }
1053
1054 #[inline]
1055 fn new_closure(obj: ClosureObj, gcc: &GcContainer) -> ValueData {
1056 let cls = Rc::new((obj, Cell::new(0)));
1057 gcc.add_closure(&cls);
1058 ValueData::from_closure(Some(cls))
1059 }
1060
1061 #[inline]
1062 fn new_closure_static(
1063 func: FunctionKey,
1064 up_ptrs: Option<&Vec<ValueDesc>>,
1065 meta: Meta,
1066 ) -> ValueData {
1067 let obj = ClosureObj::new_gos(func, up_ptrs, None, meta);
1068 ValueData::from_closure(Some(Rc::new((obj, Cell::new(0)))))
1069 }
1070
1071 #[inline]
1072 fn new_slice<T>(slice: SliceObj<T>) -> ValueData {
1073 let rc = Rc::new((slice, Cell::new(0)));
1074 ValueData::from_slice(Some(rc))
1075 }
1076
1077 #[inline]
1078 fn new_map(obj: MapObj, gcc: &GcContainer) -> ValueData {
1079 let m = Rc::new((obj, Cell::new(0)));
1080 gcc.add_map(&m);
1081 ValueData::from_map(Some(m))
1082 }
1083
1084 #[inline]
1085 fn new_interface(obj: InterfaceObj) -> ValueData {
1086 ValueData::from_interface(Some(Rc::new(obj)))
1087 }
1088
1089 #[cfg(feature = "async")]
1090 #[inline]
1091 fn new_channel(obj: ChannelObj) -> ValueData {
1092 ValueData::from_channel(Some(Rc::new(obj)))
1093 }
1094
1095 #[inline]
1096 fn into_metadata(self) -> Box<Meta> {
1097 unsafe { Box::from_raw(self.metadata) }
1098 }
1099
1100 #[inline]
1101 fn into_complex128(self) -> Box<Complex128> {
1102 unsafe { Box::from_raw(self.complex128) }
1103 }
1104
1105 #[inline]
1106 fn into_string(self) -> Rc<StringObj> {
1107 unsafe { Rc::from_raw(self.string) }
1108 }
1109
1110 #[inline]
1111 fn into_array<T>(self) -> Rc<(ArrayObj<T>, RCount)> {
1112 let p = unsafe { std::mem::transmute(self.array) };
1113 unsafe { Rc::from_raw(p) }
1114 }
1115
1116 #[inline]
1117 fn into_struct(self) -> Rc<(StructObj, RCount)> {
1118 unsafe { Rc::from_raw(self.structure) }
1119 }
1120
1121 #[inline]
1122 fn into_pointer(self) -> OptionBox<PointerObj> {
1123 unsafe { (!self.pointer.is_null()).then(|| Box::from_raw(self.pointer)) }
1124 }
1125
1126 #[inline]
1127 fn into_unsafe_ptr(self) -> OptionBox<UnsafePtrObj> {
1128 unsafe { (!self.unsafe_ptr.is_null()).then(|| Box::from_raw(self.unsafe_ptr)) }
1129 }
1130
1131 #[inline]
1132 fn into_closure(self) -> OptionRc<(ClosureObj, RCount)> {
1133 unsafe { (!self.closure.is_null()).then(|| Rc::from_raw(self.closure)) }
1134 }
1135
1136 #[inline]
1137 fn into_slice<T>(self) -> OptionRc<(SliceObj<T>, RCount)> {
1138 let p = unsafe { std::mem::transmute(self.slice) };
1139 unsafe { (!self.slice.is_null()).then(|| Rc::from_raw(p)) }
1140 }
1141
1142 #[inline]
1143 fn into_map(self) -> OptionRc<(MapObj, RCount)> {
1144 unsafe { (!self.map.is_null()).then(|| Rc::from_raw(self.map)) }
1145 }
1146
1147 #[inline]
1148 fn into_interface(self) -> OptionRc<InterfaceObj> {
1149 unsafe { (!self.interface.is_null()).then(|| Rc::from_raw(self.interface)) }
1150 }
1151
1152 #[cfg(feature = "async")]
1153 #[inline]
1154 fn into_channel(self) -> OptionRc<ChannelObj> {
1155 unsafe { (!self.channel.is_null()).then(|| Rc::from_raw(self.channel)) }
1156 }
1157
1158 #[inline]
1159 fn clone(&self, t: ValueType) -> ValueData {
1160 match t {
1161 ValueType::Metadata => ValueData::from_metadata(Box::new(self.as_metadata().clone())),
1162 ValueType::Complex128 => {
1163 ValueData::from_complex128(Box::new(self.as_complex128().clone()))
1164 }
1165 ValueType::String => unsafe {
1166 Rc::increment_strong_count(self.string);
1167 self.copy()
1168 },
1169 ValueType::Array => unsafe {
1170 Rc::increment_strong_count(self.array);
1171 self.copy()
1172 },
1173 ValueType::Struct => unsafe {
1174 Rc::increment_strong_count(self.structure);
1175 self.copy()
1176 },
1177 ValueType::Pointer => {
1178 ValueData::from_pointer(self.as_pointer().map(|x| Box::new(x.clone())))
1179 }
1180 ValueType::UnsafePtr => {
1181 ValueData::from_unsafe_ptr(self.as_unsafe_ptr().map(|x| Box::new(x.clone())))
1182 }
1183 ValueType::Closure => unsafe {
1184 if !self.closure.is_null() {
1185 Rc::increment_strong_count(self.closure);
1186 }
1187 self.copy()
1188 },
1189 ValueType::Slice => unsafe {
1190 if !self.slice.is_null() {
1191 Rc::increment_strong_count(self.slice);
1192 }
1193 self.copy()
1194 },
1195 ValueType::Map => unsafe {
1196 if !self.map.is_null() {
1197 Rc::increment_strong_count(self.map);
1198 }
1199 self.copy()
1200 },
1201 ValueType::Interface => unsafe {
1202 if !self.interface.is_null() {
1203 Rc::increment_strong_count(self.interface);
1204 }
1205 self.copy()
1206 },
1207 #[cfg(feature = "async")]
1208 ValueType::Channel => unsafe {
1209 if !self.channel.is_null() {
1210 Rc::increment_strong_count(self.pointer);
1211 }
1212 self.copy()
1213 },
1214 _ => self.copy(),
1215 }
1216 }
1217
1218 #[inline]
1219 fn copy_semantic(&self, t: ValueType, t_elem: ValueType, gcc: &GcContainer) -> ValueData {
1220 match t {
1221 _ if t != ValueType::Array
1222 && t != ValueType::Struct
1223 && t != ValueType::Slice
1224 && t != ValueType::Map =>
1225 {
1226 self.clone(t)
1227 }
1228 ValueType::Array => ArrCaller::get_slow(t_elem).array_copy_semantic(self, gcc),
1229 ValueType::Struct => ValueData::new_struct(StructObj::clone(&self.as_struct().0), gcc),
1230 ValueType::Slice => ArrCaller::get_slow(t_elem).slice_copy_semantic(self),
1231 ValueType::Map => match self.as_map() {
1232 Some(m) => ValueData::new_map(m.0.clone(), gcc),
1233 None => ValueData::new_nil(t),
1234 },
1235 _ => unreachable!(),
1236 }
1237 }
1238
1239 #[inline]
1240 fn copy(&self) -> ValueData {
1241 unsafe { std::mem::transmute_copy(self) }
1242 }
1243
1244 #[inline]
1245 fn drop_as_ptr(&self, t: ValueType, t_elem: ValueType) {
1246 match t {
1247 ValueType::Metadata => {
1248 self.copy().into_metadata();
1249 }
1250 ValueType::Complex128 => {
1251 self.copy().into_complex128();
1252 }
1253 ValueType::String => {
1254 self.copy().into_string();
1255 }
1256 ValueType::Array => match ArrCaller::get_elem_type(t_elem) {
1258 ElemType::ElemType8 => drop(self.copy().into_array::<Elem8>()),
1259 ElemType::ElemType16 => drop(self.copy().into_array::<Elem16>()),
1260 ElemType::ElemType32 => drop(self.copy().into_array::<Elem32>()),
1261 ElemType::ElemType64 => drop(self.copy().into_array::<Elem64>()),
1262 ElemType::ElemTypeWord => drop(self.copy().into_array::<ElemWord>()),
1263 ElemType::ElemTypeGos => drop(self.copy().into_array::<GosElem>()),
1264 },
1265 ValueType::Pointer => {
1266 self.copy().into_pointer();
1267 }
1268 ValueType::UnsafePtr => {
1269 self.copy().into_unsafe_ptr();
1270 }
1271 ValueType::Closure => {
1272 self.copy().into_closure();
1273 }
1274 ValueType::Slice => match ArrCaller::get_elem_type(t_elem) {
1276 ElemType::ElemType8 => drop(self.copy().into_slice::<Elem8>()),
1277 ElemType::ElemType16 => drop(self.copy().into_slice::<Elem16>()),
1278 ElemType::ElemType32 => drop(self.copy().into_slice::<Elem32>()),
1279 ElemType::ElemType64 => drop(self.copy().into_slice::<Elem64>()),
1280 ElemType::ElemTypeWord => drop(self.copy().into_slice::<ElemWord>()),
1281 ElemType::ElemTypeGos => drop(self.copy().into_slice::<GosElem>()),
1282 },
1283 ValueType::Map => {
1284 self.copy().into_map();
1285 }
1286 ValueType::Interface => {
1287 self.copy().into_interface();
1288 }
1289 ValueType::Struct => {
1290 self.copy().into_struct();
1291 }
1292 #[cfg(feature = "async")]
1293 ValueType::Channel => {
1294 self.copy().into_channel();
1295 }
1296 _ => unreachable!(),
1297 }
1298 }
1299}
1300
1301impl fmt::Debug for ValueData {
1302 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1303 write!(
1304 f,
1305 "ValueData: {:#018x}/{:?}",
1306 self.as_uint(),
1307 self.as_uint()
1308 )
1309 }
1310}
1311
1312pub struct GosValue {
1313 typ: ValueType,
1314 t_elem: ValueType,
1315 data: ValueData,
1316}
1317
1318impl GosValue {
1319 #[inline]
1320 pub fn typ(&self) -> ValueType {
1321 self.typ
1322 }
1323
1324 #[inline]
1325 pub fn t_elem(&self) -> ValueType {
1326 self.t_elem
1327 }
1328
1329 #[inline]
1331 pub(crate) fn data(&self) -> &ValueData {
1332 &self.data
1333 }
1334
1335 #[inline]
1337 pub(crate) unsafe fn data_mut(&mut self) -> &mut ValueData {
1338 &mut self.data
1339 }
1340
1341 #[inline]
1342 pub(crate) fn caller<'a>(&self, c: &'a ArrCaller) -> &'a Box<dyn Dispatcher> {
1343 c.get(self.t_elem)
1344 }
1345
1346 #[inline]
1347 pub(crate) fn caller_slow(&self) -> Box<dyn Dispatcher> {
1348 ArrCaller::get_slow(self.t_elem)
1349 }
1350
1351 #[inline]
1352 pub fn copyable(&self) -> bool {
1353 self.typ.copyable()
1354 }
1355
1356 #[inline]
1357 pub fn comparable(&self) -> bool {
1358 self.typ.comparable()
1359 }
1360
1361 #[inline]
1362 pub fn nilable(&self) -> bool {
1363 self.typ.nilable()
1364 }
1365
1366 #[inline]
1367 pub(crate) fn new_nil(t: ValueType) -> GosValue {
1368 debug_assert!(t != ValueType::Slice);
1369 GosValue::new(t, ValueData::new_nil(t))
1370 }
1371
1372 #[inline]
1373 pub(crate) fn new_nil_slice(t_elem: ValueType) -> GosValue {
1374 GosValue::with_elem_type(
1375 ValueType::Slice,
1376 t_elem,
1377 ValueData::new_nil(ValueType::Slice),
1378 )
1379 }
1380
1381 #[inline]
1382 pub(crate) fn new_uint_ptr(u: usize) -> GosValue {
1383 GosValue::new(ValueType::UintPtr, ValueData::new_uint_ptr(u))
1384 }
1385
1386 #[inline]
1387 pub(crate) fn new_float32(f: F32) -> GosValue {
1388 GosValue::new(ValueType::Float32, ValueData::new_float32(f))
1389 }
1390
1391 #[inline]
1392 pub(crate) fn new_float64(f: F64) -> GosValue {
1393 GosValue::new(ValueType::Float64, ValueData::new_float64(f))
1394 }
1395
1396 #[inline]
1397 pub(crate) fn new_complex64(r: F32, i: F32) -> GosValue {
1398 GosValue::new(ValueType::Complex64, ValueData::new_complex64(r, i))
1399 }
1400
1401 #[inline]
1402 pub(crate) fn new_function(f: FunctionKey) -> GosValue {
1403 GosValue::new(ValueType::Function, ValueData::new_function(f))
1404 }
1405
1406 #[inline]
1407 pub(crate) fn new_package(p: PackageKey) -> GosValue {
1408 GosValue::new(ValueType::Package, ValueData::new_package(p))
1409 }
1410
1411 #[inline]
1412 pub(crate) fn new_metadata(m: Meta) -> GosValue {
1413 GosValue::new(ValueType::Metadata, ValueData::new_metadata(m))
1414 }
1415
1416 #[inline]
1417 pub(crate) fn new_complex128(r: F64, i: F64) -> GosValue {
1418 GosValue::new(ValueType::Complex128, ValueData::new_complex128(r, i))
1419 }
1420
1421 #[inline]
1422 pub(crate) fn new_string(s: StringObj) -> GosValue {
1423 GosValue::new(ValueType::String, ValueData::new_string(s))
1424 }
1425
1426 #[inline]
1427 pub(crate) fn with_str(s: &str) -> GosValue {
1428 GosValue::new_string(StringObj::with_str(s))
1429 }
1430
1431 #[inline]
1432 pub(crate) fn new_array<T>(obj: ArrayObj<T>, t_elem: ValueType, gcc: &GcContainer) -> GosValue
1433 where
1434 T: Element,
1435 {
1436 let data = ValueData::new_array(obj, gcc);
1437 GosValue::with_elem_type(ValueType::Array, t_elem, data)
1438 }
1439
1440 #[inline]
1441 pub(crate) fn new_non_gc_array<T>(obj: ArrayObj<T>, t_elem: ValueType) -> GosValue
1442 where
1443 T: Element,
1444 {
1445 let data = ValueData::new_non_gc_array(obj);
1446 GosValue::with_elem_type(ValueType::Array, t_elem, data)
1447 }
1448
1449 #[inline]
1450 pub(crate) fn new_struct(obj: StructObj, gcc: &GcContainer) -> GosValue {
1451 let data = ValueData::new_struct(obj, gcc);
1452 GosValue::new(ValueType::Struct, data)
1453 }
1454
1455 #[inline]
1456 pub(crate) fn new_pointer(obj: PointerObj) -> GosValue {
1457 GosValue::new(ValueType::Pointer, ValueData::new_pointer(obj))
1458 }
1459
1460 #[inline]
1461 pub(crate) fn new_unsafe_ptr(p: Rc<dyn UnsafePtr>) -> GosValue {
1462 GosValue::new(ValueType::UnsafePtr, ValueData::new_unsafe_ptr(p))
1463 }
1464
1465 #[inline]
1466 pub(crate) fn new_closure(obj: ClosureObj, gcc: &GcContainer) -> GosValue {
1467 let data = ValueData::new_closure(obj, gcc);
1468 GosValue::new(ValueType::Closure, data)
1469 }
1470
1471 #[inline]
1472 pub(crate) fn new_closure_static(
1473 func: FunctionKey,
1474 up_ptrs: Option<&Vec<ValueDesc>>,
1475 meta: Meta,
1476 ) -> GosValue {
1477 GosValue::new(
1478 ValueType::Closure,
1479 ValueData::new_closure_static(func, up_ptrs, meta),
1480 )
1481 }
1482
1483 #[inline]
1484 pub fn new_slice<T>(obj: SliceObj<T>, t_elem: ValueType) -> GosValue
1485 where
1486 T: Element,
1487 {
1488 GosValue::with_elem_type(ValueType::Slice, t_elem, ValueData::new_slice(obj))
1489 }
1490
1491 #[inline]
1492 pub(crate) fn new_map(gcc: &GcContainer) -> GosValue {
1493 let data = ValueData::new_map(MapObj::new(), gcc);
1494 GosValue::new(ValueType::Map, data)
1495 }
1496
1497 #[inline]
1498 pub(crate) fn new_interface(obj: InterfaceObj) -> GosValue {
1499 GosValue::new(ValueType::Interface, ValueData::new_interface(obj))
1500 }
1501
1502 #[cfg(feature = "async")]
1503 #[inline]
1504 pub(crate) fn new_channel(obj: ChannelObj) -> GosValue {
1505 GosValue::new(ValueType::Channel, ValueData::new_channel(obj))
1506 }
1507
1508 #[inline]
1509 pub(crate) fn array_with_size(
1510 size: usize,
1511 cap: usize,
1512 val: &GosValue,
1513 caller: &Box<dyn Dispatcher>,
1514 gcc: &GcContainer,
1515 ) -> GosValue {
1516 debug_assert!(caller.typ() != ValueType::Void);
1517 caller.array_with_size(size, cap, val, gcc)
1518 }
1519
1520 #[inline]
1521 pub(crate) fn array_with_data(
1522 data: Vec<GosValue>,
1523 caller: &Box<dyn Dispatcher>,
1524 gcc: &GcContainer,
1525 ) -> GosValue {
1526 debug_assert!(caller.typ() != ValueType::Void);
1527 caller.array_with_data(data, gcc)
1528 }
1529
1530 #[inline]
1531 pub(crate) fn slice_with_size(
1532 size: usize,
1533 cap: usize,
1534 val: &GosValue,
1535 caller: &Box<dyn Dispatcher>,
1536 gcc: &GcContainer,
1537 ) -> GosValue {
1538 let arr = GosValue::array_with_size(size, cap, val, caller, gcc);
1539 GosValue::slice_array(arr, 0, size as isize, caller).unwrap()
1540 }
1541
1542 #[inline]
1543 pub(crate) fn slice_with_data(
1544 data: Vec<GosValue>,
1545 caller: &Box<dyn Dispatcher>,
1546 gcc: &GcContainer,
1547 ) -> GosValue {
1548 assert!(caller.typ() != ValueType::Void);
1549 let len = data.len();
1550 let arr = GosValue::array_with_data(data, caller, gcc);
1551 GosValue::slice_array(arr, 0, len as isize, caller).unwrap()
1552 }
1553
1554 #[inline]
1555 pub(crate) fn slice_array(
1556 arr: GosValue,
1557 begin: isize,
1558 end: isize,
1559 caller: &Box<dyn Dispatcher>,
1560 ) -> RuntimeResult<GosValue> {
1561 caller.slice_array(arr, begin, end)
1562 }
1563
1564 #[inline]
1565 pub(crate) fn map_with_data(data: GosMap, gcc: &GcContainer) -> GosValue {
1566 let m = MapObj::with_data(data);
1567 let data = ValueData::new_map(m, gcc);
1568 GosValue::new(ValueType::Map, data)
1569 }
1570
1571 #[inline]
1572 pub(crate) fn empty_iface_with_val(val: GosValue) -> GosValue {
1573 GosValue::new_interface(InterfaceObj::with_value(val, None))
1574 }
1575
1576 #[cfg(feature = "async")]
1577 #[inline]
1578 pub(crate) fn channel_with_chan(chan: Channel, recv_zero: GosValue) -> GosValue {
1579 GosValue::new_channel(ChannelObj::with_chan(chan, recv_zero))
1580 }
1581
1582 #[inline]
1583 pub(crate) fn from_string(s: Rc<StringObj>) -> GosValue {
1584 GosValue::new(ValueType::String, ValueData::from_string(s))
1585 }
1586
1587 #[inline]
1588 pub(crate) fn from_gos_array(arr: Rc<(GosArrayObj, RCount)>) -> GosValue {
1589 GosValue::with_elem_type(
1590 ValueType::Array,
1591 ValueType::Void,
1592 ValueData::from_array(arr),
1593 )
1594 }
1595
1596 #[inline]
1597 pub(crate) fn from_struct(s: Rc<(StructObj, RCount)>) -> GosValue {
1598 GosValue::new(ValueType::Struct, ValueData::from_struct(s))
1599 }
1600
1601 #[inline]
1602 pub(crate) fn from_closure(cls: OptionRc<(ClosureObj, RCount)>) -> GosValue {
1603 GosValue::new(ValueType::Closure, ValueData::from_closure(cls))
1604 }
1605
1606 #[inline]
1607 pub(crate) fn from_slice<T>(s: OptionRc<(SliceObj<T>, RCount)>) -> GosValue {
1608 GosValue::new(ValueType::Slice, ValueData::from_slice(s))
1609 }
1610
1611 #[inline]
1612 pub(crate) fn from_map(m: OptionRc<(MapObj, RCount)>) -> GosValue {
1613 GosValue::new(ValueType::Map, ValueData::from_map(m))
1614 }
1615
1616 #[inline]
1617 pub(crate) fn from_interface(i: OptionRc<InterfaceObj>) -> GosValue {
1618 GosValue::new(ValueType::Interface, ValueData::from_interface(i))
1619 }
1620
1621 #[cfg(feature = "async")]
1622 #[inline]
1623 pub(crate) fn from_channel(c: OptionRc<ChannelObj>) -> GosValue {
1624 GosValue::new(ValueType::Channel, ValueData::from_channel(c))
1625 }
1626
1627 #[inline]
1628 pub(crate) fn into_metadata(mut self) -> Box<Meta> {
1629 debug_assert!(self.typ == ValueType::Metadata);
1630 self.typ = ValueType::Void;
1631 self.data.copy().into_metadata()
1632 }
1633
1634 #[inline]
1635 pub(crate) fn into_complex128(mut self) -> Box<Complex128> {
1636 debug_assert!(self.typ == ValueType::Complex128);
1637 self.typ = ValueType::Void;
1638 self.data.copy().into_complex128()
1639 }
1640
1641 #[inline]
1642 pub(crate) fn into_string(mut self) -> Rc<StringObj> {
1643 debug_assert!(self.typ == ValueType::String);
1644 self.typ = ValueType::Void;
1645 self.data.copy().into_string()
1646 }
1647
1648 #[inline]
1649 pub(crate) fn into_array<T>(mut self) -> Rc<(ArrayObj<T>, RCount)> {
1650 debug_assert!(self.typ == ValueType::Array);
1651 self.typ = ValueType::Void;
1652 self.data.copy().into_array()
1653 }
1654
1655 #[inline]
1656 pub(crate) fn into_gos_array(mut self) -> Rc<(GosArrayObj, RCount)> {
1657 debug_assert!(self.typ == ValueType::Array);
1658 self.typ = ValueType::Void;
1659 self.data.copy().into_array()
1660 }
1661
1662 #[inline]
1663 pub(crate) fn into_struct(mut self) -> Rc<(StructObj, RCount)> {
1664 debug_assert!(self.typ == ValueType::Struct);
1665 self.typ = ValueType::Void;
1666 self.data.copy().into_struct()
1667 }
1668
1669 #[inline]
1670 pub(crate) fn into_pointer(mut self) -> OptionBox<PointerObj> {
1671 debug_assert!(self.typ == ValueType::Pointer);
1672 self.typ = ValueType::Void;
1673 self.data.copy().into_pointer()
1674 }
1675
1676 #[inline]
1677 pub(crate) fn into_unsafe_ptr(mut self) -> OptionBox<UnsafePtrObj> {
1678 debug_assert!(self.typ == ValueType::UnsafePtr);
1679 self.typ = ValueType::Void;
1680 self.data.copy().into_unsafe_ptr()
1681 }
1682
1683 #[inline]
1684 pub(crate) fn into_closure(mut self) -> OptionRc<(ClosureObj, RCount)> {
1685 debug_assert!(self.typ == ValueType::Closure);
1686 self.typ = ValueType::Void;
1687 self.data.copy().into_closure()
1688 }
1689
1690 #[inline]
1691 pub(crate) fn into_slice<T>(mut self) -> OptionRc<(SliceObj<T>, RCount)> {
1692 debug_assert!(self.typ == ValueType::Slice);
1693 self.typ = ValueType::Void;
1694 self.data.copy().into_slice()
1695 }
1696
1697 #[inline]
1698 pub(crate) fn into_map(mut self) -> OptionRc<(MapObj, RCount)> {
1699 debug_assert!(self.typ == ValueType::Map);
1700 self.typ = ValueType::Void;
1701 self.data.copy().into_map()
1702 }
1703
1704 #[inline]
1705 pub(crate) fn into_interface(mut self) -> OptionRc<InterfaceObj> {
1706 debug_assert!(self.typ == ValueType::Interface);
1707 self.typ = ValueType::Void;
1708 self.data.copy().into_interface()
1709 }
1710
1711 #[cfg(feature = "async")]
1712 #[inline]
1713 pub(crate) fn into_channel(mut self) -> OptionRc<ChannelObj> {
1714 debug_assert!(self.typ == ValueType::Channel);
1715 self.typ = ValueType::Void;
1716 self.data.copy().into_channel()
1717 }
1718
1719 #[inline]
1720 pub(crate) fn into_non_nil_pointer(self) -> RuntimeResult<Box<PointerObj>> {
1721 self.into_pointer().ok_or(nil_err_str!())
1722 }
1723
1724 #[inline]
1725 pub(crate) fn into_non_nil_unsafe_ptr(self) -> RuntimeResult<Box<UnsafePtrObj>> {
1726 self.into_unsafe_ptr().ok_or(nil_err_str!())
1727 }
1728
1729 #[inline]
1730 pub(crate) fn into_non_nil_closure(self) -> RuntimeResult<Rc<(ClosureObj, RCount)>> {
1731 self.into_closure().ok_or(nil_err_str!())
1732 }
1733
1734 #[inline]
1735 pub(crate) fn into_non_nil_slice<T>(self) -> RuntimeResult<Rc<(SliceObj<T>, RCount)>> {
1736 self.into_slice().ok_or(nil_err_str!())
1737 }
1738
1739 #[inline]
1740 pub(crate) fn into_non_nil_map(self) -> RuntimeResult<Rc<(MapObj, RCount)>> {
1741 self.into_map().ok_or(nil_err_str!())
1742 }
1743
1744 #[inline]
1745 pub(crate) fn into_non_nil_interface(self) -> RuntimeResult<Rc<InterfaceObj>> {
1746 self.into_interface().ok_or(nil_err_str!())
1747 }
1748
1749 #[cfg(feature = "async")]
1750 #[inline]
1751 pub(crate) fn into_non_nil_channel(self) -> RuntimeResult<Rc<ChannelObj>> {
1752 self.into_channel().ok_or(nil_err_str!())
1753 }
1754
1755 #[inline]
1756 pub fn as_bool(&self) -> &bool {
1757 debug_assert!(self.copyable());
1758 self.data.as_bool()
1759 }
1760
1761 #[inline]
1762 pub fn as_int(&self) -> &isize {
1763 debug_assert!(self.copyable());
1764 self.data.as_int()
1765 }
1766
1767 #[inline]
1768 pub fn as_int8(&self) -> &i8 {
1769 debug_assert!(self.copyable());
1770 self.data.as_int8()
1771 }
1772
1773 #[inline]
1774 pub fn as_int16(&self) -> &i16 {
1775 debug_assert!(self.copyable());
1776 self.data.as_int16()
1777 }
1778
1779 #[inline]
1780 pub fn as_int32(&self) -> &i32 {
1781 debug_assert!(self.copyable());
1782 self.data.as_int32()
1783 }
1784
1785 #[inline]
1786 pub fn as_int64(&self) -> &i64 {
1787 debug_assert!(self.copyable());
1788 self.data.as_int64()
1789 }
1790
1791 #[inline]
1792 pub fn as_uint(&self) -> &usize {
1793 debug_assert!(self.copyable());
1794 self.data.as_uint()
1795 }
1796
1797 #[inline]
1798 pub fn as_uint_ptr(&self) -> &usize {
1799 debug_assert!(self.copyable());
1800 self.data.as_uint_ptr()
1801 }
1802
1803 #[inline]
1804 pub fn as_uint8(&self) -> &u8 {
1805 debug_assert!(self.copyable());
1806 self.data.as_uint8()
1807 }
1808
1809 #[inline]
1810 pub fn as_uint16(&self) -> &u16 {
1811 debug_assert!(self.copyable());
1812 self.data.as_uint16()
1813 }
1814
1815 #[inline]
1816 pub fn as_uint32(&self) -> &u32 {
1817 debug_assert!(self.copyable());
1818 self.data.as_uint32()
1819 }
1820
1821 #[inline]
1822 pub fn as_uint64(&self) -> &u64 {
1823 debug_assert!(self.copyable());
1824 self.data.as_uint64()
1825 }
1826
1827 #[inline]
1828 pub fn as_float32(&self) -> &F32 {
1829 debug_assert!(self.copyable());
1830 self.data.as_float32()
1831 }
1832
1833 #[inline]
1834 pub fn as_float64(&self) -> &F64 {
1835 debug_assert!(self.copyable());
1836 self.data.as_float64()
1837 }
1838
1839 #[inline]
1840 pub fn as_complex64(&self) -> &Complex64 {
1841 debug_assert!(self.copyable());
1842 self.data.as_complex64()
1843 }
1844
1845 #[inline]
1846 pub fn as_function(&self) -> &FunctionKey {
1847 debug_assert!(self.copyable());
1848 self.data.as_function()
1849 }
1850
1851 #[inline]
1852 pub fn as_package(&self) -> &PackageKey {
1853 debug_assert!(self.copyable());
1854 self.data.as_package()
1855 }
1856
1857 #[inline]
1858 pub fn as_metadata(&self) -> &Meta {
1859 debug_assert!(self.typ == ValueType::Metadata);
1860 self.data.as_metadata()
1861 }
1862
1863 #[inline]
1864 pub fn as_complex128(&self) -> &Complex128 {
1865 debug_assert!(self.typ == ValueType::Complex128);
1866 self.data.as_complex128()
1867 }
1868
1869 #[inline]
1870 pub fn as_string(&self) -> &StringObj {
1871 debug_assert!(self.typ == ValueType::String);
1872 self.data.as_string()
1873 }
1874
1875 #[inline]
1876 pub fn as_gos_array(&self) -> &(GosArrayObj, RCount) {
1877 debug_assert!(self.typ == ValueType::Array);
1878 self.data.as_array()
1879 }
1880
1881 #[inline]
1882 pub fn as_array<T>(&self) -> &(ArrayObj<T>, RCount) {
1883 self.data.as_array::<T>()
1884 }
1885
1886 #[inline]
1887 pub fn as_struct(&self) -> &(StructObj, RCount) {
1888 debug_assert!(self.typ == ValueType::Struct);
1889 self.data.as_struct()
1890 }
1891
1892 #[inline]
1893 pub fn as_pointer(&self) -> Option<&PointerObj> {
1894 debug_assert!(self.typ == ValueType::Pointer);
1895 self.data.as_pointer()
1896 }
1897
1898 #[inline]
1899 pub fn as_unsafe_ptr(&self) -> Option<&UnsafePtrObj> {
1900 debug_assert!(self.typ == ValueType::UnsafePtr);
1901 self.data.as_unsafe_ptr()
1902 }
1903
1904 #[inline]
1905 pub fn as_closure(&self) -> Option<&(ClosureObj, RCount)> {
1906 debug_assert!(self.typ == ValueType::Closure);
1907 self.data.as_closure()
1908 }
1909
1910 #[inline]
1911 pub fn as_slice<T>(&self) -> Option<&(SliceObj<T>, RCount)> {
1912 debug_assert!(self.typ == ValueType::Slice || self.typ == ValueType::String);
1913 self.data.as_slice::<T>()
1914 }
1915
1916 #[inline]
1917 pub fn as_gos_slice(&self) -> Option<&(SliceObj<GosElem>, RCount)> {
1918 debug_assert!(self.typ == ValueType::Slice);
1919 self.data.as_slice::<GosElem>()
1920 }
1921
1922 #[inline]
1923 pub fn as_map(&self) -> Option<&(MapObj, RCount)> {
1924 debug_assert!(self.typ == ValueType::Map);
1925 self.data.as_map()
1926 }
1927
1928 #[inline]
1929 pub fn as_interface(&self) -> Option<&InterfaceObj> {
1930 debug_assert!(self.typ == ValueType::Interface);
1931 self.data.as_interface()
1932 }
1933
1934 #[cfg(feature = "async")]
1935 #[inline]
1936 pub fn as_channel(&self) -> Option<&ChannelObj> {
1937 debug_assert!(self.typ == ValueType::Channel);
1938 self.data.as_channel()
1939 }
1940
1941 #[inline]
1942 pub fn as_non_nil_pointer(&self) -> RuntimeResult<&PointerObj> {
1943 self.as_pointer().ok_or(nil_err_str!())
1944 }
1945
1946 #[inline]
1947 pub fn as_non_nil_unsafe_ptr(&self) -> RuntimeResult<&UnsafePtrObj> {
1948 self.as_unsafe_ptr().ok_or(nil_err_str!())
1949 }
1950
1951 #[inline]
1952 pub fn as_non_nil_closure(&self) -> RuntimeResult<&(ClosureObj, RCount)> {
1953 self.as_closure().ok_or(nil_err_str!())
1954 }
1955
1956 #[inline]
1957 pub fn as_non_nil_slice<T>(&self) -> RuntimeResult<&(SliceObj<T>, RCount)> {
1958 self.as_slice::<T>().ok_or(nil_err_str!())
1959 }
1960
1961 #[inline]
1962 pub fn as_non_nil_map(&self) -> RuntimeResult<&(MapObj, RCount)> {
1963 self.as_map().ok_or(nil_err_str!())
1964 }
1965
1966 #[inline]
1967 pub fn as_non_nil_interface(&self) -> RuntimeResult<&InterfaceObj> {
1968 self.as_interface().ok_or(nil_err_str!())
1969 }
1970
1971 #[cfg(feature = "async")]
1972 #[inline]
1973 pub fn as_non_nil_channel(&self) -> RuntimeResult<&ChannelObj> {
1974 self.as_channel().ok_or(nil_err_str!())
1975 }
1976
1977 #[inline]
1978 pub(crate) fn slice_array_equivalent(&self, index: usize) -> RuntimeResult<(&GosValue, usize)> {
1979 Ok(self
1980 .as_non_nil_slice::<AnyElem>()?
1981 .0
1982 .get_array_equivalent(index))
1983 }
1984
1985 pub fn slice_swap(&self, i: usize, j: usize) -> RuntimeResult<()> {
1986 self.caller_slow().slice_swap(self, i, j)
1987 }
1988
1989 #[inline]
1990 pub(crate) fn int32_as(i: i32, t: ValueType) -> GosValue {
1991 GosValue::new(t, ValueData::int32_as(i, t))
1992 }
1993
1994 #[inline]
1995 pub fn is_nil(&self) -> bool {
1996 match self.typ {
1997 ValueType::Pointer => self.as_pointer().is_none(),
1998 ValueType::UnsafePtr => self.as_unsafe_ptr().is_none(),
1999 ValueType::Closure => self.as_closure().is_none(),
2000 ValueType::Slice => self.as_gos_slice().is_none(),
2001 ValueType::Map => self.as_map().is_none(),
2002 ValueType::Interface => self.as_interface().is_none(),
2003 #[cfg(feature = "async")]
2004 ValueType::Channel => self.as_channel().is_none(),
2005 ValueType::Void => true,
2006 _ => false,
2007 }
2008 }
2009
2010 #[inline]
2011 pub(crate) fn copy_semantic(&self, gcc: &GcContainer) -> GosValue {
2012 if self.copyable() {
2013 GosValue::new(self.typ, self.data.copy())
2014 } else {
2015 GosValue::with_elem_type(
2016 self.typ,
2017 self.t_elem,
2018 self.data.copy_semantic(self.typ, self.t_elem, gcc),
2019 )
2020 }
2021 }
2022
2023 #[inline]
2024 pub fn cast_copyable(&self, from: ValueType, to: ValueType) -> GosValue {
2025 assert!(from.copyable());
2026 assert!(to.copyable());
2027 GosValue::new(to, self.data.cast_copyable(from, to))
2028 }
2029
2030 #[inline]
2031 pub fn as_index(&self) -> usize {
2032 debug_assert!(self.copyable());
2033 self.data.as_index(self.typ)
2034 }
2035
2036 #[inline]
2037 pub fn as_addr(&self) -> *const usize {
2038 self.data.as_addr()
2039 }
2040
2041 #[inline]
2042 pub fn iface_underlying(&self) -> RuntimeResult<Option<GosValue>> {
2043 let iface = self.as_non_nil_interface()?;
2044 Ok(iface.underlying_value().map(|x| x.clone()))
2045 }
2046
2047 #[inline]
2048 pub fn slice_string(
2049 s: &GosValue,
2050 begin: isize,
2051 end: isize,
2052 max: isize,
2053 ) -> RuntimeResult<GosValue> {
2054 Ok(GosValue::new_string(s.as_string().slice(begin, end, max)?))
2055 }
2056
2057 #[inline]
2058 pub fn identical(&self, other: &GosValue) -> bool {
2059 self.typ() == other.typ() && self == other
2060 }
2061
2062 #[inline]
2063 pub fn len(&self) -> usize {
2064 match self.typ {
2065 ValueType::Array => self.as_array::<AnyElem>().0.len(),
2066 ValueType::Slice => match self.as_slice::<AnyElem>() {
2067 Some(s) => s.0.len(),
2068 None => 0,
2069 },
2070 ValueType::Map => self.as_map().map_or(0, |x| x.0.len()),
2071 ValueType::String => self.as_string().len(),
2072 #[cfg(feature = "async")]
2073 ValueType::Channel => self.as_channel().map_or(0, |x| x.len()),
2074 _ => unreachable!(),
2075 }
2076 }
2077
2078 #[inline]
2079 pub fn cap(&self) -> usize {
2080 match self.typ {
2081 ValueType::Slice => match self.as_slice::<AnyElem>() {
2082 Some(s) => s.0.cap(),
2083 None => 0,
2084 },
2085 #[cfg(feature = "async")]
2086 ValueType::Channel => self.as_channel().map_or(0, |x| x.cap()),
2087 _ => unreachable!(),
2088 }
2089 }
2090
2091 pub fn ref_sub_one(&self) {
2093 match &self.typ {
2094 ValueType::Pointer => {
2095 self.as_pointer().map(|p| p.ref_sub_one());
2096 }
2097 ValueType::UnsafePtr => {
2098 self.as_unsafe_ptr().map(|p| p.ptr().ref_sub_one());
2099 }
2100 ValueType::Interface => {
2101 self.as_interface().map(|x| x.ref_sub_one());
2102 }
2103 ValueType::Array => self.as_gos_array().1.set(self.as_gos_array().1.get() - 1),
2104 ValueType::Struct => self.as_struct().1.set(self.as_struct().1.get() - 1),
2105 ValueType::Closure => {
2106 self.as_closure().map(|x| x.1.set(x.1.get() - 1));
2107 }
2108 ValueType::Slice => {
2109 self.as_gos_slice().map(|x| x.0.array().ref_sub_one());
2110 }
2111 ValueType::Map => {
2112 self.as_map().map(|x| x.1.set(x.1.get() - 1));
2113 }
2114 _ => {}
2115 };
2116 }
2117
2118 pub(crate) fn mark_dirty(&self, queue: &mut RCQueue) {
2120 match &self.typ {
2121 ValueType::Array => rcount_mark_and_queue(&self.as_gos_array().1, queue),
2122 ValueType::Pointer => {
2123 self.as_pointer().map(|x| x.mark_dirty(queue));
2124 }
2125 ValueType::UnsafePtr => {
2126 self.as_unsafe_ptr().map(|x| x.ptr().mark_dirty(queue));
2127 }
2128 ValueType::Closure => {
2129 self.as_closure()
2130 .map(|x| rcount_mark_and_queue(&x.1, queue));
2131 }
2132 ValueType::Slice => {
2133 self.as_gos_slice().map(|x| x.0.array().mark_dirty(queue));
2134 }
2135 ValueType::Map => {
2136 self.as_map().map(|x| rcount_mark_and_queue(&x.1, queue));
2137 }
2138 ValueType::Interface => {
2139 self.as_interface().map(|x| x.mark_dirty(queue));
2140 }
2141 ValueType::Struct => rcount_mark_and_queue(&self.as_struct().1, queue),
2142 _ => {}
2143 };
2144 }
2145
2146 #[inline]
2147 pub(crate) fn rc(&self) -> IRC {
2148 self.data.rc(self.typ).unwrap().get()
2149 }
2150
2151 #[inline]
2152 pub(crate) fn set_rc(&self, rc: IRC) {
2153 self.data.rc(self.typ).unwrap().set(rc)
2154 }
2155
2156 #[inline]
2157 pub(crate) fn drop_as_copyable(self) {
2158 debug_assert!(self.copyable());
2159 drop(self);
2160 }
2161
2162 #[inline]
2163 pub(crate) fn cast(&self, new_type: ValueType) -> GosValue {
2164 GosValue::new(new_type, self.data.clone(self.typ))
2165 }
2166
2167 #[inline]
2168 pub(crate) fn new(typ: ValueType, data: ValueData) -> GosValue {
2169 debug_assert!(typ != ValueType::Slice && typ != ValueType::Array);
2170 GosValue {
2171 typ,
2172 t_elem: ValueType::Void,
2173 data,
2174 }
2175 }
2176
2177 #[inline]
2178 fn with_elem_type(typ: ValueType, t_elem: ValueType, data: ValueData) -> GosValue {
2179 GosValue { typ, t_elem, data }
2180 }
2181}
2182
2183impl Drop for GosValue {
2184 #[inline]
2185 fn drop(&mut self) {
2186 if !self.copyable() {
2187 self.data.drop_as_ptr(self.typ, self.t_elem);
2188 }
2189 }
2190}
2191
2192impl Clone for GosValue {
2193 #[inline]
2194 fn clone(&self) -> Self {
2195 if self.copyable() {
2196 GosValue::new(self.typ, self.data.copy())
2197 } else {
2198 GosValue::with_elem_type(self.typ, self.t_elem, self.data.clone(self.typ))
2199 }
2200 }
2201}
2202
2203impl Eq for GosValue {}
2204
2205impl PartialEq for GosValue {
2206 #[inline]
2207 fn eq(&self, b: &GosValue) -> bool {
2208 match (self.typ, b.typ) {
2209 (ValueType::Bool, ValueType::Bool) => self.as_bool().eq(b.as_bool()),
2210 (ValueType::Int, ValueType::Int) => self.as_int().eq(b.as_int()),
2211 (ValueType::Int8, ValueType::Int8) => self.as_int8().eq(b.as_int8()),
2212 (ValueType::Int16, ValueType::Int16) => self.as_int16().eq(b.as_int16()),
2213 (ValueType::Int32, ValueType::Int32) => self.as_int32().eq(b.as_int32()),
2214 (ValueType::Int64, ValueType::Int64) => self.as_int64().eq(b.as_int64()),
2215 (ValueType::Uint, ValueType::Uint) => self.as_uint().eq(b.as_uint()),
2216 (ValueType::UintPtr, ValueType::UintPtr) => self.as_uint_ptr().eq(b.as_uint_ptr()),
2217 (ValueType::Uint8, ValueType::Uint8) => self.as_uint8().eq(b.as_uint8()),
2218 (ValueType::Uint16, ValueType::Uint16) => self.as_uint16().eq(b.as_uint16()),
2219 (ValueType::Uint32, ValueType::Uint32) => self.as_uint32().eq(b.as_uint32()),
2220 (ValueType::Uint64, ValueType::Uint64) => self.as_uint64().eq(b.as_uint64()),
2221 (ValueType::Float32, ValueType::Float32) => self.as_float32().eq(b.as_float32()),
2222 (ValueType::Float64, ValueType::Float64) => self.as_float64().eq(b.as_float64()),
2223 (ValueType::Complex64, ValueType::Complex64) => {
2224 let x = self.as_complex64();
2225 let y = b.as_complex64();
2226 x.r == y.r && x.i == y.i
2227 }
2228 (ValueType::Function, ValueType::Function) => self.as_function().eq(b.as_function()),
2229 (ValueType::Package, ValueType::Package) => self.as_package().eq(b.as_package()),
2230 (ValueType::Metadata, ValueType::Metadata) => self.as_metadata().eq(b.as_metadata()),
2231 (ValueType::Complex128, ValueType::Complex128) => {
2232 let x = self.as_complex128();
2233 let y = b.as_complex128();
2234 x.r == y.r && x.i == y.i
2235 }
2236 (ValueType::String, ValueType::String) => {
2237 *self.as_string().as_str() == *b.as_string().as_str()
2238 }
2239 (ValueType::Array, ValueType::Array) => {
2240 self.caller_slow().array_eq(self.data(), b.data())
2241 }
2242 (ValueType::Struct, ValueType::Struct) => {
2243 StructObj::eq(&self.as_struct().0, &b.as_struct().0)
2244 }
2245 (ValueType::Pointer, ValueType::Pointer) => self.as_pointer() == b.as_pointer(),
2246 (ValueType::UnsafePtr, ValueType::UnsafePtr) => {
2247 self.as_unsafe_ptr() == b.as_unsafe_ptr()
2248 }
2249 (ValueType::Closure, ValueType::Closure) => {
2250 ref_ptr_eq(self.as_closure(), b.as_closure())
2251 }
2252 #[cfg(feature = "async")]
2253 (ValueType::Channel, ValueType::Channel) => {
2254 ref_ptr_eq(self.as_channel(), b.as_channel())
2255 }
2256 (ValueType::Interface, ValueType::Interface) => {
2257 match (self.as_interface(), b.as_interface()) {
2258 (Some(a), Some(b)) => a.eq(b),
2259 (None, None) => true,
2260 _ => false,
2261 }
2262 }
2263 (_, ValueType::Void) => self.is_nil(),
2264 (ValueType::Void, _) => b.is_nil(),
2265 (ValueType::Interface, _) => self
2266 .as_interface()
2267 .map_or(b.is_nil(), |x| x.equals_value(b)),
2268 (_, ValueType::Interface) => b
2269 .as_interface()
2270 .map_or(self.is_nil(), |x| x.equals_value(self)),
2271 _ => false,
2272 }
2273 }
2274}
2275
2276impl Hash for GosValue {
2277 fn hash<H: Hasher>(&self, state: &mut H) {
2278 match &self.typ {
2279 ValueType::Bool => self.as_bool().hash(state),
2280 ValueType::Int => self.as_int().hash(state),
2281 ValueType::Int8 => self.as_int8().hash(state),
2282 ValueType::Int16 => self.as_int16().hash(state),
2283 ValueType::Int32 => self.as_int32().hash(state),
2284 ValueType::Int64 => self.as_int64().hash(state),
2285 ValueType::Uint => self.as_uint().hash(state),
2286 ValueType::UintPtr => self.as_uint_ptr().hash(state),
2287 ValueType::Uint8 => self.as_uint8().hash(state),
2288 ValueType::Uint16 => self.as_uint16().hash(state),
2289 ValueType::Uint32 => self.as_uint32().hash(state),
2290 ValueType::Uint64 => self.as_uint64().hash(state),
2291 ValueType::Float32 => self.as_float32().hash(state),
2292 ValueType::Float64 => self.as_float64().hash(state),
2293 ValueType::Complex64 => self.as_uint64().hash(state),
2294 ValueType::Function => self.as_function().hash(state),
2295 ValueType::Package => self.as_package().hash(state),
2296 ValueType::Metadata => self.as_metadata().hash(state),
2297 ValueType::String => self.as_string().as_str().hash(state),
2298 ValueType::Array => self.caller_slow().array_hash(self, state),
2299 ValueType::Complex128 => {
2300 let c = self.as_complex128();
2301 c.r.hash(state);
2302 c.i.hash(state);
2303 }
2304 ValueType::Struct => {
2305 self.as_struct().0.hash(state);
2306 }
2307 ValueType::Pointer => match self.as_pointer() {
2308 Some(p) => PointerObj::hash(&p, state),
2309 None => 0.hash(state),
2310 },
2311 ValueType::Interface => match self.as_interface() {
2312 Some(iface) => iface.hash(state),
2313 None => 0.hash(state),
2314 },
2315 _ => {
2316 dbg!(self.typ);
2317 unreachable!();
2318 }
2319 }
2320 }
2321}
2322
2323impl PartialOrd for GosValue {
2324 #[inline]
2325 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2326 Some(self.cmp(other))
2327 }
2328}
2329
2330impl Ord for GosValue {
2331 fn cmp(&self, b: &Self) -> Ordering {
2332 match (self.typ, b.typ) {
2333 (ValueType::Bool, ValueType::Bool) => self.as_bool().cmp(b.as_bool()),
2334 (ValueType::Int, ValueType::Int) => self.as_int().cmp(b.as_int()),
2335 (ValueType::Int8, ValueType::Int8) => self.as_int8().cmp(b.as_int8()),
2336 (ValueType::Int16, ValueType::Int16) => self.as_int16().cmp(b.as_int16()),
2337 (ValueType::Int32, ValueType::Int32) => self.as_int32().cmp(b.as_int32()),
2338 (ValueType::Int64, ValueType::Int64) => self.as_int64().cmp(b.as_int64()),
2339 (ValueType::Uint, ValueType::Uint) => self.as_uint().cmp(b.as_uint()),
2340 (ValueType::UintPtr, ValueType::UintPtr) => self.as_uint_ptr().cmp(b.as_uint_ptr()),
2341 (ValueType::Uint8, ValueType::Uint8) => self.as_uint8().cmp(b.as_uint8()),
2342 (ValueType::Uint16, ValueType::Uint16) => self.as_uint16().cmp(b.as_uint16()),
2343 (ValueType::Uint32, ValueType::Uint32) => self.as_uint32().cmp(b.as_uint32()),
2344 (ValueType::Uint64, ValueType::Uint64) => self.as_uint64().cmp(b.as_uint64()),
2345 (ValueType::Float32, ValueType::Float32) => self.as_float32().cmp(b.as_float32()),
2346 (ValueType::Float64, ValueType::Float64) => self.as_float64().cmp(b.as_float64()),
2347 (ValueType::Complex128, ValueType::Complex128) => {
2348 let left = self.as_complex128();
2349 let right = self.as_complex128();
2350 left.r.cmp(&right.r).then(left.i.cmp(&right.i))
2351 }
2352 (ValueType::Function, ValueType::Function) => self.as_uint64().cmp(b.as_uint64()),
2353 (ValueType::Package, ValueType::Package) => self.as_uint64().cmp(b.as_uint64()),
2354 (ValueType::Metadata, ValueType::Metadata) => self.as_metadata().cmp(b.as_metadata()),
2355 (ValueType::String, ValueType::String) => {
2356 self.as_string().as_str().cmp(&b.as_string().as_str())
2357 }
2358 (ValueType::Array, ValueType::Array) => {
2359 self.caller_slow().array_cmp(self.data(), b.data())
2360 }
2361 (ValueType::Complex64, ValueType::Complex64) => {
2362 let left = self.as_complex64();
2363 let right = self.as_complex64();
2364 left.r.cmp(&right.r).then(left.i.cmp(&right.i))
2365 }
2366 (ValueType::Struct, ValueType::Struct) => self.as_struct().0.cmp(&b.as_struct().0),
2367 (ValueType::Pointer, ValueType::Pointer) => match (self.as_pointer(), b.as_pointer()) {
2368 (Some(a), Some(b)) => a.cmp(b),
2369 (None, None) => Ordering::Equal,
2370 (Some(_), None) => Ordering::Greater,
2371 (None, Some(_)) => Ordering::Less,
2372 },
2373 (ValueType::Interface, ValueType::Interface) => {
2374 match (self.as_interface(), b.as_interface()) {
2375 (Some(a), Some(b)) => a.cmp(b),
2376 (None, None) => Ordering::Equal,
2377 (Some(_), None) => Ordering::Greater,
2378 (None, Some(_)) => Ordering::Less,
2379 }
2380 }
2381 _ => {
2382 dbg!(self.typ(), b.typ());
2383 unreachable!()
2384 }
2385 }
2386 }
2387}
2388
2389#[cfg(feature = "serde_borsh")]
2390mod type_serde {
2391 use super::*;
2392
2393 pub trait TypeWrite {
2395 fn serialize<W: BorshWrite>(val: &GosValue, writer: &mut W) -> BorshResult<()>;
2396 }
2397
2398 pub trait TypeRead {
2400 fn deserialize_reader<R: std::io::Read>(&self, reader: &mut R) -> BorshResult<ValueType>;
2401
2402 fn deserialize_reader_array_len<R: std::io::Read>(
2403 &self,
2404 reader: &mut R,
2405 ) -> BorshResult<usize>;
2406
2407 fn t_elem_read(&self) -> BorshResult<Self>
2408 where
2409 Self: Sized;
2410 }
2411
2412 pub(super) struct TypeEmbeded;
2414
2415 pub(super) struct TypeOmitted;
2417
2418 pub(super) struct TypeFromMetadata<'a>(pub &'a Meta, pub &'a MetadataObjs);
2420
2421 impl TypeWrite for TypeEmbeded {
2422 #[inline]
2423 fn serialize<W: BorshWrite>(val: &GosValue, writer: &mut W) -> BorshResult<()> {
2424 val.typ().serialize(writer)?;
2425 match val.typ() {
2426 ValueType::Array => {
2427 val.t_elem().serialize(writer)?;
2428 (val.len() as u32).serialize(writer)?;
2429 }
2430 ValueType::Slice => {
2431 val.t_elem().serialize(writer)?;
2432 }
2433 _ => {}
2434 }
2435 Ok(())
2436 }
2437 }
2438
2439 impl TypeWrite for TypeOmitted {
2440 #[inline]
2441 fn serialize<W: BorshWrite>(_: &GosValue, _: &mut W) -> BorshResult<()> {
2442 Ok(())
2443 }
2444 }
2445
2446 impl TypeRead for TypeEmbeded {
2447 #[inline]
2448 fn deserialize_reader<R: std::io::Read>(&self, reader: &mut R) -> BorshResult<ValueType> {
2449 ValueType::deserialize_reader(reader)
2450 }
2451
2452 fn deserialize_reader_array_len<R: std::io::Read>(
2453 &self,
2454 reader: &mut R,
2455 ) -> BorshResult<usize> {
2456 Ok(u32::deserialize_reader(reader)? as usize)
2457 }
2458
2459 #[inline]
2460 fn t_elem_read(&self) -> BorshResult<Self>
2461 where
2462 Self: Sized,
2463 {
2464 Ok(TypeEmbeded {})
2465 }
2466 }
2467
2468 impl<'a> TypeRead for TypeFromMetadata<'a> {
2469 #[inline]
2470 fn deserialize_reader<R: std::io::Read>(&self, _: &mut R) -> BorshResult<ValueType> {
2471 Ok(self.0.value_type(self.1))
2472 }
2473
2474 #[inline]
2475 fn deserialize_reader_array_len<R: std::io::Read>(&self, r: &mut R) -> BorshResult<usize> {
2476 match &self.1[self.0.key] {
2477 MetadataType::Array(_, len) => Ok(*len),
2478 MetadataType::Named(_, inner) => {
2479 Self(inner, self.1).deserialize_reader_array_len(r)
2480 }
2481 _ => unreachable!(),
2482 }
2483 }
2484
2485 #[inline]
2486 fn t_elem_read(&self) -> BorshResult<Self>
2487 where
2488 Self: Sized,
2489 {
2490 match &self.1[self.0.key] {
2491 MetadataType::Array(et, _) | MetadataType::Slice(et) => Ok(Self(et, self.1)),
2492 MetadataType::Named(_, inner) => Self(inner, self.1).t_elem_read(),
2493 _ => unreachable!(),
2494 }
2495 }
2496 }
2497}
2498
2499#[cfg(feature = "serde_borsh")]
2500impl GosValue {
2501 pub fn serialize_wo_type<W: BorshWrite>(&self, writer: &mut W) -> BorshResult<()> {
2502 self.serialize::<W, type_serde::TypeOmitted>(writer)
2503 }
2504
2505 pub fn deserialize_wo_type(
2506 meta: &Meta,
2507 metas: &MetadataObjs,
2508 buf: &mut &[u8],
2509 ) -> BorshResult<GosValue> {
2510 GosValue::deserialize(&type_serde::TypeFromMetadata(meta, metas), buf)
2511 }
2512
2513 fn serialize<W: BorshWrite, T: type_serde::TypeWrite>(
2514 &self,
2515 writer: &mut W,
2516 ) -> BorshResult<()> {
2517 T::serialize(&self, writer)?;
2518 match &self.typ {
2519 ValueType::Bool => self.as_bool().serialize(writer),
2520 ValueType::Int => self.as_int64().serialize(writer),
2521 ValueType::Int8 => self.as_int8().serialize(writer),
2522 ValueType::Int16 => self.as_int16().serialize(writer),
2523 ValueType::Int32 => self.as_int32().serialize(writer),
2524 ValueType::Int64 => self.as_int64().serialize(writer),
2525 ValueType::Uint => self.as_uint64().serialize(writer),
2526 ValueType::UintPtr => self.as_uint64().serialize(writer),
2527 ValueType::Uint8 => self.as_uint8().serialize(writer),
2528 ValueType::Uint16 => self.as_uint16().serialize(writer),
2529 ValueType::Uint32 => self.as_uint32().serialize(writer),
2530 ValueType::Uint64 => self.as_uint64().serialize(writer),
2531 ValueType::Float32 => self.as_float32().serialize(writer),
2532 ValueType::Float64 => self.as_float64().serialize(writer),
2533 ValueType::Complex64 => self.as_uint64().serialize(writer),
2534 ValueType::Function => self.as_function().serialize(writer),
2535 ValueType::Package => self.as_package().serialize(writer),
2536 ValueType::Metadata => self.as_metadata().serialize(writer),
2537 ValueType::String => self.as_string().as_str().serialize(writer),
2538 ValueType::Array => {
2539 let vec = self.caller_slow().array_get_vec(self);
2540 GosValue::too_large_check(vec.len())?;
2541 for v in vec.iter() {
2542 v.serialize::<W, T>(writer)?;
2543 }
2544 Ok(())
2545 }
2546 ValueType::Complex128 => {
2547 let c = self.as_complex128();
2548 c.r.serialize(writer)?;
2549 c.i.serialize(writer)
2550 }
2551 ValueType::Struct => self.as_struct().0.borrow_fields().serialize(writer),
2552 ValueType::Slice => {
2553 let op_vec = self.caller_slow().slice_get_vec(self);
2554 match op_vec {
2555 Some(vec) => {
2556 GosValue::too_large_check(vec.len())?;
2557 (vec.len() as u32).serialize(writer)?;
2558 for v in vec.iter() {
2559 v.serialize::<W, T>(writer)?;
2560 }
2561 Ok(())
2562 }
2563 None => u32::MAX.serialize(writer),
2564 }
2565 }
2566 ValueType::Map => match self.as_map() {
2567 Some(m) => {
2568 let map = m.0.borrow_data();
2569 GosValue::too_large_check(map.len())?;
2570 (map.len() as u32).serialize(writer)?;
2571 for (k, v) in map.iter() {
2572 k.serialize::<W, T>(writer)?;
2573 v.serialize::<W, T>(writer)?;
2574 }
2575 Ok(())
2576 }
2577 None => u32::MAX.serialize(writer),
2578 },
2579 ValueType::Closure => self
2580 .as_closure()
2581 .map(|x| match &x.0 {
2582 ClosureObj::Gos(cls) => cls,
2583 ClosureObj::Ffi(_) => unreachable!(),
2584 })
2585 .serialize(writer),
2586 _ => {
2587 if !self.is_nil() {
2588 Err(Error::new(
2589 ErrorKind::InvalidData,
2590 "GosValue serialization: only nil supported for this type",
2591 ))
2592 } else {
2593 Ok(())
2594 }
2595 }
2596 }
2597 }
2598
2599 fn deserialize<T: type_serde::TypeRead, R: std::io::Read>(
2600 tr: &T,
2601 reader: &mut R,
2602 ) -> BorshResult<GosValue> {
2603 let dummy_gcc = &GcContainer::new();
2604 let typ = tr.deserialize_reader(reader)?;
2605 let val: GosValue = match typ {
2606 ValueType::Bool => bool::deserialize_reader(reader)?.into(),
2607 ValueType::Int => (i64::deserialize_reader(reader)? as isize).into(),
2608 ValueType::Int8 => i8::deserialize_reader(reader)?.into(),
2609 ValueType::Int16 => i16::deserialize_reader(reader)?.into(),
2610 ValueType::Int32 => i32::deserialize_reader(reader)?.into(),
2611 ValueType::Int64 => i64::deserialize_reader(reader)?.into(),
2612 ValueType::Uint => (u64::deserialize_reader(reader)? as usize).into(),
2613 ValueType::UintPtr => GosValue::new_uint_ptr(u64::deserialize_reader(reader)? as usize),
2614 ValueType::Uint8 => u8::deserialize_reader(reader)?.into(),
2615 ValueType::Uint16 => u16::deserialize_reader(reader)?.into(),
2616 ValueType::Uint32 => u32::deserialize_reader(reader)?.into(),
2617 ValueType::Uint64 => u64::deserialize_reader(reader)?.into(),
2618 ValueType::Float32 => f32::deserialize_reader(reader)?.into(),
2619 ValueType::Float64 => f64::deserialize_reader(reader)?.into(),
2620 ValueType::Complex64 => {
2621 let r = f32::deserialize_reader(reader)?.into();
2622 let i = f32::deserialize_reader(reader)?.into();
2623 GosValue::new_complex64(r, i)
2624 }
2625 ValueType::Function => GosValue::new_function(FunctionKey::deserialize_reader(reader)?),
2626 ValueType::Package => GosValue::new_package(PackageKey::deserialize_reader(reader)?),
2627 ValueType::Metadata => GosValue::new_metadata(Meta::deserialize_reader(reader)?),
2628 ValueType::String => GosValue::with_str(&String::deserialize_reader(reader)?),
2629 ValueType::Array => {
2630 let elem_read = tr.t_elem_read()?;
2631 let t_elem = elem_read.deserialize_reader(reader)?;
2632 let caller = ArrCaller::get_slow(t_elem);
2633 let len = tr.deserialize_reader_array_len(reader)?;
2634 GosValue::deserialize_array(&elem_read, len, &caller, dummy_gcc, reader)?
2635 }
2636 ValueType::Complex128 => {
2637 let r = f64::deserialize_reader(reader)?.into();
2638 let i = f64::deserialize_reader(reader)?.into();
2639 GosValue::new_complex128(r, i)
2640 }
2641 ValueType::Struct => {
2642 let fields = Vec::<GosValue>::deserialize_reader(reader)?;
2643 GosValue::new_struct(StructObj::new(fields), dummy_gcc)
2644 }
2645 ValueType::Slice => {
2646 let elem_read = tr.t_elem_read()?;
2647 let t_elem = elem_read.deserialize_reader(reader)?;
2648 let len = u32::deserialize_reader(reader)?;
2649 match len {
2650 u32::MAX => GosValue::new_nil_slice(t_elem),
2651 _ => {
2652 let caller = ArrCaller::get_slow(t_elem);
2653 let array = GosValue::deserialize_array(
2654 &elem_read,
2655 len as usize,
2656 &caller,
2657 dummy_gcc,
2658 reader,
2659 )?;
2660 GosValue::slice_array(array, 0, -1, &caller).unwrap()
2661 }
2662 }
2663 }
2664 ValueType::Map => {
2665 let len = u32::deserialize_reader(reader)?;
2666 match len {
2667 u32::MAX => GosValue::new_nil(ValueType::Map),
2668 _ => {
2669 let map = GosValue::new_map(dummy_gcc);
2670 let mo = &map.as_non_nil_map().unwrap().0;
2671 for _ in 0..len {
2672 let key = GosValue::deserialize(tr, reader)?;
2673 let val = GosValue::deserialize(tr, reader)?;
2674 mo.insert(key, val);
2675 }
2676 map
2677 }
2678 }
2679 }
2680 ValueType::Closure => match Option::<GosClosureObj>::deserialize_reader(reader)? {
2681 Some(cls) => GosValue::new_closure(ClosureObj::Gos(cls), dummy_gcc),
2682 None => GosValue::new_nil(typ),
2683 },
2684 _ => GosValue::new_nil(typ),
2685 };
2686 Ok(val)
2687 }
2688
2689 #[inline]
2690 fn deserialize_array<T: type_serde::TypeRead, R: std::io::Read>(
2691 tr: &T,
2692 len: usize,
2693 caller: &Box<dyn Dispatcher>,
2694 gcc: &GcContainer,
2695 reader: &mut R,
2696 ) -> BorshResult<GosValue> {
2697 let mut data = Vec::with_capacity(len);
2698 for _ in 0..len {
2699 data.push(GosValue::deserialize(tr, reader)?)
2700 }
2701 Ok(caller.array_with_data(data, gcc))
2702 }
2703
2704 fn too_large_check(len: usize) -> BorshResult<()> {
2705 if len >= u32::MAX as usize {
2706 Err(Error::new(
2707 ErrorKind::InvalidData,
2708 "Data size too large, require: len(slice) < u32::MAX",
2709 ))
2710 } else {
2711 Ok(())
2712 }
2713 }
2714}
2715
2716#[cfg(feature = "serde_borsh")]
2717impl BorshSerialize for GosValue {
2718 fn serialize<W: BorshWrite>(&self, writer: &mut W) -> BorshResult<()> {
2719 GosValue::serialize::<W, type_serde::TypeEmbeded>(&self, writer)
2720 }
2721}
2722
2723#[cfg(feature = "serde_borsh")]
2724impl BorshDeserialize for GosValue {
2725 fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> BorshResult<Self> {
2726 GosValue::deserialize(&type_serde::TypeEmbeded, reader)
2727 }
2728}
2729
2730impl Display for GosValue {
2731 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2732 match self.typ {
2733 ValueType::Bool => write!(f, "{}", self.as_bool()),
2734 ValueType::Int => write!(f, "{}", self.as_int()),
2735 ValueType::Int8 => write!(f, "{}", self.as_int8()),
2736 ValueType::Int16 => write!(f, "{}", self.as_int16()),
2737 ValueType::Int32 => write!(f, "{}", self.as_int32()),
2738 ValueType::Int64 => write!(f, "{}", self.as_int64()),
2739 ValueType::Uint => write!(f, "{}", self.as_uint()),
2740 ValueType::UintPtr => write!(f, "{}", self.as_uint_ptr()),
2741 ValueType::Uint8 => write!(f, "{}", self.as_uint8()),
2742 ValueType::Uint16 => write!(f, "{}", self.as_uint16()),
2743 ValueType::Uint32 => write!(f, "{}", self.as_uint32()),
2744 ValueType::Uint64 => write!(f, "{}", self.as_uint64()),
2745 ValueType::Float32 => write!(f, "{}", self.as_float32()),
2746 ValueType::Float64 => write!(f, "{}", self.as_float64()),
2747 ValueType::Complex64 => {
2748 let c = self.as_complex64();
2749 write!(f, "({}, {})", c.r, c.i)
2750 }
2751 ValueType::Function => f.write_str("<function>"),
2752 ValueType::Package => f.write_str("<package>"),
2753 ValueType::Metadata => f.write_str("<metadata>"),
2754 ValueType::Complex128 => {
2755 let c = self.as_complex128();
2756 write!(f, "({}, {})", c.r, c.i)
2757 }
2758 ValueType::String => f.write_str(&self.as_string().as_str()),
2759 ValueType::Array => display_vec(&self.caller_slow().array_get_vec(self), f),
2760 ValueType::Struct => write!(f, "{}", self.as_struct().0),
2761 ValueType::Pointer => match self.as_pointer() {
2762 Some(p) => std::fmt::Display::fmt(p, f),
2763 None => f.write_str("<nil(pointer)>"),
2764 },
2765 ValueType::UnsafePtr => match self.as_unsafe_ptr() {
2766 Some(p) => std::fmt::Display::fmt(p, f),
2767 None => f.write_str("<nil(unsafe pointer)>"),
2768 },
2769 ValueType::Closure => match self.as_closure() {
2770 Some(_) => f.write_str("<closure>"),
2771 None => f.write_str("<nil(closure)>"),
2772 },
2773 ValueType::Slice => match self.caller_slow().slice_get_vec(self) {
2774 Some(v) => display_vec(&v, f),
2775 None => f.write_str("<nil(slice)>"),
2776 },
2777 ValueType::Map => match self.as_map() {
2778 Some(m) => write!(f, "{}", m.0),
2779 None => f.write_str("<nil(map)>"),
2780 },
2781 ValueType::Interface => match self.as_interface() {
2782 Some(i) => write!(f, "{}", i),
2783 None => f.write_str("<nil(interface)>"),
2784 },
2785 #[cfg(feature = "async")]
2786 ValueType::Channel => match self.as_channel() {
2787 Some(_) => f.write_str("<channel>"),
2788 None => f.write_str("<nil(channel)>"),
2789 },
2790 ValueType::Void => f.write_str("<nil(untyped)>"),
2791 _ => unreachable!(),
2792 }
2793 }
2794}
2795
2796impl fmt::Debug for GosValue {
2797 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2798 let t = self.typ();
2799 match t {
2800 ValueType::Bool => write!(f, "Type: {:?}, Data: {:?}", t, self.as_bool()),
2801 ValueType::Int => write!(f, "Type: {:?}, Data: {:?}", t, self.as_int()),
2802 ValueType::Int8 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_int8()),
2803 ValueType::Int16 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_int16()),
2804 ValueType::Int32 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_int32()),
2805 ValueType::Int64 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_int64()),
2806 ValueType::Uint => write!(f, "Type: {:?}, Data: {:?}", t, self.as_uint()),
2807 ValueType::UintPtr => write!(f, "Type: {:?}, Data: {:?}", t, self.as_uint_ptr()),
2808 ValueType::Uint8 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_uint8()),
2809 ValueType::Uint16 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_uint16()),
2810 ValueType::Uint32 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_uint32()),
2811 ValueType::Uint64 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_uint64()),
2812 ValueType::Float32 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_float32()),
2813 ValueType::Float64 => write!(f, "Type: {:?}, Data: {:?}", t, self.as_float64()),
2814 ValueType::Complex64 => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_complex64()),
2815 ValueType::Function => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_function()),
2816 ValueType::Package => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_package()),
2817 ValueType::Metadata => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_metadata()),
2818 ValueType::Complex128 => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_complex128()),
2819 ValueType::String => {
2820 write!(f, "Type: {:?}, Data: {:?}", t, &self.as_string().as_str(),)
2821 }
2822 ValueType::Array => match self.t_elem {
2823 ValueType::Void => write!(f, "Type: {:?}, Data: {:?}", t, "unknown"),
2824 _ => display_vec(&self.caller_slow().array_get_vec(self), f),
2825 },
2826 ValueType::Struct => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_struct()),
2827 ValueType::Pointer => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_pointer()),
2828 ValueType::UnsafePtr => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_unsafe_ptr()),
2829 ValueType::Closure => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_closure()),
2830 ValueType::Slice => match self.t_elem {
2831 ValueType::Void => write!(f, "Type: {:?}, Data: {:?}", t, "unknown"),
2832 _ => match self.caller_slow().slice_get_vec(self) {
2833 Some(v) => debug_vec(&v, f),
2834 None => f.write_str("<nil(slice)>"),
2835 },
2836 },
2837 ValueType::Map => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_map()),
2838 ValueType::Interface => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_interface()),
2839 #[cfg(feature = "async")]
2840 ValueType::Channel => write!(f, "Type: {:?}, Data: {:#?}", t, self.as_channel()),
2841 ValueType::Void => write!(
2842 f,
2843 "Type: {:?}, Data: {:#018x}/{:?}",
2844 t,
2845 self.as_uint(),
2846 self.as_uint()
2847 ),
2848 _ => unreachable!(),
2849 }
2850 }
2851}
2852
2853fn display_vec(vec: &Vec<GosValue>, f: &mut fmt::Formatter) -> fmt::Result {
2854 f.write_char('[')?;
2855 for (i, v) in vec.iter().enumerate() {
2856 if i > 0 {
2857 f.write_char(' ')?;
2858 }
2859 write!(f, "{}", v)?
2860 }
2861 f.write_char(']')
2862}
2863
2864pub fn debug_vec(vec: &Vec<GosValue>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2865 f.write_char('[')?;
2866 for (i, v) in vec.iter().enumerate() {
2867 if i > 0 {
2868 f.write_char(' ')?;
2869 }
2870 write!(f, "{:#?}", v)?
2871 }
2872 f.write_char(']')
2873}
2874
2875impl From<bool> for GosValue {
2876 #[inline]
2877 fn from(b: bool) -> Self {
2878 GosValue::new(ValueType::Bool, ValueData::new_bool(b))
2879 }
2880}
2881
2882impl AsPrimitive<bool> for GosValue {
2883 #[inline]
2884 fn as_(&self) -> bool {
2885 debug_assert!(self.copyable());
2886 *self.data.as_bool()
2887 }
2888}
2889
2890impl From<isize> for GosValue {
2891 #[inline]
2892 fn from(i: isize) -> Self {
2893 GosValue::new(ValueType::Int, ValueData::new_int(i))
2894 }
2895}
2896
2897impl AsPrimitive<isize> for GosValue {
2898 #[inline]
2899 fn as_(&self) -> isize {
2900 *self.as_int()
2901 }
2902}
2903
2904impl From<i8> for GosValue {
2905 #[inline]
2906 fn from(i: i8) -> Self {
2907 GosValue::new(ValueType::Int8, ValueData::new_int8(i))
2908 }
2909}
2910
2911impl AsPrimitive<i8> for GosValue {
2912 #[inline]
2913 fn as_(&self) -> i8 {
2914 *self.as_int8()
2915 }
2916}
2917
2918impl From<i16> for GosValue {
2919 #[inline]
2920 fn from(i: i16) -> Self {
2921 GosValue::new(ValueType::Int16, ValueData::new_int16(i))
2922 }
2923}
2924
2925impl AsPrimitive<i16> for GosValue {
2926 #[inline]
2927 fn as_(&self) -> i16 {
2928 *self.as_int16()
2929 }
2930}
2931
2932impl From<i32> for GosValue {
2933 #[inline]
2934 fn from(i: i32) -> Self {
2935 GosValue::new(ValueType::Int32, ValueData::new_int32(i))
2936 }
2937}
2938
2939impl AsPrimitive<i32> for GosValue {
2940 #[inline]
2941 fn as_(&self) -> i32 {
2942 *self.as_int32()
2943 }
2944}
2945
2946impl From<i64> for GosValue {
2947 #[inline]
2948 fn from(i: i64) -> Self {
2949 GosValue::new(ValueType::Int64, ValueData::new_int64(i))
2950 }
2951}
2952
2953impl AsPrimitive<i64> for GosValue {
2954 #[inline]
2955 fn as_(&self) -> i64 {
2956 *self.as_int64()
2957 }
2958}
2959
2960impl From<usize> for GosValue {
2961 #[inline]
2962 fn from(i: usize) -> Self {
2963 GosValue::new(ValueType::Uint, ValueData::new_uint(i))
2964 }
2965}
2966
2967impl AsPrimitive<usize> for GosValue {
2968 #[inline]
2969 fn as_(&self) -> usize {
2970 *self.as_uint()
2971 }
2972}
2973
2974impl From<u8> for GosValue {
2975 #[inline]
2976 fn from(i: u8) -> Self {
2977 GosValue::new(ValueType::Uint8, ValueData::new_uint8(i))
2978 }
2979}
2980
2981impl AsPrimitive<u8> for GosValue {
2982 #[inline]
2983 fn as_(&self) -> u8 {
2984 *self.as_uint8()
2985 }
2986}
2987
2988impl From<u16> for GosValue {
2989 #[inline]
2990 fn from(i: u16) -> Self {
2991 GosValue::new(ValueType::Uint16, ValueData::new_uint16(i))
2992 }
2993}
2994
2995impl AsPrimitive<u16> for GosValue {
2996 #[inline]
2997 fn as_(&self) -> u16 {
2998 *self.as_uint16()
2999 }
3000}
3001
3002impl From<u32> for GosValue {
3003 #[inline]
3004 fn from(i: u32) -> Self {
3005 GosValue::new(ValueType::Uint32, ValueData::new_uint32(i))
3006 }
3007}
3008
3009impl AsPrimitive<u32> for GosValue {
3010 #[inline]
3011 fn as_(&self) -> u32 {
3012 *self.as_uint32()
3013 }
3014}
3015
3016impl From<u64> for GosValue {
3017 #[inline]
3018 fn from(i: u64) -> Self {
3019 GosValue::new(ValueType::Uint64, ValueData::new_uint64(i))
3020 }
3021}
3022
3023impl AsPrimitive<u64> for GosValue {
3024 #[inline]
3025 fn as_(&self) -> u64 {
3026 *self.as_uint64()
3027 }
3028}
3029
3030impl From<f32> for GosValue {
3031 #[inline]
3032 fn from(f: f32) -> Self {
3033 GosValue::new(ValueType::Float32, ValueData::new_float32(f.into()))
3034 }
3035}
3036
3037impl AsPrimitive<f32> for GosValue {
3038 #[inline]
3039 fn as_(&self) -> f32 {
3040 self.as_float32().into_inner()
3041 }
3042}
3043
3044impl From<f64> for GosValue {
3045 #[inline]
3046 fn from(f: f64) -> Self {
3047 GosValue::new(ValueType::Float64, ValueData::new_float64(f.into()))
3048 }
3049}
3050
3051impl AsPrimitive<f64> for GosValue {
3052 #[inline]
3053 fn as_(&self) -> f64 {
3054 self.as_float64().into_inner()
3055 }
3056}
3057
3058impl From<String> for GosValue {
3059 #[inline]
3060 fn from(s: String) -> Self {
3061 GosValue::new_string(StringObj::with_str(&s))
3062 }
3063}
3064
3065impl AsPrimitive<String> for GosValue {
3066 #[inline]
3067 fn as_(&self) -> String {
3068 self.as_string().as_str().to_owned()
3069 }
3070}
3071
3072define_dispatcher!(Dispatcher8, Elem8);
3073define_dispatcher!(Dispatcher16, Elem16);
3074define_dispatcher!(Dispatcher32, Elem32);
3075define_dispatcher!(Dispatcher64, Elem64);
3076define_dispatcher!(DispatcherWord, ElemWord);
3077define_dispatcher!(DispatcherGos, GosElem);
3078
3079#[cfg(test)]
3080mod test {
3081 use super::super::value::*;
3082 use std::cell::RefCell;
3083 use std::collections::HashMap;
3084 use std::mem;
3085
3086 #[cfg(feature = "serde_borsh")]
3087 #[test]
3088 fn test_serial() {
3089 let data = vec![1.into()];
3090 let dummy_gcc = &GcContainer::new();
3091 let arr = GosValue::array_with_data(data, &ArrCaller::get_slow(ValueType::Int), dummy_gcc);
3092 let v = arr.try_to_vec().unwrap();
3093 let arr = GosValue::try_from_slice(&v).unwrap();
3094 dbg!(arr);
3095 }
3096
3097 #[test]
3098 fn test_size() {
3099 dbg!(mem::size_of::<HashMap<GosValue, GosValue>>());
3100 dbg!(mem::size_of::<String>());
3101 dbg!(mem::size_of::<Rc<String>>());
3102 dbg!(mem::size_of::<Rc<dyn UnsafePtr>>());
3103 dbg!(mem::size_of::<Box<Rc<dyn UnsafePtr>>>());
3104 dbg!(mem::size_of::<RefCell<GosValue>>());
3105 dbg!(mem::size_of::<GosValue>());
3106 dbg!(mem::size_of::<ValueData>());
3107 dbg!(mem::size_of::<Meta>());
3108 dbg!(mem::size_of::<Box<Meta>>());
3109 dbg!(mem::size_of::<OptionBox<Meta>>());
3110
3111 dbg!(mem::size_of::<Option<bool>>());
3112 dbg!(mem::size_of::<ValueData>());
3113 dbg!(mem::size_of::<Cell<bool>>());
3114 dbg!(mem::size_of::<Cell<u8>>());
3115 dbg!(mem::size_of::<RefCell<u8>>());
3116
3117 dbg!(mem::size_of::<ArrayObj<GosElem>>());
3118 dbg!(mem::size_of::<SliceObj<GosElem>>());
3119 dbg!(mem::size_of::<(StructObj, RCount)>());
3120 dbg!(mem::size_of::<MapObj>());
3121 dbg!(mem::size_of::<PackageObj>());
3122 dbg!(mem::size_of::<FunctionObj>());
3123 dbg!(mem::size_of::<ClosureObj>());
3124 dbg!(mem::size_of::<RefCell<GosValue>>());
3125
3126 let s = GosValue::with_str("aaa");
3127 dbg!(s.data());
3128 }
3131}