1#![cfg_attr(not(feature = "std"), no_std)]
38
39extern crate alloc;
40
41use alloc::format;
42use alloc::string::String;
43use alloc::sync::Arc as Rc;
44use alloc::vec::Vec;
45use core::cmp::Ordering;
46use core::hash::{Hash, Hasher};
47use core::ops::Deref;
48
49pub trait ArenaTypes: Clone + core::fmt::Debug + 'static {
58 type Fn: Clone + core::fmt::Debug + FnValueName;
60 type Map: Clone + core::fmt::Debug + MapLike;
62}
63
64pub trait FnValueName {
66 fn name(&self) -> &str;
67}
68
69pub trait MapLike: Sized {
73 fn new() -> Self;
74 fn get(&self, key: &u64) -> Option<&(NanValue, NanValue)>;
75 fn insert(&self, key: u64, value: (NanValue, NanValue)) -> Self;
76 fn insert_owned(self, key: u64, value: (NanValue, NanValue)) -> Self {
78 self.insert(key, value) }
80 fn rewrite_values_mut(&mut self, f: impl FnMut(&mut (NanValue, NanValue)));
83 fn len(&self) -> usize;
84 fn is_empty(&self) -> bool {
85 self.len() == 0
86 }
87 fn iter(&self) -> impl Iterator<Item = (&u64, &(NanValue, NanValue))>;
88 fn values(&self) -> impl Iterator<Item = &(NanValue, NanValue)>;
89}
90
91const QNAN: u64 = 0x7FFC_0000_0000_0000;
96const QNAN_MASK: u64 = 0xFFFC_0000_0000_0000;
97const QNAN_MARKER_BIT: u64 = 1u64 << 50;
98const TAG_SHIFT: u32 = 46;
99const TAG_MASK: u64 = 0xF;
100const PAYLOAD_MASK: u64 = (1u64 << 46) - 1;
101
102pub const TAG_IMMEDIATE: u64 = 0;
103pub const TAG_SYMBOL: u64 = 1;
104pub const TAG_INT: u64 = 2;
105pub const TAG_STRING: u64 = 3;
106pub const TAG_SOME: u64 = 4;
107pub const TAG_NONE: u64 = 5;
108pub const TAG_OK: u64 = 6;
109pub const TAG_ERR: u64 = 7;
110pub const TAG_LIST: u64 = 8;
111pub const TAG_VECTOR: u64 = 9;
112pub const TAG_MAP: u64 = 10;
113pub const TAG_RECORD: u64 = 11;
114pub const TAG_VARIANT: u64 = 12;
115pub const TAG_TUPLE: u64 = 13;
116pub const TAG_INLINE_VARIANT: u64 = 14;
117
118pub const SYMBOL_FN: u64 = 0;
119pub const SYMBOL_BUILTIN: u64 = 1;
120pub const SYMBOL_NAMESPACE: u64 = 2;
121pub const SYMBOL_NULLARY_VARIANT: u64 = 3;
122const SYMBOL_KIND_MASK: u64 = 0b11;
123
124pub const IMM_FALSE: u64 = 0;
125pub const IMM_TRUE: u64 = 1;
126pub const IMM_UNIT: u64 = 2;
127
128pub const WRAP_SOME: u64 = 0;
129pub const WRAP_OK: u64 = 1;
130pub const WRAP_ERR: u64 = 2;
131const WRAPPER_INLINE_KIND_SHIFT: u32 = 43;
132const WRAPPER_INLINE_KIND_MASK: u64 = 0b11 << WRAPPER_INLINE_KIND_SHIFT;
133const WRAPPER_INLINE_PAYLOAD_MASK: u64 = (1u64 << WRAPPER_INLINE_KIND_SHIFT) - 1;
134const WRAPPER_INLINE_IMMEDIATE: u64 = 0;
135const WRAPPER_INLINE_INT: u64 = 1;
136const WRAPPER_INLINE_NONE: u64 = 2;
137const WRAPPER_INT_INLINE_MASK: u64 = WRAPPER_INLINE_PAYLOAD_MASK;
138const WRAPPER_INT_INLINE_MAX: i64 = (1i64 << 42) - 1;
139const WRAPPER_INT_INLINE_MIN: i64 = -(1i64 << 42);
140
141pub const ARENA_REF_BIT: u64 = 1u64 << 45;
142const INT_BIG_BIT: u64 = ARENA_REF_BIT;
143const INT_INLINE_MASK: u64 = (1u64 << 45) - 1;
144pub const INT_INLINE_MAX: i64 = (1i64 << 44) - 1;
145pub const INT_INLINE_MIN: i64 = -(1i64 << 44);
146
147const STRING_ARENA_BIT: u64 = ARENA_REF_BIT;
148const STRING_INLINE_LEN_SHIFT: u32 = 40;
149const STRING_INLINE_LEN_MASK: u64 = 0b111 << STRING_INLINE_LEN_SHIFT;
150const STRING_INLINE_MAX_BYTES: usize = 5;
151
152const IV_CTOR_SHIFT: u32 = 30;
154const IV_CTOR_MASK: u64 = 0xFFFF;
155const IV_KIND_BIT: u64 = 1 << 29;
156const IV_INT_MASK: u64 = (1u64 << 29) - 1;
157const IV_INT_SIGN_BIT: u64 = 1u64 << 28;
158const IV_INT_MAX: i64 = (1i64 << 28) - 1;
159const IV_INT_MIN: i64 = -(1i64 << 28);
160const IV_IMM_SHIFT: u32 = 27;
161const IV_IMM_FALSE: u64 = 0;
162const IV_IMM_TRUE: u64 = 1;
163const IV_IMM_UNIT: u64 = 2;
164const IV_IMM_NONE: u64 = 3;
165
166#[derive(Clone, Copy)]
171pub struct NanValue(u64);
172
173#[derive(Clone, Copy, Debug)]
174pub enum NanString<'a> {
175 Borrowed(&'a str),
176 Inline {
177 len: u8,
178 bytes: [u8; STRING_INLINE_MAX_BYTES],
179 },
180}
181
182impl<'a> NanString<'a> {
183 #[inline]
184 pub fn as_str(&self) -> &str {
185 match self {
186 NanString::Borrowed(s) => s,
187 NanString::Inline { len, bytes } => core::str::from_utf8(&bytes[..*len as usize])
188 .expect("NanString inline payload must be valid UTF-8"),
189 }
190 }
191}
192
193impl Deref for NanString<'_> {
194 type Target = str;
195
196 #[inline]
197 fn deref(&self) -> &Self::Target {
198 self.as_str()
199 }
200}
201
202impl PartialEq for NanString<'_> {
203 #[inline]
204 fn eq(&self, other: &Self) -> bool {
205 self.as_str() == other.as_str()
206 }
207}
208
209impl Eq for NanString<'_> {}
210
211impl PartialEq<&str> for NanString<'_> {
212 #[inline]
213 fn eq(&self, other: &&str) -> bool {
214 self.as_str() == *other
215 }
216}
217
218impl PartialEq<NanString<'_>> for &str {
219 #[inline]
220 fn eq(&self, other: &NanString<'_>) -> bool {
221 *self == other.as_str()
222 }
223}
224
225impl PartialOrd for NanString<'_> {
226 #[inline]
227 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
228 Some(self.cmp(other))
229 }
230}
231
232impl Ord for NanString<'_> {
233 #[inline]
234 fn cmp(&self, other: &Self) -> Ordering {
235 self.as_str().cmp(other.as_str())
236 }
237}
238
239impl Hash for NanString<'_> {
240 #[inline]
241 fn hash<H: Hasher>(&self, state: &mut H) {
242 self.as_str().hash(state);
243 }
244}
245
246impl core::fmt::Display for NanString<'_> {
247 #[inline]
248 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
249 f.write_str(self.as_str())
250 }
251}
252
253impl NanValue {
256 #[inline]
257 fn decode_inline_int_payload(payload: u64) -> i64 {
258 debug_assert!(payload & INT_BIG_BIT == 0);
259 let raw = payload & INT_INLINE_MASK;
260 if raw & (1u64 << 44) != 0 {
261 (raw | !INT_INLINE_MASK) as i64
262 } else {
263 raw as i64
264 }
265 }
266
267 #[inline]
268 pub fn encode(tag: u64, payload: u64) -> Self {
269 debug_assert!(tag <= TAG_MASK);
270 debug_assert!(payload <= PAYLOAD_MASK);
271 NanValue(QNAN | (tag << TAG_SHIFT) | payload)
272 }
273
274 #[inline]
275 pub fn is_nan_boxed(self) -> bool {
276 (self.0 & QNAN_MASK) == QNAN
277 }
278
279 #[inline]
280 pub fn tag(self) -> u64 {
281 (self.0 >> TAG_SHIFT) & TAG_MASK
282 }
283
284 #[inline]
285 pub fn payload(self) -> u64 {
286 self.0 & PAYLOAD_MASK
287 }
288
289 #[inline]
292 pub fn new_float(f: f64) -> Self {
293 let bits = f.to_bits();
294 if (bits & QNAN_MASK) == QNAN {
295 NanValue(bits & !QNAN_MARKER_BIT)
299 } else {
300 NanValue(bits)
301 }
302 }
303
304 #[inline]
305 pub fn as_float(self) -> f64 {
306 f64::from_bits(self.0)
307 }
308
309 #[inline]
310 pub fn new_int_inline(i: i64) -> Self {
311 debug_assert!((INT_INLINE_MIN..=INT_INLINE_MAX).contains(&i));
312 let payload = (i as u64) & INT_INLINE_MASK;
313 Self::encode(TAG_INT, payload)
314 }
315
316 #[inline]
317 pub fn new_int_arena(arena_index: u32) -> Self {
318 Self::encode(TAG_INT, INT_BIG_BIT | (arena_index as u64))
319 }
320
321 #[inline]
322 pub fn new_int<T: ArenaTypes>(i: i64, arena: &mut Arena<T>) -> Self {
323 if (INT_INLINE_MIN..=INT_INLINE_MAX).contains(&i) {
324 Self::new_int_inline(i)
325 } else {
326 let idx = arena.push_i64(i);
327 Self::new_int_arena(idx)
328 }
329 }
330
331 #[inline]
338 pub fn new_big_int<T: ArenaTypes>(value: num_bigint::BigInt, arena: &mut Arena<T>) -> Self {
339 match i64::try_from(&value) {
340 Ok(n) => Self::new_int(n, arena),
341 Err(_) => Self::new_int_arena(arena.push_bigint(value)),
342 }
343 }
344
345 #[inline]
349 pub fn as_int<T: ArenaTypes>(self, arena: &Arena<T>) -> i64 {
350 let p = self.payload();
351 if p & INT_BIG_BIT != 0 {
352 let idx = (p & !INT_BIG_BIT) as u32;
353 arena.get_i64(idx)
354 } else {
355 Self::decode_inline_int_payload(p)
356 }
357 }
358
359 #[inline]
363 pub fn int_ref<T: ArenaTypes>(self, arena: &Arena<T>) -> ArenaIntRef<'_> {
364 let p = self.payload();
365 if p & INT_BIG_BIT != 0 {
366 arena.int_ref_at((p & !INT_BIG_BIT) as u32)
367 } else {
368 ArenaIntRef::Small(Self::decode_inline_int_payload(p))
369 }
370 }
371
372 #[inline]
373 pub fn inline_int_payload(self) -> Option<u64> {
374 (self.is_nan_boxed() && self.tag() == TAG_INT && self.payload() & INT_BIG_BIT == 0)
375 .then_some(self.payload())
376 }
377
378 #[inline]
379 pub fn inline_int_value(self) -> Option<i64> {
380 self.inline_int_payload()
381 .map(Self::decode_inline_int_payload)
382 }
383
384 pub const FALSE: NanValue = NanValue(QNAN | (TAG_IMMEDIATE << TAG_SHIFT) | IMM_FALSE);
387 pub const TRUE: NanValue = NanValue(QNAN | (TAG_IMMEDIATE << TAG_SHIFT) | IMM_TRUE);
388 pub const UNIT: NanValue = NanValue(QNAN | (TAG_IMMEDIATE << TAG_SHIFT) | IMM_UNIT);
389 pub const NONE: NanValue = NanValue(QNAN | (TAG_NONE << TAG_SHIFT));
390 pub const EMPTY_LIST: NanValue = NanValue(QNAN | (TAG_LIST << TAG_SHIFT));
391 pub const EMPTY_MAP: NanValue = NanValue(QNAN | (TAG_MAP << TAG_SHIFT));
392 pub const EMPTY_VECTOR: NanValue = NanValue(QNAN | (TAG_VECTOR << TAG_SHIFT));
393 pub const EMPTY_STRING: NanValue = NanValue(QNAN | (TAG_STRING << TAG_SHIFT));
394
395 #[inline]
396 pub fn new_bool(b: bool) -> Self {
397 if b { Self::TRUE } else { Self::FALSE }
398 }
399
400 #[inline]
401 pub fn as_bool(self) -> bool {
402 self.0 == Self::TRUE.0
403 }
404
405 #[inline]
406 pub fn plain_immediate_payload(self) -> Option<u64> {
407 (self.is_nan_boxed() && self.tag() == TAG_IMMEDIATE && self.payload() <= IMM_UNIT)
408 .then_some(self.payload())
409 }
410
411 #[inline]
412 pub fn wrapper_kind(self) -> u64 {
413 match self.tag() {
414 TAG_SOME => WRAP_SOME,
415 TAG_OK => WRAP_OK,
416 TAG_ERR => WRAP_ERR,
417 _ => panic!("wrapper_kind() called on non-wrapper"),
418 }
419 }
420
421 #[inline]
422 fn wrapper_inline_kind(self) -> Option<u64> {
423 if !self.is_nan_boxed() {
424 return None;
425 }
426 match self.tag() {
427 TAG_SOME | TAG_OK | TAG_ERR if self.payload() & ARENA_REF_BIT == 0 => {
428 Some((self.payload() & WRAPPER_INLINE_KIND_MASK) >> WRAPPER_INLINE_KIND_SHIFT)
429 }
430 _ => None,
431 }
432 }
433
434 #[inline]
435 fn decode_wrapper_inline_int_payload(payload: u64) -> i64 {
436 let raw = payload & WRAPPER_INT_INLINE_MASK;
437 if raw & (1u64 << 42) != 0 {
438 (raw | !WRAPPER_INT_INLINE_MASK) as i64
439 } else {
440 raw as i64
441 }
442 }
443
444 #[inline]
445 fn encode_wrapper_inline_int(i: i64) -> u64 {
446 debug_assert!((WRAPPER_INT_INLINE_MIN..=WRAPPER_INT_INLINE_MAX).contains(&i));
447 (i as u64) & WRAPPER_INT_INLINE_MASK
448 }
449
450 #[inline]
451 pub fn wrapper_inline_inner(self) -> Option<NanValue> {
452 let kind = self.wrapper_inline_kind()?;
453 let payload = self.payload() & WRAPPER_INLINE_PAYLOAD_MASK;
454 match kind {
455 WRAPPER_INLINE_IMMEDIATE => Some(Self::encode(TAG_IMMEDIATE, payload)),
456 WRAPPER_INLINE_INT => Some(Self::new_int_inline(
457 Self::decode_wrapper_inline_int_payload(payload),
458 )),
459 WRAPPER_INLINE_NONE => Some(Self::NONE),
460 _ => None,
461 }
462 }
463
464 #[inline]
465 fn new_inline_wrapper(tag: u64, inline_kind: u64, payload: u64) -> Self {
466 debug_assert!(matches!(tag, TAG_SOME | TAG_OK | TAG_ERR));
467 debug_assert!(inline_kind <= WRAPPER_INLINE_NONE);
468 debug_assert!(payload <= WRAPPER_INLINE_PAYLOAD_MASK);
469 Self::encode(tag, (inline_kind << WRAPPER_INLINE_KIND_SHIFT) | payload)
470 }
471
472 #[inline]
473 pub fn wrapper_parts<T: ArenaTypes>(self, arena: &Arena<T>) -> Option<(u64, NanValue)> {
474 if !self.is_nan_boxed() {
475 return None;
476 }
477 match self.tag() {
478 TAG_SOME | TAG_OK | TAG_ERR if self.payload() & ARENA_REF_BIT != 0 => {
479 Some((self.wrapper_kind(), arena.get_boxed(self.arena_index())))
480 }
481 TAG_SOME | TAG_OK | TAG_ERR => self
482 .wrapper_inline_inner()
483 .map(|inner| (self.wrapper_kind(), inner)),
484 _ => None,
485 }
486 }
487
488 #[inline]
491 pub fn new_some(inner_index: u32) -> Self {
492 Self::encode(TAG_SOME, ARENA_REF_BIT | (inner_index as u64))
493 }
494
495 #[inline]
496 pub fn new_ok(inner_index: u32) -> Self {
497 Self::encode(TAG_OK, ARENA_REF_BIT | (inner_index as u64))
498 }
499
500 #[inline]
501 pub fn new_err(inner_index: u32) -> Self {
502 Self::encode(TAG_ERR, ARENA_REF_BIT | (inner_index as u64))
503 }
504
505 #[inline]
506 pub fn wrapper_index(self) -> u32 {
507 debug_assert!(
508 self.is_nan_boxed()
509 && matches!(self.tag(), TAG_SOME | TAG_OK | TAG_ERR)
510 && self.payload() & ARENA_REF_BIT != 0
511 );
512 self.arena_index()
513 }
514
515 #[inline]
516 pub fn wrapper_inner<T: ArenaTypes>(self, arena: &Arena<T>) -> NanValue {
517 self.wrapper_parts(arena)
518 .map(|(_, inner)| inner)
519 .expect("wrapper_inner() called on non-wrapper")
520 }
521
522 #[inline]
523 fn wrap_value<T: ArenaTypes>(kind: u64, inner: NanValue, arena: &mut Arena<T>) -> Self {
524 if let Some(payload) = inner.plain_immediate_payload() {
525 let tag = match kind {
526 WRAP_SOME => TAG_SOME,
527 WRAP_OK => TAG_OK,
528 WRAP_ERR => TAG_ERR,
529 _ => unreachable!("invalid wrapper kind"),
530 };
531 Self::new_inline_wrapper(tag, WRAPPER_INLINE_IMMEDIATE, payload)
532 } else if inner.is_none() {
533 let tag = match kind {
534 WRAP_SOME => TAG_SOME,
535 WRAP_OK => TAG_OK,
536 WRAP_ERR => TAG_ERR,
537 _ => unreachable!("invalid wrapper kind"),
538 };
539 Self::new_inline_wrapper(tag, WRAPPER_INLINE_NONE, 0)
540 } else if let Some(value) = inner.inline_int_value() {
541 if (WRAPPER_INT_INLINE_MIN..=WRAPPER_INT_INLINE_MAX).contains(&value) {
542 let tag = match kind {
543 WRAP_SOME => TAG_SOME,
544 WRAP_OK => TAG_OK,
545 WRAP_ERR => TAG_ERR,
546 _ => unreachable!("invalid wrapper kind"),
547 };
548 return Self::new_inline_wrapper(
549 tag,
550 WRAPPER_INLINE_INT,
551 Self::encode_wrapper_inline_int(value),
552 );
553 }
554 let idx = arena.push_boxed(inner);
555 match kind {
556 WRAP_SOME => Self::new_some(idx),
557 WRAP_OK => Self::new_ok(idx),
558 WRAP_ERR => Self::new_err(idx),
559 _ => unreachable!("invalid wrapper kind"),
560 }
561 } else {
562 let idx = arena.push_boxed(inner);
563 match kind {
564 WRAP_SOME => Self::new_some(idx),
565 WRAP_OK => Self::new_ok(idx),
566 WRAP_ERR => Self::new_err(idx),
567 _ => unreachable!("invalid wrapper kind"),
568 }
569 }
570 }
571
572 #[inline]
573 pub fn new_some_value<T: ArenaTypes>(inner: NanValue, arena: &mut Arena<T>) -> Self {
574 Self::wrap_value(WRAP_SOME, inner, arena)
575 }
576
577 #[inline]
578 pub fn new_ok_value<T: ArenaTypes>(inner: NanValue, arena: &mut Arena<T>) -> Self {
579 Self::wrap_value(WRAP_OK, inner, arena)
580 }
581
582 #[inline]
583 pub fn new_err_value<T: ArenaTypes>(inner: NanValue, arena: &mut Arena<T>) -> Self {
584 Self::wrap_value(WRAP_ERR, inner, arena)
585 }
586
587 #[inline]
590 pub fn new_string(arena_index: u32) -> Self {
591 Self::encode(TAG_STRING, STRING_ARENA_BIT | (arena_index as u64))
592 }
593
594 #[inline]
595 fn new_small_string_bytes(bytes: &[u8]) -> Self {
596 debug_assert!(bytes.len() <= STRING_INLINE_MAX_BYTES);
597 let mut payload = (bytes.len() as u64) << STRING_INLINE_LEN_SHIFT;
598 for (idx, byte) in bytes.iter().enumerate() {
599 payload |= (*byte as u64) << (idx * 8);
600 }
601 Self::encode(TAG_STRING, payload)
602 }
603
604 #[inline]
605 pub fn small_string(self) -> Option<NanString<'static>> {
606 if !self.is_nan_boxed()
607 || self.tag() != TAG_STRING
608 || self.payload() & STRING_ARENA_BIT != 0
609 {
610 return None;
611 }
612 let payload = self.payload();
613 let len = ((payload & STRING_INLINE_LEN_MASK) >> STRING_INLINE_LEN_SHIFT) as u8;
614 if len as usize > STRING_INLINE_MAX_BYTES {
615 return None;
616 }
617 let mut bytes = [0u8; STRING_INLINE_MAX_BYTES];
618 for (idx, slot) in bytes.iter_mut().take(len as usize).enumerate() {
619 *slot = ((payload >> (idx * 8)) & 0xFF) as u8;
620 }
621 Some(NanString::Inline { len, bytes })
622 }
623
624 #[inline]
625 pub fn new_string_value<T: ArenaTypes>(s: &str, arena: &mut Arena<T>) -> Self {
626 if s.len() <= STRING_INLINE_MAX_BYTES {
627 Self::new_small_string_bytes(s.as_bytes())
628 } else {
629 Self::new_string(arena.push_string(s))
630 }
631 }
632
633 #[inline]
634 pub fn new_list(arena_index: u32) -> Self {
635 Self::encode(TAG_LIST, ARENA_REF_BIT | (arena_index as u64))
636 }
637
638 #[inline]
639 pub fn new_tuple(arena_index: u32) -> Self {
640 Self::encode(TAG_TUPLE, ARENA_REF_BIT | (arena_index as u64))
641 }
642
643 #[inline]
644 pub fn new_map(arena_index: u32) -> Self {
645 Self::encode(TAG_MAP, ARENA_REF_BIT | (arena_index as u64))
646 }
647
648 #[inline]
649 pub fn new_vector(arena_index: u32) -> Self {
650 Self::encode(TAG_VECTOR, ARENA_REF_BIT | (arena_index as u64))
651 }
652
653 #[inline]
654 pub fn new_record(arena_index: u32) -> Self {
655 Self::encode(TAG_RECORD, ARENA_REF_BIT | (arena_index as u64))
656 }
657
658 #[inline]
659 pub fn new_variant(arena_index: u32) -> Self {
660 Self::encode(TAG_VARIANT, ARENA_REF_BIT | (arena_index as u64))
661 }
662
663 #[inline]
664 fn new_symbol(symbol_kind: u64, symbol_index: u32) -> Self {
665 Self::encode(TAG_SYMBOL, symbol_kind | ((symbol_index as u64) << 2))
666 }
667
668 #[inline]
669 pub fn symbol_kind(self) -> u64 {
670 debug_assert!(self.is_nan_boxed() && self.tag() == TAG_SYMBOL);
671 self.payload() & SYMBOL_KIND_MASK
672 }
673
674 #[inline]
675 pub fn symbol_index(self) -> u32 {
676 debug_assert!(self.is_nan_boxed() && self.tag() == TAG_SYMBOL);
677 (self.payload() >> 2) as u32
678 }
679
680 #[inline]
681 pub fn new_nullary_variant(symbol_index: u32) -> Self {
682 Self::new_symbol(SYMBOL_NULLARY_VARIANT, symbol_index)
683 }
684
685 #[inline]
686 pub fn try_new_inline_variant(ctor_id: u32, inner: NanValue) -> Option<Self> {
687 if ctor_id > IV_CTOR_MASK as u32 {
688 return None;
689 }
690 let ctor_bits = (ctor_id as u64) << IV_CTOR_SHIFT;
691
692 if inner.is_nan_boxed() {
693 match inner.tag() {
694 TAG_INT if inner.payload() & INT_BIG_BIT == 0 => {
695 let i = Self::decode_inline_int_payload(inner.payload());
696 if (IV_INT_MIN..=IV_INT_MAX).contains(&i) {
697 let int_bits = (i as u64) & IV_INT_MASK;
698 return Some(Self::encode(TAG_INLINE_VARIANT, ctor_bits | int_bits));
699 }
700 }
701 TAG_IMMEDIATE => {
702 let imm = match inner.payload() {
703 IMM_FALSE => IV_IMM_FALSE,
704 IMM_TRUE => IV_IMM_TRUE,
705 IMM_UNIT => IV_IMM_UNIT,
706 _ => return None,
707 };
708 return Some(Self::encode(
709 TAG_INLINE_VARIANT,
710 ctor_bits | IV_KIND_BIT | (imm << IV_IMM_SHIFT),
711 ));
712 }
713 TAG_NONE => {
714 return Some(Self::encode(
715 TAG_INLINE_VARIANT,
716 ctor_bits | IV_KIND_BIT | (IV_IMM_NONE << IV_IMM_SHIFT),
717 ));
718 }
719 _ => {}
720 }
721 }
722 None
723 }
724
725 #[inline]
726 pub fn inline_variant_ctor_id(self) -> u32 {
727 debug_assert!(self.is_nan_boxed() && self.tag() == TAG_INLINE_VARIANT);
728 ((self.payload() >> IV_CTOR_SHIFT) & IV_CTOR_MASK) as u32
729 }
730
731 #[inline]
732 pub fn inline_variant_inner(self) -> NanValue {
733 debug_assert!(self.is_nan_boxed() && self.tag() == TAG_INLINE_VARIANT);
734 let payload = self.payload();
735 if payload & IV_KIND_BIT == 0 {
736 let raw = payload & IV_INT_MASK;
737 let i = if raw & IV_INT_SIGN_BIT != 0 {
738 (raw | !IV_INT_MASK) as i64
739 } else {
740 raw as i64
741 };
742 Self::new_int_inline(i)
743 } else {
744 let imm = (payload >> IV_IMM_SHIFT) & 0b11;
745 match imm {
746 IV_IMM_FALSE => Self::FALSE,
747 IV_IMM_TRUE => Self::TRUE,
748 IV_IMM_UNIT => Self::UNIT,
749 IV_IMM_NONE => Self::NONE,
750 _ => unreachable!(),
751 }
752 }
753 }
754
755 #[inline]
756 pub fn new_fn(arena_index: u32) -> Self {
757 Self::new_symbol(SYMBOL_FN, arena_index)
758 }
759
760 #[inline]
761 pub fn new_builtin(arena_index: u32) -> Self {
762 Self::new_symbol(SYMBOL_BUILTIN, arena_index)
763 }
764
765 #[inline]
766 pub fn new_namespace(arena_index: u32) -> Self {
767 Self::new_symbol(SYMBOL_NAMESPACE, arena_index)
768 }
769
770 #[inline]
771 pub fn arena_index(self) -> u32 {
772 (self.payload() & !ARENA_REF_BIT) as u32
773 }
774
775 #[inline]
776 pub fn heap_index(self) -> Option<u32> {
777 if !self.is_nan_boxed() {
778 return None;
779 }
780 match self.tag() {
781 TAG_INT => {
782 let p = self.payload();
783 if p & INT_BIG_BIT != 0 {
784 Some((p & !INT_BIG_BIT) as u32)
785 } else {
786 None
787 }
788 }
789 TAG_STRING | TAG_SOME | TAG_OK | TAG_ERR | TAG_LIST | TAG_TUPLE | TAG_MAP
790 | TAG_RECORD | TAG_VARIANT | TAG_VECTOR => {
791 (self.payload() & ARENA_REF_BIT != 0).then_some(self.arena_index())
792 }
793 _ => None,
794 }
795 }
796
797 #[inline]
798 pub fn with_heap_index(self, index: u32) -> Self {
799 if !self.is_nan_boxed() {
800 return self;
801 }
802 match self.tag() {
803 TAG_INT => {
804 debug_assert!(self.payload() & INT_BIG_BIT != 0);
805 Self::new_int_arena(index)
806 }
807 TAG_SOME => Self::new_some(index),
808 TAG_OK => Self::new_ok(index),
809 TAG_ERR => Self::new_err(index),
810 TAG_STRING => Self::new_string(index),
811 TAG_LIST => Self::new_list(index),
812 TAG_TUPLE => Self::new_tuple(index),
813 TAG_MAP => Self::new_map(index),
814 TAG_VECTOR => Self::new_vector(index),
815 TAG_RECORD => Self::new_record(index),
816 TAG_VARIANT => Self::new_variant(index),
817 _ => self,
818 }
819 }
820
821 #[inline]
824 pub fn is_float(self) -> bool {
825 !self.is_nan_boxed()
826 }
827
828 #[inline]
829 pub fn is_int(self) -> bool {
830 self.is_nan_boxed() && self.tag() == TAG_INT
831 }
832
833 #[inline]
834 pub fn is_bool(self) -> bool {
835 self.is_nan_boxed()
836 && self.tag() == TAG_IMMEDIATE
837 && (self.payload() == IMM_TRUE || self.payload() == IMM_FALSE)
838 }
839
840 #[inline]
841 pub fn is_unit(self) -> bool {
842 self.0 == Self::UNIT.0
843 }
844
845 #[inline]
846 pub fn is_none(self) -> bool {
847 self.0 == Self::NONE.0
848 }
849
850 #[inline]
851 pub fn is_some(self) -> bool {
852 self.is_nan_boxed() && self.tag() == TAG_SOME
853 }
854
855 #[inline]
856 pub fn is_ok(self) -> bool {
857 self.is_nan_boxed() && self.tag() == TAG_OK
858 }
859
860 #[inline]
861 pub fn is_err(self) -> bool {
862 self.is_nan_boxed() && self.tag() == TAG_ERR
863 }
864
865 #[inline]
866 pub fn is_string(self) -> bool {
867 self.is_nan_boxed() && self.tag() == TAG_STRING
868 }
869
870 pub fn string_eq<T: ArenaTypes>(self, other: NanValue, arena: &Arena<T>) -> bool {
871 if self.bits() == other.bits() {
872 return true;
873 }
874 if !self.is_string() || !other.is_string() {
875 return false;
876 }
877 arena.get_string_value(self).as_str() == arena.get_string_value(other).as_str()
878 }
879
880 #[inline]
881 pub fn is_list(self) -> bool {
882 self.is_nan_boxed() && self.tag() == TAG_LIST
883 }
884
885 #[inline]
886 pub fn is_record(self) -> bool {
887 self.is_nan_boxed() && self.tag() == TAG_RECORD
888 }
889
890 #[inline]
891 pub fn is_fn(self) -> bool {
892 self.is_nan_boxed() && self.tag() == TAG_SYMBOL && self.symbol_kind() == SYMBOL_FN
893 }
894
895 #[inline]
896 pub fn is_variant(self) -> bool {
897 self.is_nan_boxed()
898 && (self.tag() == TAG_VARIANT
899 || self.tag() == TAG_INLINE_VARIANT
900 || (self.tag() == TAG_SYMBOL && self.symbol_kind() == SYMBOL_NULLARY_VARIANT))
901 }
902
903 #[inline]
904 pub fn is_inline_variant(self) -> bool {
905 self.is_nan_boxed() && self.tag() == TAG_INLINE_VARIANT
906 }
907
908 #[inline]
909 pub fn is_map(self) -> bool {
910 self.is_nan_boxed() && self.tag() == TAG_MAP
911 }
912
913 #[inline]
914 pub fn is_vector(self) -> bool {
915 self.is_nan_boxed() && self.tag() == TAG_VECTOR
916 }
917
918 #[inline]
919 pub fn is_empty_vector_immediate(self) -> bool {
920 self.is_nan_boxed() && self.tag() == TAG_VECTOR && self.payload() & ARENA_REF_BIT == 0
921 }
922
923 #[inline]
924 pub fn is_tuple(self) -> bool {
925 self.is_nan_boxed() && self.tag() == TAG_TUPLE
926 }
927
928 #[inline]
929 pub fn is_builtin(self) -> bool {
930 self.is_nan_boxed() && self.tag() == TAG_SYMBOL && self.symbol_kind() == SYMBOL_BUILTIN
931 }
932
933 #[inline]
934 pub fn is_namespace(self) -> bool {
935 self.is_nan_boxed() && self.tag() == TAG_SYMBOL && self.symbol_kind() == SYMBOL_NAMESPACE
936 }
937
938 #[inline]
939 pub fn is_empty_list_immediate(self) -> bool {
940 self.is_nan_boxed() && self.tag() == TAG_LIST && self.payload() & ARENA_REF_BIT == 0
941 }
942
943 #[inline]
944 pub fn is_empty_map_immediate(self) -> bool {
945 self.is_nan_boxed() && self.tag() == TAG_MAP && self.payload() & ARENA_REF_BIT == 0
946 }
947
948 pub fn type_name(self) -> &'static str {
949 if self.is_float() {
950 return "Float";
951 }
952 match self.tag() {
953 TAG_INT => "Int",
954 TAG_IMMEDIATE => match self.payload() {
955 IMM_FALSE | IMM_TRUE => "Bool",
956 IMM_UNIT => "Unit",
957 _ => "Unknown",
958 },
959 TAG_SOME => "Option.Some",
960 TAG_NONE => "Option.None",
961 TAG_OK => "Result.Ok",
962 TAG_ERR => "Result.Err",
963 TAG_STRING => "String",
964 TAG_LIST => "List",
965 TAG_TUPLE => "Tuple",
966 TAG_MAP => "Map",
967 TAG_VECTOR => "Vector",
968 TAG_RECORD => "Record",
969 TAG_VARIANT | TAG_INLINE_VARIANT => "Variant",
970 TAG_SYMBOL => match self.symbol_kind() {
971 SYMBOL_FN => "Fn",
972 SYMBOL_BUILTIN => "Builtin",
973 SYMBOL_NAMESPACE => "Namespace",
974 SYMBOL_NULLARY_VARIANT => "Variant",
975 _ => "Unknown",
976 },
977 _ => "Unknown",
978 }
979 }
980
981 #[inline]
982 pub fn variant_ctor_id<T: ArenaTypes>(self, arena: &Arena<T>) -> Option<u32> {
983 if !self.is_nan_boxed() {
984 return None;
985 }
986 match self.tag() {
987 TAG_INLINE_VARIANT => Some(self.inline_variant_ctor_id()),
988 TAG_VARIANT => {
989 let (type_id, variant_id, _) = arena.get_variant(self.arena_index());
990 arena.find_ctor_id(type_id, variant_id)
991 }
992 TAG_SYMBOL if self.symbol_kind() == SYMBOL_NULLARY_VARIANT => {
993 Some(arena.get_nullary_variant_ctor(self.symbol_index()))
994 }
995 _ => None,
996 }
997 }
998
999 #[inline]
1000 pub fn variant_parts<T: ArenaTypes>(self, arena: &Arena<T>) -> Option<(u32, u16, &[NanValue])> {
1001 if !self.is_nan_boxed() {
1002 return None;
1003 }
1004 match self.tag() {
1005 TAG_VARIANT => {
1006 let (type_id, variant_id, fields) = arena.get_variant(self.arena_index());
1007 Some((type_id, variant_id, fields))
1008 }
1009 TAG_SYMBOL if self.symbol_kind() == SYMBOL_NULLARY_VARIANT => {
1010 let (type_id, variant_id) =
1011 arena.get_ctor_parts(arena.get_nullary_variant_ctor(self.symbol_index()));
1012 Some((type_id, variant_id, &[]))
1013 }
1014 _ => None,
1015 }
1016 }
1017
1018 #[inline]
1019 pub fn variant_single_field<T: ArenaTypes>(self, arena: &Arena<T>) -> NanValue {
1020 if self.tag() == TAG_INLINE_VARIANT {
1021 self.inline_variant_inner()
1022 } else {
1023 let (_, _, fields) = arena.get_variant(self.arena_index());
1024 debug_assert_eq!(fields.len(), 1);
1025 fields[0]
1026 }
1027 }
1028
1029 #[inline]
1030 pub fn inline_variant_info<T: ArenaTypes>(
1031 self,
1032 arena: &Arena<T>,
1033 ) -> Option<(u32, u16, NanValue)> {
1034 if !self.is_nan_boxed() || self.tag() != TAG_INLINE_VARIANT {
1035 return None;
1036 }
1037 let ctor_id = self.inline_variant_ctor_id();
1038 let (type_id, variant_id) = arena.get_ctor_parts(ctor_id);
1039 Some((type_id, variant_id, self.inline_variant_inner()))
1040 }
1041
1042 #[inline]
1043 pub fn bits(self) -> u64 {
1044 self.0
1045 }
1046
1047 #[inline]
1048 pub fn from_bits(bits: u64) -> Self {
1049 NanValue(bits)
1050 }
1051
1052 pub fn map_key_hash<T: ArenaTypes>(self, arena: &Arena<T>) -> u64 {
1053 if self.is_string() {
1054 use core::hash::{Hash, Hasher};
1055 let mut hasher = DefaultHasher::new();
1056 3u8.hash(&mut hasher);
1057 arena.get_string_value(self).hash(&mut hasher);
1058 hasher.finish()
1059 } else if self.is_int() && self.heap_index().is_some() {
1060 self.map_key_hash_deep(arena)
1065 } else {
1066 self.bits()
1067 }
1068 }
1069
1070 pub fn map_key_hash_deep<T: ArenaTypes>(self, arena: &Arena<T>) -> u64 {
1075 use core::hash::Hasher;
1076 let mut hasher = DefaultHasher::new();
1077 self.hash_in(&mut hasher, arena);
1078 hasher.finish()
1079 }
1080}
1081
1082impl core::fmt::Debug for NanValue {
1085 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1086 if self.is_float() {
1087 return write!(f, "Float({})", self.as_float());
1088 }
1089 match self.tag() {
1090 TAG_INT => {
1091 if self.payload() & INT_BIG_BIT != 0 {
1092 write!(f, "Int(arena:{})", (self.payload() & !INT_BIG_BIT) as u32)
1093 } else {
1094 write!(
1095 f,
1096 "Int({})",
1097 Self::decode_inline_int_payload(self.payload())
1098 )
1099 }
1100 }
1101 TAG_IMMEDIATE => match self.payload() {
1102 IMM_FALSE => write!(f, "False"),
1103 IMM_TRUE => write!(f, "True"),
1104 IMM_UNIT => write!(f, "Unit"),
1105 _ => write!(f, "Immediate({})", self.payload()),
1106 },
1107 TAG_NONE => write!(f, "None"),
1108 TAG_SOME | TAG_OK | TAG_ERR => {
1109 let kind = match self.tag() {
1110 TAG_SOME => "Some",
1111 TAG_OK => "Ok",
1112 TAG_ERR => "Err",
1113 _ => "?",
1114 };
1115 if self.payload() & ARENA_REF_BIT != 0 {
1116 write!(f, "{}(arena:{})", kind, self.arena_index())
1117 } else if let Some(inner) = self.wrapper_inline_inner() {
1118 write!(f, "{}({:?})", kind, inner)
1119 } else {
1120 write!(f, "{}(?)", kind)
1121 }
1122 }
1123 TAG_SYMBOL => match self.symbol_kind() {
1124 SYMBOL_FN => write!(f, "Fn(symbol:{})", self.symbol_index()),
1125 SYMBOL_BUILTIN => write!(f, "Builtin(symbol:{})", self.symbol_index()),
1126 SYMBOL_NAMESPACE => write!(f, "Namespace(symbol:{})", self.symbol_index()),
1127 SYMBOL_NULLARY_VARIANT => {
1128 write!(f, "NullaryVariant(symbol:{})", self.symbol_index())
1129 }
1130 _ => write!(f, "Symbol({})", self.payload()),
1131 },
1132 TAG_STRING => {
1133 if let Some(s) = self.small_string() {
1134 write!(f, "String({:?})", s.as_str())
1135 } else {
1136 write!(f, "String(arena:{})", self.arena_index())
1137 }
1138 }
1139 TAG_INLINE_VARIANT => {
1140 let ctor = self.inline_variant_ctor_id();
1141 let inner = self.inline_variant_inner();
1142 write!(f, "InlineVariant(ctor:{}, {:?})", ctor, inner)
1143 }
1144 TAG_LIST if self.is_empty_list_immediate() => write!(f, "EmptyList"),
1145 TAG_MAP if self.is_empty_map_immediate() => write!(f, "EmptyMap"),
1146 TAG_VECTOR if self.is_empty_vector_immediate() => write!(f, "EmptyVector"),
1147 _ => write!(f, "{}(arena:{})", self.type_name(), self.arena_index()),
1148 }
1149 }
1150}
1151
1152struct DefaultHasher {
1159 #[cfg(feature = "std")]
1160 inner: std::collections::hash_map::DefaultHasher,
1161 #[cfg(not(feature = "std"))]
1162 state: u64,
1163}
1164
1165impl DefaultHasher {
1166 fn new() -> Self {
1167 #[cfg(feature = "std")]
1168 {
1169 Self {
1170 inner: std::collections::hash_map::DefaultHasher::new(),
1171 }
1172 }
1173 #[cfg(not(feature = "std"))]
1174 {
1175 Self {
1176 state: 0xcbf29ce484222325,
1177 }
1178 }
1179 }
1180}
1181
1182impl Hasher for DefaultHasher {
1183 #[cfg(feature = "std")]
1184 fn finish(&self) -> u64 {
1185 self.inner.finish()
1186 }
1187 #[cfg(feature = "std")]
1188 fn write(&mut self, bytes: &[u8]) {
1189 self.inner.write(bytes)
1190 }
1191
1192 #[cfg(not(feature = "std"))]
1193 fn finish(&self) -> u64 {
1194 self.state
1195 }
1196 #[cfg(not(feature = "std"))]
1197 fn write(&mut self, bytes: &[u8]) {
1198 for &b in bytes {
1199 self.state ^= b as u64;
1200 self.state = self.state.wrapping_mul(0x100000001b3);
1201 }
1202 }
1203}
1204
1205#[derive(Debug, Clone)]
1210pub struct Arena<T: ArenaTypes> {
1211 young_entries: Vec<ArenaEntry<T>>,
1212 yard_entries: Vec<ArenaEntry<T>>,
1213 handoff_entries: Vec<ArenaEntry<T>>,
1214 stable_entries: Vec<ArenaEntry<T>>,
1215 scratch_young: Vec<u32>,
1216 scratch_yard: Vec<u32>,
1217 scratch_handoff: Vec<u32>,
1218 scratch_stable: Vec<u32>,
1219 peak_usage: ArenaUsage,
1220 alloc_space: AllocSpace,
1221 pub type_names: Vec<String>,
1222 pub type_field_names: Vec<Vec<String>>,
1223 pub type_variant_names: Vec<Vec<String>>,
1224 pub type_variant_ctor_ids: Vec<Vec<u32>>,
1225 pub ctor_to_type_variant: Vec<(u32, u16)>,
1226 pub symbol_entries: Vec<ArenaSymbol<T>>,
1227 pub type_aliases: Vec<(String, u32)>,
1229}
1230
1231#[derive(Debug, Clone)]
1232pub enum ArenaEntry<T: ArenaTypes> {
1233 Int(i64),
1236 BigInt(Box<num_bigint::BigInt>),
1240 String(Rc<str>),
1241 List(ArenaList),
1242 Tuple(Vec<NanValue>),
1243 Map(T::Map),
1244 Vector(Vec<NanValue>),
1245 Record {
1246 type_id: u32,
1247 fields: Vec<NanValue>,
1248 },
1249 Variant {
1250 type_id: u32,
1251 variant_id: u16,
1252 fields: Vec<NanValue>,
1253 },
1254 Fn(Rc<T::Fn>),
1255 Builtin(Rc<str>),
1256 Namespace {
1257 name: Rc<str>,
1258 members: Vec<(Rc<str>, NanValue)>,
1259 },
1260 Boxed(NanValue),
1261}
1262
1263#[derive(Debug, Clone, Copy)]
1267pub enum ArenaIntRef<'a> {
1268 Small(i64),
1269 Big(&'a num_bigint::BigInt),
1270}
1271
1272#[derive(Debug, Clone)]
1273pub enum ArenaSymbol<T: ArenaTypes> {
1274 Fn(Rc<T::Fn>),
1275 Builtin(Rc<str>),
1276 Namespace {
1277 name: Rc<str>,
1278 members: Vec<(Rc<str>, NanValue)>,
1279 },
1280 NullaryVariant {
1281 ctor_id: u32,
1282 },
1283}
1284
1285#[derive(Debug, Clone)]
1286pub enum ArenaList {
1287 Flat {
1288 items: Rc<Vec<NanValue>>,
1289 start: usize,
1290 },
1291 Prepend {
1292 head: NanValue,
1293 tail: NanValue,
1294 len: usize,
1295 },
1296 Concat {
1297 left: NanValue,
1298 right: NanValue,
1299 len: usize,
1300 },
1301 Segments {
1302 current: NanValue,
1303 rest: Rc<Vec<NanValue>>,
1304 start: usize,
1305 len: usize,
1306 },
1307}
1308
1309const LIST_APPEND_CHUNK_LIMIT: usize = 128;
1310
1311#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1312pub(crate) enum HeapSpace {
1313 Young = 0,
1314 Yard = 1,
1315 Handoff = 2,
1316 Stable = 3,
1317}
1318
1319#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1320pub enum AllocSpace {
1321 Young,
1322 Yard,
1323 Handoff,
1324}
1325
1326#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1327pub struct ArenaUsage {
1328 pub young: usize,
1329 pub yard: usize,
1330 pub handoff: usize,
1331 pub stable: usize,
1332}
1333
1334impl ArenaUsage {
1335 pub fn total(self) -> usize {
1336 self.young + self.yard + self.handoff + self.stable
1337 }
1338}
1339
1340pub(crate) const HEAP_SPACE_SHIFT: u32 = 30;
1341pub(crate) const HEAP_SPACE_MASK_U32: u32 = 0b11 << HEAP_SPACE_SHIFT;
1342pub(crate) const HEAP_INDEX_MASK_U32: u32 = (1 << HEAP_SPACE_SHIFT) - 1;
1343
1344mod arena;
1345mod compare;
1346mod lists;
1347mod memory;
1348
1349#[cfg(feature = "runtime")]
1354pub type PersistentMap = aver_rt::AverMap<u64, (NanValue, NanValue)>;
1356
1357#[cfg(feature = "runtime")]
1358impl MapLike for aver_rt::AverMap<u64, (NanValue, NanValue)> {
1359 fn new() -> Self {
1360 aver_rt::AverMap::new()
1361 }
1362
1363 fn get(&self, key: &u64) -> Option<&(NanValue, NanValue)> {
1364 aver_rt::AverMap::get(self, key)
1365 }
1366
1367 fn insert(&self, key: u64, value: (NanValue, NanValue)) -> Self {
1368 aver_rt::AverMap::insert(self, key, value)
1369 }
1370
1371 fn insert_owned(self, key: u64, value: (NanValue, NanValue)) -> Self {
1372 aver_rt::AverMap::insert_owned(self, key, value)
1373 }
1374
1375 fn rewrite_values_mut(&mut self, f: impl FnMut(&mut (NanValue, NanValue))) {
1376 self.rewrite_values_in_place(f)
1377 }
1378
1379 fn len(&self) -> usize {
1380 aver_rt::AverMap::len(self)
1381 }
1382
1383 fn is_empty(&self) -> bool {
1384 aver_rt::AverMap::is_empty(self)
1385 }
1386
1387 fn iter(&self) -> impl Iterator<Item = (&u64, &(NanValue, NanValue))> {
1388 aver_rt::AverMap::iter(self)
1389 }
1390
1391 fn values(&self) -> impl Iterator<Item = &(NanValue, NanValue)> {
1392 aver_rt::AverMap::values(self)
1393 }
1394}
1395
1396#[cfg(not(feature = "runtime"))]
1401#[derive(Clone, Debug)]
1403pub struct PersistentMap(alloc::collections::BTreeMap<u64, (NanValue, NanValue)>);
1404
1405#[cfg(not(feature = "runtime"))]
1406impl MapLike for PersistentMap {
1407 fn new() -> Self {
1408 PersistentMap(alloc::collections::BTreeMap::new())
1409 }
1410
1411 fn get(&self, key: &u64) -> Option<&(NanValue, NanValue)> {
1412 self.0.get(key)
1413 }
1414
1415 fn insert(&self, key: u64, value: (NanValue, NanValue)) -> Self {
1416 let mut m = self.0.clone();
1417 m.insert(key, value);
1418 PersistentMap(m)
1419 }
1420
1421 fn rewrite_values_mut(&mut self, mut f: impl FnMut(&mut (NanValue, NanValue))) {
1422 for value in self.0.values_mut() {
1423 f(value);
1424 }
1425 }
1426
1427 fn len(&self) -> usize {
1428 self.0.len()
1429 }
1430
1431 fn is_empty(&self) -> bool {
1432 self.0.is_empty()
1433 }
1434
1435 fn iter(&self) -> impl Iterator<Item = (&u64, &(NanValue, NanValue))> {
1436 self.0.iter()
1437 }
1438
1439 fn values(&self) -> impl Iterator<Item = &(NanValue, NanValue)> {
1440 self.0.values()
1441 }
1442}