1use super::gc::{GcWeak, GcoVec};
3use super::instruction::{Opcode, ValueType};
4use super::metadata::*;
5pub use super::objects::*;
6use super::stack::Stack;
7use ordered_float;
8use std::cell::{Cell, RefCell};
9use std::cmp::Ordering;
10use std::collections::VecDeque;
11use std::fmt::{self, Display};
12use std::hash::{Hash, Hasher};
13use std::num::Wrapping;
14use std::rc::Rc;
15use std::result;
16
17type F32 = ordered_float::OrderedFloat<f32>;
18type F64 = ordered_float::OrderedFloat<f64>;
19pub type IRC = i32;
20pub type RCount = Cell<IRC>;
21pub type RCQueue = VecDeque<IRC>;
22
23#[inline]
24pub fn rcount_mark_and_queue(rc: &RCount, queue: &mut RCQueue) {
25 let i = rc.get();
26 if i <= 0 {
27 queue.push_back(i);
28 rc.set(1);
29 }
30}
31
32macro_rules! unwrap_gos_val {
33 ($name:tt, $self_:ident) => {
34 if let GosValue::$name(k) = $self_ {
35 k
36 } else {
37 unreachable!();
38 }
39 };
40}
41
42macro_rules! union_op_wrap {
43 ($a:ident, $b:ident, $name:tt, $op:tt) => {
44 GosValue64{
45 data: V64Union {
46 $name: (Wrapping($a.data.$name) $op Wrapping($b.data.$name)).0,
47 }}
48 };
49}
50
51macro_rules! union_op {
52 ($a:ident, $b:ident, $name:tt, $op:tt) => {
53 GosValue64{
54 data: V64Union {
55 $name: $a.data.$name $op $b.data.$name,
56 }}
57 };
58}
59
60macro_rules! union_shift {
61 ($a:ident, $b:ident, $name:tt, $op:tt) => {
62 GosValue64 {
63 data: V64Union {
64 $name: $a.data.$name.$op($b).unwrap_or(0),
65 },
66 }
67 };
68}
69
70macro_rules! union_cmp {
71 ($a:ident, $b:ident, $name:tt, $op:tt) => {
72 $a.data.$name $op $b.data.$name
73 };
74}
75
76macro_rules! binary_op_int_float {
77 ($t:ident, $a:ident, $b:ident, $op:tt) => {
78 match $t {
79 ValueType::Int => union_op_wrap!($a, $b, int, $op),
80 ValueType::Int8 => union_op_wrap!($a, $b, int8, $op),
81 ValueType::Int16 => union_op_wrap!($a, $b, int16, $op),
82 ValueType::Int32 => union_op_wrap!($a, $b, int32, $op),
83 ValueType::Int64 => union_op_wrap!($a, $b, int64, $op),
84 ValueType::Uint => union_op_wrap!($a, $b, uint, $op),
85 ValueType::Uint8 => union_op_wrap!($a, $b, uint8, $op),
86 ValueType::Uint16 => union_op_wrap!($a, $b, uint16, $op),
87 ValueType::Uint32 => union_op_wrap!($a, $b, uint32, $op),
88 ValueType::Uint64 => union_op_wrap!($a, $b, uint64, $op),
89 ValueType::Float32 => union_op!($a, $b, float32, $op),
90 ValueType::Float64 => union_op!($a, $b, float64, $op),
91 _ => unreachable!(),
92 }
93 };
94}
95
96macro_rules! binary_op_int_no_wrap {
97 ($t:ident, $a:ident, $b:ident, $op:tt) => {
98 match $t {
99 ValueType::Int => union_op!($a, $b, int, $op),
100 ValueType::Int8 => union_op!($a, $b, int8, $op),
101 ValueType::Int16 => union_op!($a, $b, int16, $op),
102 ValueType::Int32 => union_op!($a, $b, int32, $op),
103 ValueType::Int64 => union_op!($a, $b, int64, $op),
104 ValueType::Uint => union_op!($a, $b, uint, $op),
105 ValueType::Uint8 => union_op!($a, $b, uint8, $op),
106 ValueType::Uint16 => union_op!($a, $b, uint16, $op),
107 ValueType::Uint32 => union_op!($a, $b, uint32, $op),
108 ValueType::Uint64 => union_op!($a, $b, uint64, $op),
109 _ => unreachable!(),
110 }
111 };
112}
113
114macro_rules! cmp_bool_int_float {
115 ($t:ident, $a:ident, $b:ident, $op:tt) => {
116 match $t {
117 ValueType::Bool => union_cmp!($a, $b, ubool, $op),
118 ValueType::Int => union_cmp!($a, $b, int, $op),
119 ValueType::Int8 => union_cmp!($a, $b, int8, $op),
120 ValueType::Int16 => union_cmp!($a, $b, int16, $op),
121 ValueType::Int32 => union_cmp!($a, $b, int32, $op),
122 ValueType::Int64 => union_cmp!($a, $b, int64, $op),
123 ValueType::Uint => union_cmp!($a, $b, uint, $op),
124 ValueType::Uint8 => union_cmp!($a, $b, uint8, $op),
125 ValueType::Uint16 => union_cmp!($a, $b, uint16, $op),
126 ValueType::Uint32 => union_cmp!($a, $b, uint32, $op),
127 ValueType::Uint64 => union_cmp!($a, $b, uint64, $op),
128 ValueType::Float32 => union_cmp!($a, $b, float32, $op),
129 ValueType::Float64 => union_cmp!($a, $b, float64, $op),
130 _ => unreachable!(),
131 }
132 };
133}
134
135macro_rules! cmp_int_float {
136 ($t:ident, $a:ident, $b:ident, $op:tt) => {
137 match $t {
138 ValueType::Int => union_cmp!($a, $b, int, $op),
139 ValueType::Int8 => union_cmp!($a, $b, int8, $op),
140 ValueType::Int16 => union_cmp!($a, $b, int16, $op),
141 ValueType::Int32 => union_cmp!($a, $b, int32, $op),
142 ValueType::Int64 => union_cmp!($a, $b, int64, $op),
143 ValueType::Uint => union_cmp!($a, $b, uint, $op),
144 ValueType::Uint8 => union_cmp!($a, $b, uint8, $op),
145 ValueType::Uint16 => union_cmp!($a, $b, uint16, $op),
146 ValueType::Uint32 => union_cmp!($a, $b, uint32, $op),
147 ValueType::Uint64 => union_cmp!($a, $b, uint64, $op),
148 ValueType::Float32 => union_cmp!($a, $b, float32, $op),
149 ValueType::Float64 => union_cmp!($a, $b, float64, $op),
150 _ => unreachable!(),
151 }
152 };
153}
154
155macro_rules! shift_int {
156 ($t:ident, $a:ident, $b:ident, $op:tt) => {
157 *$a = match $t {
158 ValueType::Int => union_shift!($a, $b, int, $op),
159 ValueType::Int8 => union_shift!($a, $b, int8, $op),
160 ValueType::Int16 => union_shift!($a, $b, int16, $op),
161 ValueType::Int32 => union_shift!($a, $b, int32, $op),
162 ValueType::Int64 => union_shift!($a, $b, int64, $op),
163 ValueType::Uint => union_shift!($a, $b, uint, $op),
164 ValueType::Uint8 => union_shift!($a, $b, uint8, $op),
165 ValueType::Uint16 => union_shift!($a, $b, uint16, $op),
166 ValueType::Uint32 => union_shift!($a, $b, uint32, $op),
167 ValueType::Uint64 => union_shift!($a, $b, uint64, $op),
168 _ => unreachable!(),
169 };
170 };
171}
172
173macro_rules! convert_to_int {
174 ($val:expr, $vt:expr, $d_type:tt, $typ:tt) => {{
175 unsafe {
176 match $vt {
177 ValueType::Uint => $val.data.$d_type = $val.data.uint as $typ,
178 ValueType::Uint8 => $val.data.$d_type = $val.data.uint8 as $typ,
179 ValueType::Uint16 => $val.data.$d_type = $val.data.uint16 as $typ,
180 ValueType::Uint32 => $val.data.$d_type = $val.data.uint32 as $typ,
181 ValueType::Uint64 => $val.data.$d_type = $val.data.uint64 as $typ,
182 ValueType::Int => $val.data.$d_type = $val.data.int as $typ,
183 ValueType::Int8 => $val.data.$d_type = $val.data.int8 as $typ,
184 ValueType::Int16 => $val.data.$d_type = $val.data.int16 as $typ,
185 ValueType::Int32 => $val.data.$d_type = $val.data.int32 as $typ,
186 ValueType::Int64 => $val.data.$d_type = $val.data.int64 as $typ,
187 ValueType::Float32 => $val.data.$d_type = f32::from($val.data.float32) as $typ,
188 ValueType::Float64 => $val.data.$d_type = f64::from($val.data.float64) as $typ,
189 _ => unreachable!(),
190 }
191 }
192 }};
193}
194
195macro_rules! convert_to_float {
196 ($val:expr, $vt:expr, $d_type:tt, $f_type:tt, $typ:tt) => {{
197 unsafe {
198 match $vt {
199 ValueType::Uint => $val.data.$d_type = $f_type::from($val.data.uint as $typ),
200 ValueType::Uint8 => $val.data.$d_type = $f_type::from($val.data.uint8 as $typ),
201 ValueType::Uint16 => $val.data.$d_type = $f_type::from($val.data.uint16 as $typ),
202 ValueType::Uint32 => $val.data.$d_type = $f_type::from($val.data.uint32 as $typ),
203 ValueType::Uint64 => $val.data.$d_type = $f_type::from($val.data.uint64 as $typ),
204 ValueType::Int => $val.data.$d_type = $f_type::from($val.data.int as $typ),
205 ValueType::Int8 => $val.data.$d_type = $f_type::from($val.data.int8 as $typ),
206 ValueType::Int16 => $val.data.$d_type = $f_type::from($val.data.int16 as $typ),
207 ValueType::Int32 => $val.data.$d_type = $f_type::from($val.data.int32 as $typ),
208 ValueType::Int64 => $val.data.$d_type = $f_type::from($val.data.int64 as $typ),
209 ValueType::Float32 => {
210 $val.data.$d_type = $f_type::from(f32::from($val.data.float32) as $typ)
211 }
212 ValueType::Float64 => {
213 $val.data.$d_type = $f_type::from(f64::from($val.data.float64) as $typ)
214 }
215 _ => unreachable!(),
216 }
217 }
218 }};
219}
220
221pub type RuntimeResult<T> = result::Result<T, String>;
222
223pub type EmptyResult = RuntimeResult<()>;
224
225pub type RtValueResult = RuntimeResult<GosValue>;
226
227#[derive(Debug, Clone)]
230pub enum GosValue {
231 Nil(GosMetadata),
232 Bool(bool),
233 Int(isize),
234 Int8(i8),
235 Int16(i16),
236 Int32(i32),
237 Int64(i64),
238 Uint(usize),
239 Uint8(u8),
240 Uint16(u16),
241 Uint32(u32),
242 Uint64(u64),
243 Float32(F32),
244 Float64(F64), Complex64(F32, F32),
246 Complex128(Box<(F64, F64)>),
247
248 Function(FunctionKey),
251 Package(PackageKey),
252 Metadata(GosMetadata),
253
254 Str(Rc<StringObj>), Array(Rc<(ArrayObj, RCount)>),
256 Pointer(Box<PointerObj>),
257 Closure(Rc<(RefCell<ClosureObj>, RCount)>),
258 Slice(Rc<(SliceObj, RCount)>),
259 Map(Rc<(MapObj, RCount)>),
260 Interface(Rc<RefCell<InterfaceObj>>),
261 Struct(Rc<(RefCell<StructObj>, RCount)>),
262 Channel(Rc<ChannelObj>),
263
264 Named(Box<(GosValue, GosMetadata)>),
265}
266
267impl GosValue {
268 #[inline]
269 pub fn new_nil() -> GosValue {
270 GosValue::Nil(GosMetadata::Untyped)
271 }
272
273 #[inline]
274 pub fn new_str(s: String) -> GosValue {
275 GosValue::Str(Rc::new(StringObj::with_str(s)))
276 }
277
278 #[inline]
279 pub fn new_pointer(v: PointerObj) -> GosValue {
280 GosValue::Pointer(Box::new(v))
281 }
282
283 #[inline]
284 pub fn array_with_size(
285 size: usize,
286 val: &GosValue,
287 meta: GosMetadata,
288 gcobjs: &GcoVec,
289 ) -> GosValue {
290 let arr = Rc::new((ArrayObj::with_size(size, val, meta, gcobjs), Cell::new(0)));
291 let v = GosValue::Array(arr);
292 gcobjs.add(&v);
293 v
294 }
295
296 #[inline]
297 pub fn array_with_val(val: Vec<GosValue>, meta: GosMetadata, gcobjs: &GcoVec) -> GosValue {
298 let arr = Rc::new((ArrayObj::with_data(val, meta), Cell::new(0)));
299 let v = GosValue::Array(arr);
300 gcobjs.add(&v);
301 v
302 }
303
304 #[inline]
305 pub fn new_slice(
306 len: usize,
307 cap: usize,
308 meta: GosMetadata,
309 dval: Option<&GosValue>,
310 gcobjs: &GcoVec,
311 ) -> GosValue {
312 let s = Rc::new((SliceObj::new(len, cap, meta, dval), Cell::new(0)));
313 let v = GosValue::Slice(s);
314 gcobjs.add(&v);
315 v
316 }
317
318 #[inline]
319 pub fn new_slice_nil(meta: GosMetadata, gcobjs: &GcoVec) -> GosValue {
320 let s = Rc::new((SliceObj::new_nil(meta), Cell::new(0)));
321 let v = GosValue::Slice(s);
322 gcobjs.add(&v);
323 v
324 }
325
326 #[inline]
327 pub fn slice_with_val(val: Vec<GosValue>, meta: GosMetadata, gcobjs: &GcoVec) -> GosValue {
328 let s = Rc::new((SliceObj::with_data(val, meta), Cell::new(0)));
329 let v = GosValue::Slice(s);
330 gcobjs.add(&v);
331 v
332 }
333
334 #[inline]
335 pub fn slice_with_array(arr: &GosValue, begin: isize, end: isize, gcobjs: &GcoVec) -> GosValue {
336 let s = Rc::new((
337 SliceObj::with_array(&arr.as_array().0, begin, end),
338 Cell::new(0),
339 ));
340 let v = GosValue::Slice(s);
341 gcobjs.add(&v);
342 v
343 }
344
345 #[inline]
346 pub fn new_map(meta: GosMetadata, default_val: GosValue, gcobjs: &GcoVec) -> GosValue {
347 let val = Rc::new((MapObj::new(meta, default_val), Cell::new(0)));
348 let v = GosValue::Map(val);
349 gcobjs.add(&v);
350 v
351 }
352
353 #[inline]
354 pub fn new_map_nil(meta: GosMetadata, default_val: GosValue, gcobjs: &GcoVec) -> GosValue {
355 let val = Rc::new((MapObj::new_nil(meta, default_val), Cell::new(0)));
356 let v = GosValue::Map(val);
357 gcobjs.add(&v);
358 v
359 }
360
361 #[inline]
362 pub fn new_struct(obj: StructObj, gcobjs: &GcoVec) -> GosValue {
363 let val = Rc::new((RefCell::new(obj), Cell::new(0)));
364 let v = GosValue::Struct(val);
365 gcobjs.add(&v);
366 v
367 }
368
369 #[inline]
370 pub fn new_function(
371 package: PackageKey,
372 meta: GosMetadata,
373 objs: &mut VMObjects,
374 gcv: &GcoVec,
375 flag: FuncFlag,
376 ) -> GosValue {
377 let val = FunctionVal::new(package, meta, objs, gcv, flag);
378 GosValue::Function(objs.functions.insert(val))
379 }
380
381 #[inline]
382 pub fn new_closure(
383 fkey: FunctionKey,
384 fobjs: &FunctionObjs, ) -> GosValue {
386 let val = ClosureObj::new_gos(fkey, fobjs, None);
387 GosValue::Closure(Rc::new((RefCell::new(val), Cell::new(0))))
388 }
389
390 #[inline]
391 pub fn new_runtime_closure(clsobj: ClosureObj, gcobjs: &GcoVec) -> GosValue {
392 let v = GosValue::Closure(Rc::new((RefCell::new(clsobj), Cell::new(0))));
393 gcobjs.add(&v);
394 v
395 }
396
397 #[inline]
398 pub fn new_iface(meta: GosMetadata, underlying: IfaceUnderlying) -> GosValue {
399 let val = Rc::new(RefCell::new(InterfaceObj::new(meta, underlying)));
400 GosValue::Interface(val)
401 }
402
403 #[inline]
404 pub fn new_empty_iface(mdata: &Metadata, underlying: GosValue) -> GosValue {
405 let val = Rc::new(RefCell::new(InterfaceObj::new(
406 mdata.empty_iface,
407 IfaceUnderlying::Gos(underlying, None),
408 )));
409 GosValue::Interface(val)
410 }
411
412 #[inline]
413 pub fn new_channel(meta: GosMetadata, cap: usize) -> GosValue {
414 GosValue::Channel(Rc::new(ChannelObj::new(meta, cap)))
415 }
416
417 #[inline]
418 pub fn new_meta(t: MetadataType, metas: &mut MetadataObjs) -> GosValue {
419 GosValue::Metadata(GosMetadata::NonPtr(metas.insert(t), MetaCategory::Default))
420 }
421
422 #[inline]
423 pub fn as_bool(&self) -> &bool {
424 unwrap_gos_val!(Bool, self)
425 }
426
427 #[inline]
428 pub fn as_int(&self) -> &isize {
429 unwrap_gos_val!(Int, self)
430 }
431
432 #[inline]
433 pub fn as_uint8(&self) -> &u8 {
434 unwrap_gos_val!(Uint8, self)
435 }
436
437 #[inline]
438 pub fn as_int32(&self) -> &i32 {
439 unwrap_gos_val!(Int32, self)
440 }
441
442 #[inline]
443 pub fn as_int_mut(&mut self) -> &mut isize {
444 unwrap_gos_val!(Int, self)
445 }
446
447 #[inline]
448 pub fn as_float(&self) -> &f64 {
449 unwrap_gos_val!(Float64, self)
450 }
451
452 #[inline]
453 pub fn as_str(&self) -> &Rc<StringObj> {
454 unwrap_gos_val!(Str, self)
455 }
456
457 #[inline]
458 pub fn as_array(&self) -> &Rc<(ArrayObj, RCount)> {
459 unwrap_gos_val!(Array, self)
460 }
461
462 #[inline]
463 pub fn as_slice(&self) -> &Rc<(SliceObj, RCount)> {
464 unwrap_gos_val!(Slice, self)
465 }
466
467 #[inline]
468 pub fn as_map(&self) -> &Rc<(MapObj, RCount)> {
469 unwrap_gos_val!(Map, self)
470 }
471
472 #[inline]
473 pub fn as_interface(&self) -> &Rc<RefCell<InterfaceObj>> {
474 unwrap_gos_val!(Interface, self)
475 }
476
477 #[inline]
478 pub fn as_channel(&self) -> &Rc<ChannelObj> {
479 unwrap_gos_val!(Channel, self)
480 }
481
482 #[inline]
483 pub fn as_function(&self) -> &FunctionKey {
484 unwrap_gos_val!(Function, self)
485 }
486
487 #[inline]
488 pub fn as_package(&self) -> &PackageKey {
489 unwrap_gos_val!(Package, self)
490 }
491
492 #[inline]
493 pub fn as_struct(&self) -> &Rc<(RefCell<StructObj>, RCount)> {
494 unwrap_gos_val!(Struct, self)
495 }
496
497 #[inline]
498 pub fn as_closure(&self) -> &Rc<(RefCell<ClosureObj>, RCount)> {
499 unwrap_gos_val!(Closure, self)
500 }
501
502 #[inline]
503 pub fn as_meta(&self) -> &GosMetadata {
504 unwrap_gos_val!(Metadata, self)
505 }
506
507 #[inline]
508 pub fn as_pointer(&self) -> &Box<PointerObj> {
509 unwrap_gos_val!(Pointer, self)
510 }
511
512 #[inline]
513 pub fn as_named(&self) -> &Box<(GosValue, GosMetadata)> {
514 unwrap_gos_val!(Named, self)
515 }
516
517 #[inline]
518 pub fn is_nil(&self) -> bool {
519 match &self {
520 GosValue::Nil(_) => true,
521 _ => false,
522 }
523 }
524
525 pub fn try_get_struct(&self) -> Option<&Rc<(RefCell<StructObj>, RCount)>> {
526 match &self {
527 GosValue::Struct(_) => Some(self.as_struct()),
528 GosValue::Named(n) => Some(n.0.as_struct()),
529 _ => None,
530 }
531 }
532
533 pub fn try_get_map(&self) -> Option<&Rc<(MapObj, RCount)>> {
534 match &self {
535 GosValue::Map(_) => Some(self.as_map()),
536 GosValue::Named(n) => Some(n.0.as_map()),
537 _ => None,
538 }
539 }
540
541 #[inline]
542 pub fn iface_underlying(&self) -> Option<GosValue> {
543 match &self {
544 GosValue::Named(n) => {
545 let b = n.0.as_interface().borrow();
546 b.underlying_value().map(|x| x.clone())
547 }
548 GosValue::Interface(v) => {
549 let b = v.borrow();
550 b.underlying_value().map(|x| x.clone())
551 }
552 _ => unreachable!(),
553 }
554 }
555
556 #[inline]
557 pub fn equals_nil(&self) -> bool {
558 match &self {
559 GosValue::Nil(_) => true,
560 GosValue::Named(n) => n.0.is_nil(),
561 GosValue::Slice(s) => s.0.is_nil(),
562 GosValue::Map(m) => m.0.is_nil(),
563 GosValue::Interface(iface) => iface.borrow().is_nil(),
564 _ => false,
565 }
566 }
567
568 #[inline]
569 pub fn get_type(&self) -> ValueType {
570 match self {
571 GosValue::Nil(_) => ValueType::Nil,
572 GosValue::Bool(_) => ValueType::Bool,
573 GosValue::Int(_) => ValueType::Int,
574 GosValue::Int8(_) => ValueType::Int8,
575 GosValue::Int16(_) => ValueType::Int16,
576 GosValue::Int32(_) => ValueType::Int32,
577 GosValue::Int64(_) => ValueType::Int64,
578 GosValue::Uint(_) => ValueType::Uint,
579 GosValue::Uint8(_) => ValueType::Uint8,
580 GosValue::Uint16(_) => ValueType::Uint16,
581 GosValue::Uint32(_) => ValueType::Uint32,
582 GosValue::Uint64(_) => ValueType::Uint64,
583 GosValue::Float32(_) => ValueType::Float32,
584 GosValue::Float64(_) => ValueType::Float64,
585 GosValue::Complex64(_, _) => ValueType::Complex64,
586 GosValue::Complex128(_) => ValueType::Complex128,
587 GosValue::Str(_) => ValueType::Str,
588 GosValue::Array(_) => ValueType::Array,
589 GosValue::Pointer(_) => ValueType::Pointer,
590 GosValue::Closure(_) => ValueType::Closure,
591 GosValue::Slice(_) => ValueType::Slice,
592 GosValue::Map(_) => ValueType::Map,
593 GosValue::Interface(_) => ValueType::Interface,
594 GosValue::Struct(_) => ValueType::Struct,
595 GosValue::Channel(_) => ValueType::Channel,
596 GosValue::Function(_) => ValueType::Function,
597 GosValue::Package(_) => ValueType::Package,
598 GosValue::Metadata(_) => ValueType::Metadata,
599 GosValue::Named(_) => ValueType::Named,
600 }
601 }
602
603 pub fn identical(&self, other: &GosValue) -> bool {
604 self.get_type() == other.get_type() && self == other
605 }
606
607 pub fn get_meta(&self, objs: &VMObjects, stack: &Stack) -> GosMetadata {
608 match self {
609 GosValue::Nil(m) => *m,
610 GosValue::Bool(_) => objs.metadata.mbool,
611 GosValue::Int(_) => objs.metadata.mint,
612 GosValue::Int8(_) => objs.metadata.mint8,
613 GosValue::Int16(_) => objs.metadata.mint16,
614 GosValue::Int32(_) => objs.metadata.mint32,
615 GosValue::Int64(_) => objs.metadata.mint64,
616 GosValue::Uint(_) => objs.metadata.muint,
617 GosValue::Uint8(_) => objs.metadata.muint8,
618 GosValue::Uint16(_) => objs.metadata.muint16,
619 GosValue::Uint32(_) => objs.metadata.muint32,
620 GosValue::Uint64(_) => objs.metadata.muint64,
621 GosValue::Float32(_) => objs.metadata.mfloat32,
622 GosValue::Float64(_) => objs.metadata.mfloat64,
623 GosValue::Complex64(_, _) => objs.metadata.mcomplex64,
624 GosValue::Complex128(_) => objs.metadata.mcomplex128,
625 GosValue::Str(_) => objs.metadata.mstr,
626 GosValue::Array(a) => a.0.meta,
627 GosValue::Pointer(b) => {
628 let bobj: &PointerObj = &*b;
629 let pointee = match bobj {
630 PointerObj::UpVal(uv) => {
632 let state: &UpValueState = &uv.inner.borrow();
633 match state {
634 UpValueState::Open(d) => stack
635 .get_with_type(d.index as usize, d.typ)
636 .get_meta(objs, stack),
637 UpValueState::Closed(v) => v.get_meta(objs, stack),
638 }
639 }
640 PointerObj::Struct(s, named_md) => match named_md {
641 GosMetadata::Untyped => s.0.borrow().meta,
642 _ => *named_md,
643 },
644 PointerObj::Array(a, named_md) => match named_md {
645 GosMetadata::Untyped => a.0.meta,
646 _ => *named_md,
647 },
648 PointerObj::Slice(s, named_md) => match named_md {
649 GosMetadata::Untyped => s.0.meta,
650 _ => *named_md,
651 },
652 PointerObj::Map(m, named_md) => match named_md {
653 GosMetadata::Untyped => m.0.meta,
654 _ => *named_md,
655 },
656 PointerObj::StructField(sobj, index) => {
657 sobj.0.borrow().fields[*index as usize].get_meta(objs, stack)
658 }
659 PointerObj::SliceMember(sobj, index) => sobj.0.borrow_data()[*index as usize]
660 .borrow()
661 .get_meta(objs, stack),
662 PointerObj::PkgMember(pkey, index) => {
663 objs.packages[*pkey].member(*index).get_meta(objs, stack)
664 }
665 PointerObj::Released => unreachable!(),
666 };
667 pointee.ptr_to()
668 }
669 GosValue::Closure(c) => c.0.borrow().meta,
670 GosValue::Slice(s) => s.0.meta,
671 GosValue::Map(m) => m.0.meta,
672 GosValue::Interface(i) => i.borrow().meta,
673 GosValue::Struct(s) => s.0.borrow().meta,
674 GosValue::Channel(_) => unimplemented!(),
675 GosValue::Function(_) => unimplemented!(),
676 GosValue::Package(_) => unimplemented!(),
677 GosValue::Metadata(_) => unimplemented!(),
678 GosValue::Named(v) => v.1,
679 }
680 }
681
682 #[inline]
683 pub fn copy_semantic(&self, gcos: &GcoVec) -> GosValue {
684 match self {
685 GosValue::Slice(s) => {
686 let rc = Rc::new((SliceObj::clone(&s.0), Cell::new(0)));
687 gcos.add_weak(GcWeak::Slice(Rc::downgrade(&rc)));
688 GosValue::Slice(rc)
689 }
690 GosValue::Map(m) => {
691 let rc = Rc::new((MapObj::clone(&m.0), Cell::new(0)));
692 gcos.add_weak(GcWeak::Map(Rc::downgrade(&rc)));
693 GosValue::Map(rc)
694 }
695 GosValue::Struct(s) => {
696 let rc = Rc::new((RefCell::clone(&s.0), Cell::new(0)));
697 gcos.add_weak(GcWeak::Struct(Rc::downgrade(&rc)));
698 GosValue::Struct(rc)
699 }
700 GosValue::Named(v) => GosValue::Named(Box::new((v.0.copy_semantic(gcos), v.1))),
701 _ => self.clone(),
702 }
703 }
704
705 #[inline]
706 pub fn deep_clone(&self, gcos: &GcoVec) -> GosValue {
707 match self {
708 GosValue::Slice(s) => {
709 let rc = Rc::new((s.0.deep_clone(gcos), Cell::new(0)));
710 gcos.add_weak(GcWeak::Slice(Rc::downgrade(&rc)));
711 GosValue::Slice(rc)
712 }
713 GosValue::Map(m) => {
714 let rc = Rc::new((m.0.deep_clone(gcos), Cell::new(0)));
715 gcos.add_weak(GcWeak::Map(Rc::downgrade(&rc)));
716 GosValue::Map(rc)
717 }
718 GosValue::Array(arr) => {
719 let rc = Rc::new((arr.0.deep_clone(gcos), Cell::new(0)));
720 gcos.add_weak(GcWeak::Array(Rc::downgrade(&rc)));
721 GosValue::Array(rc)
722 }
723 GosValue::Struct(s) => {
724 let rc = Rc::new((RefCell::new(s.0.borrow().deep_clone(gcos)), Cell::new(0)));
725 gcos.add_weak(GcWeak::Struct(Rc::downgrade(&rc)));
726 GosValue::Struct(rc)
727 }
728 GosValue::Pointer(p) => GosValue::Pointer(Box::new(p.deep_clone(gcos))),
729 GosValue::Named(v) => GosValue::Named(Box::new((v.0.deep_clone(gcos), v.1))),
730 _ => self.clone(),
731 }
732 }
733
734 #[inline]
735 pub fn add_str(a: &GosValue, b: &GosValue) -> GosValue {
736 let mut s = a.as_str().as_str().to_string();
737 s.push_str(b.as_str().as_str());
738 GosValue::new_str(s)
739 }
740
741 pub fn ref_sub_one(&self) {
743 match &self {
744 GosValue::Array(obj) => obj.1.set(obj.1.get() - 1),
745 GosValue::Pointer(obj) => obj.ref_sub_one(),
746 GosValue::Closure(obj) => obj.1.set(obj.1.get() - 1),
747 GosValue::Slice(obj) => obj.1.set(obj.1.get() - 1),
748 GosValue::Map(obj) => obj.1.set(obj.1.get() - 1),
749 GosValue::Interface(obj) => obj.borrow().ref_sub_one(),
750 GosValue::Struct(obj) => obj.1.set(obj.1.get() - 1),
751 GosValue::Named(obj) => obj.0.ref_sub_one(),
752 _ => {}
753 };
754 }
755
756 pub fn mark_dirty(&self, queue: &mut RCQueue) {
758 match &self {
759 GosValue::Array(obj) => rcount_mark_and_queue(&obj.1, queue),
760 GosValue::Pointer(obj) => obj.mark_dirty(queue),
761 GosValue::Closure(obj) => rcount_mark_and_queue(&obj.1, queue),
762 GosValue::Slice(obj) => rcount_mark_and_queue(&obj.1, queue),
763 GosValue::Map(obj) => rcount_mark_and_queue(&obj.1, queue),
764 GosValue::Interface(obj) => obj.borrow().mark_dirty(queue),
765 GosValue::Struct(obj) => rcount_mark_and_queue(&obj.1, queue),
766 GosValue::Named(obj) => obj.0.mark_dirty(queue),
767 _ => {}
768 };
769 }
770
771 pub fn rc(&self) -> IRC {
772 match &self {
773 GosValue::Array(obj) => obj.1.get(),
774 GosValue::Closure(obj) => obj.1.get(),
775 GosValue::Slice(obj) => obj.1.get(),
776 GosValue::Map(obj) => obj.1.get(),
777 GosValue::Struct(obj) => obj.1.get(),
778 _ => unreachable!(),
779 }
780 }
781
782 pub fn set_rc(&self, rc: IRC) {
783 match &self {
784 GosValue::Array(obj) => obj.1.set(rc),
785 GosValue::Closure(obj) => obj.1.set(rc),
786 GosValue::Slice(obj) => obj.1.set(rc),
787 GosValue::Map(obj) => obj.1.set(rc),
788 GosValue::Struct(obj) => obj.1.set(rc),
789 _ => unreachable!(),
790 }
791 }
792}
793
794impl Eq for GosValue {}
795
796impl PartialEq for GosValue {
797 fn eq(&self, b: &GosValue) -> bool {
798 match (self, b) {
799 (Self::Nil(_), Self::Nil(_)) => true,
800 (Self::Bool(x), Self::Bool(y)) => x == y,
801 (Self::Int(x), Self::Int(y)) => x == y,
802 (Self::Int8(x), Self::Int8(y)) => x == y,
803 (Self::Int16(x), Self::Int16(y)) => x == y,
804 (Self::Int32(x), Self::Int32(y)) => x == y,
805 (Self::Int64(x), Self::Int64(y)) => x == y,
806 (Self::Uint(x), Self::Uint(y)) => x == y,
807 (Self::Uint8(x), Self::Uint8(y)) => x == y,
808 (Self::Uint16(x), Self::Uint16(y)) => x == y,
809 (Self::Uint32(x), Self::Uint32(y)) => x == y,
810 (Self::Uint64(x), Self::Uint64(y)) => x == y,
811 (Self::Float32(x), Self::Float32(y)) => x == y,
812 (Self::Float64(x), Self::Float64(y)) => x == y,
813 (Self::Complex64(xr, xi), Self::Complex64(yr, yi)) => xr == yr && xi == yi,
814 (Self::Complex128(x), Self::Complex128(y)) => x.0 == y.0 && x.1 == y.1,
815 (Self::Function(x), Self::Function(y)) => x == y,
816 (Self::Package(x), Self::Package(y)) => x == y,
817 (Self::Metadata(x), Self::Metadata(y)) => x == y,
818 (Self::Str(x), Self::Str(y)) => *x == *y,
819 (Self::Array(x), Self::Array(y)) => x.0 == y.0,
820 (Self::Pointer(x), Self::Pointer(y)) => x == y,
821 (Self::Closure(x), Self::Closure(y)) => Rc::ptr_eq(x, y),
822 (Self::Slice(x), Self::Slice(y)) => Rc::ptr_eq(x, y),
823 (Self::Map(x), Self::Map(y)) => Rc::ptr_eq(x, y),
824 (Self::Interface(x), Self::Interface(y)) => InterfaceObj::eq(&x.borrow(), &y.borrow()),
825 (Self::Struct(x), Self::Struct(y)) => StructObj::eq(&x.0.borrow(), &y.0.borrow()),
826 (Self::Channel(x), Self::Channel(y)) => Rc::ptr_eq(x, y),
827 (Self::Named(x), Self::Named(y)) => x.0 == y.0,
828 (Self::Nil(_), nil) | (nil, Self::Nil(_)) => nil.equals_nil(),
829 (Self::Interface(iface), val) | (val, Self::Interface(iface)) => {
830 match iface.borrow().underlying_value() {
831 Some(v) => v == val,
832 None => false,
833 }
834 }
835 _ => false,
836 }
837 }
838}
839
840impl PartialOrd for GosValue {
841 #[inline]
842 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
843 Some(self.cmp(other))
844 }
845}
846
847impl Hash for GosValue {
848 fn hash<H: Hasher>(&self, state: &mut H) {
849 match &self {
850 GosValue::Bool(b) => b.hash(state),
851 GosValue::Int(i) => i.hash(state),
852 GosValue::Int8(i) => i.hash(state),
853 GosValue::Int16(i) => i.hash(state),
854 GosValue::Int32(i) => i.hash(state),
855 GosValue::Int64(i) => i.hash(state),
856 GosValue::Uint(i) => i.hash(state),
857 GosValue::Uint8(i) => i.hash(state),
858 GosValue::Uint16(i) => i.hash(state),
859 GosValue::Uint32(i) => i.hash(state),
860 GosValue::Uint64(i) => i.hash(state),
861 GosValue::Float32(f) => f.to_bits().hash(state),
862 GosValue::Float64(f) => f.to_bits().hash(state),
863 GosValue::Str(s) => s.as_str().hash(state),
864 GosValue::Array(a) => a.0.hash(state),
865 GosValue::Complex64(i, r) => {
866 i.hash(state);
867 r.hash(state);
868 }
869 GosValue::Complex128(c) => {
870 c.0.hash(state);
871 c.1.hash(state);
872 }
873 GosValue::Struct(s) => {
874 s.0.borrow().hash(state);
875 }
876 GosValue::Interface(i) => {
877 i.borrow().hash(state);
878 }
879 GosValue::Pointer(p) => {
880 PointerObj::hash(&p, state);
881 }
882 GosValue::Named(n) => n.0.hash(state),
883 _ => unreachable!(),
884 }
885 }
886}
887
888impl Ord for GosValue {
889 fn cmp(&self, b: &Self) -> Ordering {
890 match (self, b) {
891 (Self::Bool(x), Self::Bool(y)) => x.cmp(y),
892 (Self::Int(x), Self::Int(y)) => x.cmp(y),
893 (Self::Int8(x), Self::Int8(y)) => x.cmp(y),
894 (Self::Int16(x), Self::Int16(y)) => x.cmp(y),
895 (Self::Int32(x), Self::Int32(y)) => x.cmp(y),
896 (Self::Int64(x), Self::Int64(y)) => x.cmp(y),
897 (Self::Uint(x), Self::Uint(y)) => x.cmp(y),
898 (Self::Uint8(x), Self::Uint8(y)) => x.cmp(y),
899 (Self::Uint16(x), Self::Uint16(y)) => x.cmp(y),
900 (Self::Uint32(x), Self::Uint32(y)) => x.cmp(y),
901 (Self::Uint64(x), Self::Uint64(y)) => x.cmp(y),
902 (Self::Float32(x), Self::Float32(y)) => x.cmp(y),
903 (Self::Float64(x), Self::Float64(y)) => x.cmp(y),
904 (Self::Str(x), Self::Str(y)) => x.cmp(y),
905 _ => {
906 dbg!(self, b);
907 unreachable!()
908 }
909 }
910 }
911}
912
913impl Display for GosValue {
914 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
915 match self {
916 GosValue::Nil(_) => f.write_str("<nil>"),
917 GosValue::Bool(true) => f.write_str("true"),
918 GosValue::Bool(false) => f.write_str("false"),
919 GosValue::Int(i) => write!(f, "{}", i),
920 GosValue::Int8(i) => write!(f, "{}", i),
921 GosValue::Int16(i) => write!(f, "{}", i),
922 GosValue::Int32(i) => write!(f, "{}", i),
923 GosValue::Int64(i) => write!(f, "{}", i),
924 GosValue::Uint(i) => write!(f, "{}", i),
925 GosValue::Uint8(i) => write!(f, "{}", i),
926 GosValue::Uint16(i) => write!(f, "{}", i),
927 GosValue::Uint32(i) => write!(f, "{}", i),
928 GosValue::Uint64(i) => write!(f, "{}", i),
929 GosValue::Float32(fl) => write!(f, "{}", fl),
930 GosValue::Float64(fl) => write!(f, "{}", fl),
931 GosValue::Complex64(r, i) => write!(f, "({}, {})", r, i),
932 GosValue::Complex128(b) => write!(f, "({}, {})", b.0, b.1),
933 GosValue::Str(s) => f.write_str(s.as_ref().as_str()),
934 GosValue::Array(a) => write!(f, "{}", a.0),
935 GosValue::Pointer(p) => p.fmt(f),
936 GosValue::Closure(_) => f.write_str("<closure>"),
937 GosValue::Slice(s) => write!(f, "{}", s.0),
938 GosValue::Map(m) => write!(f, "{}", m.0),
939 GosValue::Interface(i) => write!(f, "{}", i.borrow()),
940 GosValue::Struct(s) => write!(f, "{}", s.0.borrow()),
941 GosValue::Channel(_) => f.write_str("<channel>"),
942 GosValue::Function(_) => f.write_str("<function>"),
943 GosValue::Package(_) => f.write_str("<package>"),
944 GosValue::Metadata(_) => f.write_str("<metadata>"),
945 GosValue::Named(v) => write!(f, "{}", v.0),
946 }
947 }
948}
949
950#[derive(Copy, Clone)]
956pub union V64Union {
957 nil: (),
958 ubool: bool,
959 int: isize,
960 int8: i8,
961 int16: i16,
962 int32: i32,
963 int64: i64,
964 uint: usize,
965 uint8: u8,
966 uint16: u16,
967 uint32: u32,
968 uint64: u64,
969 float32: F32,
970 float64: F64,
971 complex64: (F32, F32),
972 function: FunctionKey,
973 package: PackageKey,
974}
975
976impl fmt::Debug for V64Union {
977 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
978 f.write_fmt(format_args!("{:x}", unsafe { self.uint64 }))
979 }
980}
981
982#[derive(Copy, Clone, Debug)]
986pub struct GosValue64 {
987 data: V64Union,
988 }
990
991impl GosValue64 {
992 #[inline]
993 pub fn from_v128(v: &GosValue) -> (GosValue64, ValueType) {
994 match v {
995 GosValue::Bool(b) => (
996 GosValue64 {
997 data: V64Union { ubool: *b },
998 },
999 ValueType::Bool,
1000 ),
1001 GosValue::Int(i) => (
1002 GosValue64 {
1003 data: V64Union { int: *i },
1004 },
1005 ValueType::Int,
1006 ),
1007 GosValue::Int8(i) => (
1008 GosValue64 {
1009 data: V64Union { int8: *i },
1010 },
1011 ValueType::Int8,
1012 ),
1013 GosValue::Int16(i) => (
1014 GosValue64 {
1015 data: V64Union { int16: *i },
1016 },
1017 ValueType::Int16,
1018 ),
1019 GosValue::Int32(i) => (
1020 GosValue64 {
1021 data: V64Union { int32: *i },
1022 },
1023 ValueType::Int32,
1024 ),
1025 GosValue::Int64(i) => (
1026 GosValue64 {
1027 data: V64Union { int64: *i },
1028 },
1029 ValueType::Int64,
1030 ),
1031 GosValue::Uint(i) => (
1032 GosValue64 {
1033 data: V64Union { uint: *i },
1034 },
1035 ValueType::Uint,
1036 ),
1037 GosValue::Uint8(i) => (
1038 GosValue64 {
1039 data: V64Union { uint8: *i },
1040 },
1041 ValueType::Uint8,
1042 ),
1043 GosValue::Uint16(i) => (
1044 GosValue64 {
1045 data: V64Union { uint16: *i },
1046 },
1047 ValueType::Uint16,
1048 ),
1049 GosValue::Uint32(i) => (
1050 GosValue64 {
1051 data: V64Union { uint32: *i },
1052 },
1053 ValueType::Uint32,
1054 ),
1055 GosValue::Uint64(i) => (
1056 GosValue64 {
1057 data: V64Union { uint64: *i },
1058 },
1059 ValueType::Uint64,
1060 ),
1061 GosValue::Float32(f) => (
1062 GosValue64 {
1063 data: V64Union { float32: *f },
1064 },
1065 ValueType::Float32,
1066 ),
1067 GosValue::Float64(f) => (
1068 GosValue64 {
1069 data: V64Union { float64: *f },
1070 },
1071 ValueType::Float64,
1072 ),
1073 GosValue::Complex64(f1, f2) => (
1074 GosValue64 {
1075 data: V64Union {
1076 complex64: (*f1, *f2),
1077 },
1078 },
1079 ValueType::Complex64,
1080 ),
1081 GosValue::Function(k) => (
1082 GosValue64 {
1083 data: V64Union { function: *k },
1084 },
1085 ValueType::Function,
1086 ),
1087 GosValue::Package(k) => (
1088 GosValue64 {
1089 data: V64Union { package: *k },
1090 },
1091 ValueType::Package,
1092 ),
1093 _ => unreachable!(),
1094 }
1095 }
1096
1097 #[inline]
1098 pub fn nil() -> GosValue64 {
1099 GosValue64 {
1100 data: V64Union { nil: () },
1101 }
1103 }
1104
1105 #[inline]
1106 pub fn from_bool(b: bool) -> GosValue64 {
1107 GosValue64 {
1108 data: V64Union { ubool: b },
1109 }
1111 }
1112
1113 #[inline]
1114 pub fn from_int(i: isize) -> GosValue64 {
1115 GosValue64 {
1116 data: V64Union { int: i },
1117 }
1119 }
1120
1121 #[inline]
1122 pub fn from_int32_as(i: i32, t: ValueType) -> GosValue64 {
1123 let u = match t {
1124 ValueType::Int => V64Union { int: i as isize },
1125 ValueType::Int8 => V64Union { int8: i as i8 },
1126 ValueType::Int16 => V64Union { int16: i as i16 },
1127 ValueType::Int32 => V64Union { int32: i as i32 },
1128 ValueType::Int64 => V64Union { int64: i as i64 },
1129 ValueType::Uint => V64Union { uint: i as usize },
1130 ValueType::Uint8 => V64Union { uint8: i as u8 },
1131 ValueType::Uint16 => V64Union { uint16: i as u16 },
1132 ValueType::Uint32 => V64Union { uint32: i as u32 },
1133 ValueType::Uint64 => V64Union { uint64: i as u64 },
1134 _ => unreachable!(),
1135 };
1136 GosValue64 { data: u }
1137 }
1138
1139 #[inline]
1140 pub fn from_float64(f: F64) -> GosValue64 {
1141 GosValue64 {
1142 data: V64Union { float64: f },
1143 }
1145 }
1146
1147 #[inline]
1148 pub fn from_complex64(r: F32, i: F32) -> GosValue64 {
1149 GosValue64 {
1150 data: V64Union { complex64: (r, i) },
1151 }
1153 }
1154
1155 #[inline]
1157 pub fn get_v128(&self, t: ValueType) -> GosValue {
1158 unsafe {
1160 match t {
1161 ValueType::Bool => GosValue::Bool(self.data.ubool),
1162 ValueType::Int => GosValue::Int(self.data.int),
1163 ValueType::Int8 => GosValue::Int8(self.data.int8),
1164 ValueType::Int16 => GosValue::Int16(self.data.int16),
1165 ValueType::Int32 => GosValue::Int32(self.data.int32),
1166 ValueType::Int64 => GosValue::Int64(self.data.int64),
1167 ValueType::Uint => GosValue::Uint(self.data.uint),
1168 ValueType::Uint8 => GosValue::Uint8(self.data.uint8),
1169 ValueType::Uint16 => GosValue::Uint16(self.data.uint16),
1170 ValueType::Uint32 => GosValue::Uint32(self.data.uint32),
1171 ValueType::Uint64 => GosValue::Uint64(self.data.uint64),
1172 ValueType::Float32 => GosValue::Float32(self.data.float32),
1173 ValueType::Float64 => GosValue::Float64(self.data.float64),
1174 ValueType::Complex64 => {
1175 GosValue::Complex64(self.data.complex64.0, self.data.complex64.1)
1176 }
1177 ValueType::Function => GosValue::Function(self.data.function),
1178 ValueType::Package => GosValue::Package(self.data.package),
1179 _ => unreachable!(),
1180 }
1181 }
1182 }
1183
1184 #[inline]
1185 pub fn get_bool(&self) -> bool {
1186 unsafe { self.data.ubool }
1188 }
1189
1190 #[inline]
1191 pub fn get_int(&self) -> isize {
1192 unsafe { self.data.int }
1194 }
1195
1196 #[inline]
1197 pub fn get_int32(&self) -> i32 {
1198 unsafe { self.data.int32 }
1199 }
1200
1201 #[inline]
1202 pub fn get_uint(&self) -> usize {
1203 unsafe { self.data.uint }
1204 }
1205
1206 #[inline]
1207 pub fn get_uint32(&self) -> u32 {
1208 unsafe { self.data.uint32 }
1209 }
1210
1211 #[inline]
1212 pub fn get_float64(&self) -> F64 {
1213 unsafe { self.data.float64 }
1215 }
1216
1217 #[inline]
1218 pub fn get_complex64(&self) -> (F32, F32) {
1219 unsafe { self.data.complex64 }
1221 }
1222
1223 #[inline]
1224 pub fn to_uint(&mut self, t: ValueType) {
1225 convert_to_int!(self, t, uint, usize);
1226 }
1227
1228 #[inline]
1229 pub fn to_uint8(&mut self, t: ValueType) {
1230 convert_to_int!(self, t, uint8, u8);
1231 }
1232
1233 #[inline]
1234 pub fn to_uint16(&mut self, t: ValueType) {
1235 convert_to_int!(self, t, uint16, u16);
1236 }
1237
1238 #[inline]
1239 pub fn to_uint32(&mut self, t: ValueType) {
1240 convert_to_int!(self, t, uint32, u32);
1241 }
1242
1243 #[inline]
1244 pub fn to_uint64(&mut self, t: ValueType) {
1245 convert_to_int!(self, t, uint64, u64);
1246 }
1247
1248 #[inline]
1249 pub fn to_int(&mut self, t: ValueType) {
1250 convert_to_int!(self, t, int, isize);
1251 }
1252
1253 #[inline]
1254 pub fn to_int8(&mut self, t: ValueType) {
1255 convert_to_int!(self, t, int8, i8);
1256 }
1257
1258 #[inline]
1259 pub fn to_int16(&mut self, t: ValueType) {
1260 convert_to_int!(self, t, int16, i16);
1261 }
1262
1263 #[inline]
1264 pub fn to_int32(&mut self, t: ValueType) {
1265 convert_to_int!(self, t, int32, i32);
1266 }
1267
1268 #[inline]
1269 pub fn to_int64(&mut self, t: ValueType) {
1270 convert_to_int!(self, t, int64, i64);
1271 }
1272
1273 #[inline]
1274 pub fn to_float32(&mut self, t: ValueType) {
1275 convert_to_float!(self, t, float32, F32, f32);
1276 }
1277
1278 #[inline]
1279 pub fn to_float64(&mut self, t: ValueType) {
1280 convert_to_float!(self, t, float64, F64, f64);
1281 }
1282
1283 #[inline]
1284 pub fn unary_negate(&mut self, t: ValueType) {
1285 match t {
1286 ValueType::Int => self.data.int = -unsafe { self.data.int },
1287 ValueType::Int8 => self.data.int8 = -unsafe { self.data.int8 },
1288 ValueType::Int16 => self.data.int16 = -unsafe { self.data.int16 },
1289 ValueType::Int32 => self.data.int32 = -unsafe { self.data.int32 },
1290 ValueType::Int64 => self.data.int64 = -unsafe { self.data.int64 },
1291 ValueType::Float32 => self.data.float32 = -unsafe { self.data.float32 },
1292 ValueType::Float64 => self.data.float64 = -unsafe { self.data.float64 },
1293 ValueType::Uint => self.data.uint = unsafe { (!0) ^ self.data.uint } + 1,
1294 ValueType::Uint8 => self.data.uint8 = unsafe { (!0) ^ self.data.uint8 } + 1,
1295 ValueType::Uint16 => self.data.uint16 = unsafe { (!0) ^ self.data.uint16 } + 1,
1296 ValueType::Uint32 => self.data.uint32 = unsafe { (!0) ^ self.data.uint32 } + 1,
1297 ValueType::Uint64 => self.data.uint64 = unsafe { (!0) ^ self.data.uint64 } + 1,
1298 _ => unreachable!(),
1299 }
1300 }
1301
1302 #[inline]
1303 pub fn unary_xor(&mut self, t: ValueType) {
1304 match t {
1305 ValueType::Uint => self.data.uint = unsafe { (!0) ^ self.data.uint },
1306 ValueType::Uint8 => self.data.uint8 = unsafe { (!0) ^ self.data.uint8 },
1307 ValueType::Uint16 => self.data.uint16 = unsafe { (!0) ^ self.data.uint16 },
1308 ValueType::Uint32 => self.data.uint32 = unsafe { (!0) ^ self.data.uint32 },
1309 ValueType::Uint64 => self.data.uint64 = unsafe { (!0) ^ self.data.uint64 },
1310 ValueType::Int => self.data.int = unsafe { -1 ^ self.data.int },
1311 ValueType::Int8 => self.data.int8 = unsafe { -1 ^ self.data.int8 },
1312 ValueType::Int16 => self.data.int16 = unsafe { -1 ^ self.data.int16 },
1313 ValueType::Int32 => self.data.int32 = unsafe { -1 ^ self.data.int32 },
1314 ValueType::Int64 => self.data.int64 = unsafe { -1 ^ self.data.int64 },
1315 _ => unreachable!(),
1316 }
1317 }
1318
1319 #[inline]
1320 pub fn unary_not(&mut self, t: ValueType) {
1321 debug_assert!(t == ValueType::Bool);
1322 self.data.ubool = unsafe { !self.data.ubool };
1323 }
1324
1325 #[inline]
1326 pub fn binary_op_add(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1327 unsafe { binary_op_int_float!(t, a, b, +) }
1328 }
1329
1330 #[inline]
1331 pub fn binary_op_sub(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1332 unsafe { binary_op_int_float!(t, a, b, -) }
1333 }
1334
1335 #[inline]
1336 pub fn binary_op_mul(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1337 unsafe { binary_op_int_float!(t, a, b, *) }
1338 }
1339
1340 #[inline]
1341 pub fn binary_op_quo(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1342 unsafe { binary_op_int_float!(t, a, b, /) }
1343 }
1344
1345 #[inline]
1346 pub fn binary_op_rem(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1347 unsafe { binary_op_int_no_wrap!(t, a, b, %) }
1348 }
1349
1350 #[inline]
1351 pub fn binary_op_and(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1352 unsafe { binary_op_int_no_wrap!(t, a, b, &) }
1353 }
1354
1355 #[inline]
1356 pub fn binary_op_or(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1357 unsafe { binary_op_int_no_wrap!(t, a, b, |) }
1358 }
1359
1360 #[inline]
1361 pub fn binary_op_xor(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1362 unsafe { binary_op_int_no_wrap!(t, a, b, ^) }
1363 }
1364
1365 #[inline]
1366 pub fn binary_op_shl(&mut self, b: u32, t: ValueType) {
1367 unsafe { shift_int!(t, self, b, checked_shl) }
1368 }
1369
1370 #[inline]
1371 pub fn binary_op_shr(&mut self, b: u32, t: ValueType) {
1372 unsafe { shift_int!(t, self, b, checked_shr) }
1373 }
1374
1375 #[inline]
1376 pub fn binary_op_and_not(a: &GosValue64, b: &GosValue64, t: ValueType) -> GosValue64 {
1377 GosValue64 {
1378 data: unsafe {
1380 match t {
1381 ValueType::Int => V64Union {
1382 int: a.data.int & !b.data.int,
1383 },
1384 ValueType::Int8 => V64Union {
1385 int8: a.data.int8 & !b.data.int8,
1386 },
1387 ValueType::Int16 => V64Union {
1388 int16: a.data.int16 & !b.data.int16,
1389 },
1390 ValueType::Int32 => V64Union {
1391 int32: a.data.int32 & !b.data.int32,
1392 },
1393 ValueType::Int64 => V64Union {
1394 int64: a.data.int64 & !b.data.int64,
1395 },
1396 ValueType::Uint => V64Union {
1397 uint: a.data.uint & !b.data.uint,
1398 },
1399 ValueType::Uint8 => V64Union {
1400 uint8: a.data.uint8 & !b.data.uint8,
1401 },
1402 ValueType::Uint16 => V64Union {
1403 uint16: a.data.uint16 & !b.data.uint16,
1404 },
1405 ValueType::Uint32 => V64Union {
1406 uint32: a.data.uint32 & !b.data.uint32,
1407 },
1408 ValueType::Uint64 => V64Union {
1409 uint64: a.data.uint64 & !b.data.uint64,
1410 },
1411 _ => unreachable!(),
1412 }
1413 },
1414 }
1415 }
1416
1417 #[inline]
1418 pub fn binary_op(a: &GosValue64, b: &GosValue64, t: ValueType, op: Opcode) -> GosValue64 {
1419 match op {
1420 Opcode::ADD => GosValue64::binary_op_add(a, b, t),
1421 Opcode::SUB => GosValue64::binary_op_sub(a, b, t),
1422 Opcode::MUL => GosValue64::binary_op_mul(a, b, t),
1423 Opcode::QUO => GosValue64::binary_op_quo(a, b, t),
1424 Opcode::REM => GosValue64::binary_op_rem(a, b, t),
1425 Opcode::AND => GosValue64::binary_op_and(a, b, t),
1426 Opcode::OR => GosValue64::binary_op_or(a, b, t),
1427 Opcode::XOR => GosValue64::binary_op_xor(a, b, t),
1428 Opcode::AND_NOT => GosValue64::binary_op_and_not(a, b, t),
1429 Opcode::SHL => {
1430 let mut v = a.clone();
1431 v.binary_op_shl(b.get_uint32(), t);
1432 v
1433 }
1434 Opcode::SHR => {
1435 let mut v = a.clone();
1436 v.binary_op_shr(b.get_uint32(), t);
1437 v
1438 }
1439 _ => {
1440 dbg!(t, op);
1441 unreachable!()
1442 }
1443 }
1444 }
1445
1446 #[inline]
1447 pub fn compare_eql(a: &GosValue64, b: &GosValue64, t: ValueType) -> bool {
1448 unsafe { cmp_bool_int_float!(t, a, b, ==) }
1449 }
1450
1451 #[inline]
1452 pub fn compare_neq(a: &GosValue64, b: &GosValue64, t: ValueType) -> bool {
1453 unsafe { cmp_bool_int_float!(t, a, b, !=) }
1454 }
1455
1456 #[inline]
1457 pub fn compare_lss(a: &GosValue64, b: &GosValue64, t: ValueType) -> bool {
1458 unsafe { cmp_int_float!(t, a, b, <) }
1459 }
1460
1461 #[inline]
1462 pub fn compare_gtr(a: &GosValue64, b: &GosValue64, t: ValueType) -> bool {
1463 unsafe { cmp_int_float!(t, a, b, >) }
1464 }
1465
1466 #[inline]
1467 pub fn compare_leq(a: &GosValue64, b: &GosValue64, t: ValueType) -> bool {
1468 unsafe { cmp_int_float!(t, a, b, <=) }
1469 }
1470
1471 #[inline]
1472 pub fn compare_geq(a: &GosValue64, b: &GosValue64, t: ValueType) -> bool {
1473 unsafe { cmp_int_float!(t, a, b, >=) }
1474 }
1475}
1476
1477#[cfg(test)]
1478mod test {
1479 use super::super::value::*;
1480 use std::collections::HashMap;
1481 use std::mem;
1482
1483 #[test]
1484 fn test_types() {
1485 let _t1: Vec<GosValue> = vec![
1486 GosValue::new_str("Norway".to_string()),
1487 GosValue::Int(100),
1488 GosValue::new_str("Denmark".to_string()),
1489 GosValue::Int(10),
1490 ];
1491
1492 let _t2: Vec<GosValue> = vec![
1493 GosValue::new_str("Norway".to_string()),
1494 GosValue::Int(100),
1495 GosValue::new_str("Denmark".to_string()),
1496 GosValue::Int(10),
1497 ];
1498 }
1499
1500 #[test]
1501 fn test_size() {
1502 dbg!(mem::size_of::<HashMap<GosValue, GosValue>>());
1503 dbg!(mem::size_of::<String>());
1504 dbg!(mem::size_of::<Rc<String>>());
1505 dbg!(mem::size_of::<SliceObj>());
1506 dbg!(mem::size_of::<RefCell<GosValue>>());
1507 dbg!(mem::size_of::<GosValue>());
1508 dbg!(mem::size_of::<GosValue64>());
1509
1510 let mut h: HashMap<isize, isize> = HashMap::new();
1511 h.insert(0, 1);
1512 let mut h2 = h.clone();
1513 h2.insert(0, 3);
1514 dbg!(h[&0]);
1515 dbg!(h2[&0]);
1516 }
1517}