1use super::*;
2
3impl<T: ArenaTypes> Arena<T> {
4 pub fn new() -> Self {
5 Arena {
6 young_entries: Vec::with_capacity(256),
7 yard_entries: Vec::with_capacity(64),
8 handoff_entries: Vec::with_capacity(64),
9 stable_entries: Vec::with_capacity(64),
10 scratch_young: Vec::new(),
11 scratch_yard: Vec::new(),
12 scratch_handoff: Vec::new(),
13 scratch_stable: Vec::new(),
14 peak_usage: ArenaUsage::default(),
15 alloc_space: AllocSpace::Young,
16 type_names: Vec::new(),
17 type_field_names: Vec::new(),
18 type_variant_names: Vec::new(),
19 type_variant_ctor_ids: Vec::new(),
20 ctor_to_type_variant: Vec::new(),
21 symbol_entries: Vec::new(),
22 type_aliases: Vec::new(),
23 }
24 }
25
26 pub fn clone_static(&self) -> Self {
31 Arena {
32 young_entries: Vec::with_capacity(64),
33 yard_entries: Vec::new(),
34 handoff_entries: Vec::new(),
35 stable_entries: self.stable_entries.clone(),
36 scratch_young: Vec::new(),
37 scratch_yard: Vec::new(),
38 scratch_handoff: Vec::new(),
39 scratch_stable: Vec::new(),
40 peak_usage: ArenaUsage::default(),
41 alloc_space: AllocSpace::Young,
42 type_names: self.type_names.clone(),
43 type_field_names: self.type_field_names.clone(),
44 type_variant_names: self.type_variant_names.clone(),
45 type_variant_ctor_ids: self.type_variant_ctor_ids.clone(),
46 ctor_to_type_variant: self.ctor_to_type_variant.clone(),
47 symbol_entries: self.symbol_entries.clone(),
48 type_aliases: self.type_aliases.clone(),
49 }
50 }
51
52 pub fn deep_import(&mut self, value: NanValue, source: &Arena<T>) -> NanValue {
56 if !value.is_nan_boxed() {
58 return value;
59 }
60 let heap_idx = match value.heap_index() {
62 Some(idx) => idx,
63 None => return value, };
65
66 let entry = source.get(heap_idx).clone();
67 match entry {
68 ArenaEntry::Int(i) => NanValue::new_int(i, self),
69 ArenaEntry::BigInt(b) => NanValue::new_big_int(*b, self),
70 ArenaEntry::String(s) => {
71 let idx = self.push(ArenaEntry::String(s));
72 NanValue::new_string(idx)
73 }
74 ArenaEntry::Tuple(items) => {
75 let imported: Vec<NanValue> =
76 items.iter().map(|v| self.deep_import(*v, source)).collect();
77 let idx = self.push_tuple(imported);
78 NanValue::new_tuple(idx)
79 }
80 ArenaEntry::List(_) => {
81 let flat = source.list_to_vec_value(value);
83 let imported: Vec<NanValue> =
84 flat.iter().map(|v| self.deep_import(*v, source)).collect();
85 if imported.is_empty() {
86 NanValue::EMPTY_LIST
87 } else {
88 let rc_items = Rc::new(imported);
89 let idx = self.push(ArenaEntry::List(ArenaList::Flat {
90 items: rc_items,
91 start: 0,
92 }));
93 NanValue::new_list(idx)
94 }
95 }
96 ArenaEntry::Map(map) => {
97 let mut new_map = T::Map::new();
98 for (hash, (k, v)) in map.iter() {
99 let ik = self.deep_import(*k, source);
100 let iv = self.deep_import(*v, source);
101 new_map = new_map.insert(*hash, (ik, iv));
102 }
103 let idx = self.push(ArenaEntry::Map(new_map));
104 NanValue::new_map(idx)
105 }
106 ArenaEntry::Vector(items) => {
107 let imported: Vec<NanValue> =
108 items.iter().map(|v| self.deep_import(*v, source)).collect();
109 let idx = self.push(ArenaEntry::Vector(imported));
110 NanValue::new_vector(idx)
111 }
112 ArenaEntry::Record { type_id, fields } => {
113 let imported: Vec<NanValue> = fields
114 .iter()
115 .map(|v| self.deep_import(*v, source))
116 .collect();
117 let idx = self.push(ArenaEntry::Record {
118 type_id,
119 fields: imported,
120 });
121 NanValue::new_record(idx)
122 }
123 ArenaEntry::Variant {
124 type_id,
125 variant_id,
126 fields,
127 } => {
128 let imported: Vec<NanValue> = fields
129 .iter()
130 .map(|v| self.deep_import(*v, source))
131 .collect();
132 let idx = self.push(ArenaEntry::Variant {
133 type_id,
134 variant_id,
135 fields: imported,
136 });
137 NanValue::new_variant(idx)
138 }
139 ArenaEntry::Boxed(inner) => {
140 let imported = self.deep_import(inner, source);
141 let idx = self.push(ArenaEntry::Boxed(imported));
142 NanValue::encode(value.tag(), ARENA_REF_BIT | (idx as u64))
143 }
144 ArenaEntry::Fn(_) | ArenaEntry::Builtin(_) | ArenaEntry::Namespace { .. } => value,
146 }
147 }
148
149 #[inline]
150 pub fn push(&mut self, entry: ArenaEntry<T>) -> u32 {
151 match &entry {
152 ArenaEntry::Fn(_) | ArenaEntry::Builtin(_) | ArenaEntry::Namespace { .. } => {}
153 _ => {
154 return match self.alloc_space {
155 AllocSpace::Young => {
156 let idx = self.young_entries.len() as u32;
157 self.young_entries.push(entry);
158 self.note_peak_usage();
159 Self::encode_index(HeapSpace::Young, idx)
160 }
161 AllocSpace::Yard => {
162 let idx = self.yard_entries.len() as u32;
163 self.yard_entries.push(entry);
164 self.note_peak_usage();
165 Self::encode_index(HeapSpace::Yard, idx)
166 }
167 AllocSpace::Handoff => {
168 let idx = self.handoff_entries.len() as u32;
169 self.handoff_entries.push(entry);
170 self.note_peak_usage();
171 Self::encode_index(HeapSpace::Handoff, idx)
172 }
173 };
174 }
175 }
176 match entry {
177 ArenaEntry::Fn(f) => self.push_symbol(ArenaSymbol::Fn(f)),
178 ArenaEntry::Builtin(name) => self.push_symbol(ArenaSymbol::Builtin(name)),
179 ArenaEntry::Namespace { name, members } => {
180 self.push_symbol(ArenaSymbol::Namespace { name, members })
181 }
182 _ => unreachable!("non-symbol entry already returned above"),
183 }
184 }
185
186 #[inline]
187 pub fn push_symbol(&mut self, symbol: ArenaSymbol<T>) -> u32 {
188 let idx = self.symbol_entries.len() as u32;
189 self.symbol_entries.push(symbol);
190 idx
191 }
192
193 #[inline]
194 pub fn get(&self, index: u32) -> &ArenaEntry<T> {
195 let (space, raw_index) = Self::decode_index(index);
196 match space {
197 HeapSpace::Young => &self.young_entries[raw_index as usize],
198 HeapSpace::Yard => &self.yard_entries[raw_index as usize],
199 HeapSpace::Handoff => &self.handoff_entries[raw_index as usize],
200 HeapSpace::Stable => &self.stable_entries[raw_index as usize],
201 }
202 }
203
204 #[inline]
205 pub fn get_mut(&mut self, index: u32) -> &mut ArenaEntry<T> {
206 let (space, raw_index) = Self::decode_index(index);
207 match space {
208 HeapSpace::Young => &mut self.young_entries[raw_index as usize],
209 HeapSpace::Yard => &mut self.yard_entries[raw_index as usize],
210 HeapSpace::Handoff => &mut self.handoff_entries[raw_index as usize],
211 HeapSpace::Stable => &mut self.stable_entries[raw_index as usize],
212 }
213 }
214
215 #[inline]
216 pub(crate) fn encode_index(space: HeapSpace, index: u32) -> u32 {
217 ((space as u32) << HEAP_SPACE_SHIFT) | index
218 }
219
220 #[inline]
221 pub(crate) fn encode_yard_index(index: u32) -> u32 {
222 Self::encode_index(HeapSpace::Yard, index)
223 }
224
225 #[inline]
226 pub(crate) fn encode_stable_index(index: u32) -> u32 {
227 Self::encode_index(HeapSpace::Stable, index)
228 }
229
230 #[inline]
231 pub(crate) fn encode_handoff_index(index: u32) -> u32 {
232 Self::encode_index(HeapSpace::Handoff, index)
233 }
234
235 #[inline]
236 pub(crate) fn decode_index(index: u32) -> (HeapSpace, u32) {
237 let space = match (index & HEAP_SPACE_MASK_U32) >> HEAP_SPACE_SHIFT {
238 0 => HeapSpace::Young,
239 1 => HeapSpace::Yard,
240 2 => HeapSpace::Handoff,
241 3 => HeapSpace::Stable,
242 _ => unreachable!("invalid heap space bits"),
243 };
244 (space, index & HEAP_INDEX_MASK_U32)
245 }
246
247 #[inline]
248 pub fn is_stable_index(index: u32) -> bool {
249 matches!(Self::decode_index(index).0, HeapSpace::Stable)
250 }
251
252 #[inline]
253 pub fn is_yard_index_in_region(&self, index: u32, mark: u32) -> bool {
254 let (space, raw_index) = Self::decode_index(index);
255 matches!(space, HeapSpace::Yard)
256 && raw_index >= mark
257 && raw_index < self.yard_entries.len() as u32
258 }
259
260 #[inline]
261 pub fn is_handoff_index_in_region(&self, index: u32, mark: u32) -> bool {
262 let (space, raw_index) = Self::decode_index(index);
263 matches!(space, HeapSpace::Handoff)
264 && raw_index >= mark
265 && raw_index < self.handoff_entries.len() as u32
266 }
267
268 #[inline]
269 pub fn is_young_index_in_region(&self, index: u32, mark: u32) -> bool {
270 let (space, raw_index) = Self::decode_index(index);
271 matches!(space, HeapSpace::Young)
272 && raw_index >= mark
273 && raw_index < self.young_entries.len() as u32
274 }
275
276 #[inline]
277 pub fn young_len(&self) -> usize {
278 self.young_entries.len()
279 }
280
281 #[inline]
282 pub fn yard_len(&self) -> usize {
283 self.yard_entries.len()
284 }
285
286 #[inline]
287 pub fn handoff_len(&self) -> usize {
288 self.handoff_entries.len()
289 }
290
291 #[inline]
292 pub fn stable_len(&self) -> usize {
293 self.stable_entries.len()
294 }
295
296 #[inline]
297 pub fn usage(&self) -> ArenaUsage {
298 ArenaUsage {
299 young: self.young_entries.len(),
300 yard: self.yard_entries.len(),
301 handoff: self.handoff_entries.len(),
302 stable: self.stable_entries.len(),
303 }
304 }
305
306 #[inline]
307 pub fn peak_usage(&self) -> ArenaUsage {
308 self.peak_usage
309 }
310
311 #[inline]
312 pub(crate) fn note_peak_usage(&mut self) {
313 let usage = self.usage();
314 self.peak_usage.young = self.peak_usage.young.max(usage.young);
315 self.peak_usage.yard = self.peak_usage.yard.max(usage.yard);
316 self.peak_usage.handoff = self.peak_usage.handoff.max(usage.handoff);
317 self.peak_usage.stable = self.peak_usage.stable.max(usage.stable);
318 }
319
320 #[inline]
321 pub(crate) fn take_u32_scratch(slot: &mut Vec<u32>, len: usize) -> Vec<u32> {
322 let mut scratch = core::mem::take(slot);
323 scratch.clear();
324 scratch.resize(len, u32::MAX);
325 scratch
326 }
327
328 #[inline]
329 pub(crate) fn recycle_u32_scratch(slot: &mut Vec<u32>, mut scratch: Vec<u32>) {
330 scratch.clear();
331 *slot = scratch;
332 }
333
334 #[inline]
335 pub fn is_frame_local_index(
336 &self,
337 index: u32,
338 arena_mark: u32,
339 yard_mark: u32,
340 handoff_mark: u32,
341 ) -> bool {
342 self.is_young_index_in_region(index, arena_mark)
343 || self.is_yard_index_in_region(index, yard_mark)
344 || self.is_handoff_index_in_region(index, handoff_mark)
345 }
346
347 pub fn with_alloc_space<R>(
348 &mut self,
349 space: AllocSpace,
350 f: impl FnOnce(&mut Arena<T>) -> R,
351 ) -> R {
352 let prev = self.alloc_space;
353 self.alloc_space = space;
354 let out = f(self);
355 self.alloc_space = prev;
356 out
357 }
358
359 pub fn push_inheriting_source_space(&mut self, entry: ArenaEntry<T>, source: NanValue) -> u32 {
363 if let Some(index) = source.heap_index() {
364 let (space, _) = Self::decode_index(index);
365 let target = match space {
366 HeapSpace::Yard => Some(AllocSpace::Yard),
367 HeapSpace::Handoff => Some(AllocSpace::Handoff),
368 _ => None,
369 };
370 if let Some(target) = target {
371 let prev = self.alloc_space;
372 self.alloc_space = target;
373 let idx = self.push(entry);
374 self.alloc_space = prev;
375 return idx;
376 }
377 }
378 self.push(entry)
379 }
380
381 pub fn push_i64(&mut self, val: i64) -> u32 {
384 self.push(ArenaEntry::Int(val))
385 }
386 pub fn push_bigint(&mut self, val: num_bigint::BigInt) -> u32 {
393 match i64::try_from(&val) {
394 Ok(n) => self.push(ArenaEntry::Int(n)),
395 Err(_) => self.push(ArenaEntry::BigInt(Box::new(val))),
396 }
397 }
398 pub fn push_string(&mut self, s: &str) -> u32 {
399 self.push(ArenaEntry::String(Rc::from(s)))
400 }
401 pub fn push_boxed(&mut self, val: NanValue) -> u32 {
402 self.push(ArenaEntry::Boxed(val))
403 }
404 pub fn push_record(&mut self, type_id: u32, fields: Vec<NanValue>) -> u32 {
405 self.push(ArenaEntry::Record { type_id, fields })
406 }
407 pub fn push_variant(&mut self, type_id: u32, variant_id: u16, fields: Vec<NanValue>) -> u32 {
408 self.push(ArenaEntry::Variant {
409 type_id,
410 variant_id,
411 fields,
412 })
413 }
414 pub fn push_list(&mut self, items: Vec<NanValue>) -> u32 {
415 self.push(ArenaEntry::List(ArenaList::Flat {
416 items: Rc::new(items),
417 start: 0,
418 }))
419 }
420 pub fn push_map(&mut self, map: T::Map) -> u32 {
421 self.push(ArenaEntry::Map(map))
422 }
423 pub fn push_tuple(&mut self, items: Vec<NanValue>) -> u32 {
424 self.push(ArenaEntry::Tuple(items))
425 }
426 pub fn push_vector(&mut self, items: Vec<NanValue>) -> u32 {
427 self.push(ArenaEntry::Vector(items))
428 }
429 pub fn push_fn(&mut self, f: Rc<T::Fn>) -> u32 {
430 self.push_symbol(ArenaSymbol::Fn(f))
431 }
432 pub fn push_builtin(&mut self, name: &str) -> u32 {
433 self.push_symbol(ArenaSymbol::Builtin(Rc::from(name)))
434 }
435 pub fn push_nullary_variant_symbol(&mut self, ctor_id: u32) -> u32 {
436 self.push_symbol(ArenaSymbol::NullaryVariant { ctor_id })
437 }
438
439 pub fn get_i64(&self, index: u32) -> i64 {
442 match self.get(index) {
443 ArenaEntry::Int(i) => *i,
444 _ => panic!("Arena: expected Int at {}", index),
445 }
446 }
447 pub fn get_bigint(&self, index: u32) -> &num_bigint::BigInt {
449 match self.get(index) {
450 ArenaEntry::BigInt(b) => b,
451 _ => panic!("Arena: expected BigInt at {}", index),
452 }
453 }
454 pub fn int_ref_at(&self, index: u32) -> ArenaIntRef<'_> {
458 match self.get(index) {
459 ArenaEntry::Int(i) => ArenaIntRef::Small(*i),
460 ArenaEntry::BigInt(b) => ArenaIntRef::Big(b),
461 other => panic!(
462 "Arena: expected an integer at {} but found {:?}",
463 index, other
464 ),
465 }
466 }
467 pub fn get_string(&self, index: u32) -> &str {
468 match self.get(index) {
469 ArenaEntry::String(s) => s,
470 other => panic!("Arena: expected String at {} but found {:?}", index, other),
471 }
472 }
473 pub fn get_string_value(&self, value: NanValue) -> NanString<'_> {
474 if let Some(s) = value.small_string() {
475 s
476 } else {
477 NanString::Borrowed(self.get_string(value.arena_index()))
478 }
479 }
480 pub fn get_boxed(&self, index: u32) -> NanValue {
481 match self.get(index) {
482 ArenaEntry::Boxed(v) => *v,
483 _ => panic!("Arena: expected Boxed at {}", index),
484 }
485 }
486 pub fn get_record(&self, index: u32) -> (u32, &[NanValue]) {
487 match self.get(index) {
488 ArenaEntry::Record { type_id, fields } => (*type_id, fields),
489 _ => panic!("Arena: expected Record at {}", index),
490 }
491 }
492 pub fn get_variant(&self, index: u32) -> (u32, u16, &[NanValue]) {
493 match self.get(index) {
494 ArenaEntry::Variant {
495 type_id,
496 variant_id,
497 fields,
498 } => (*type_id, *variant_id, fields),
499 other => panic!("Arena: expected Variant at {} but found {:?}", index, other),
500 }
501 }
502 pub fn get_list(&self, index: u32) -> &ArenaList {
503 match self.get(index) {
504 ArenaEntry::List(items) => items,
505 _ => panic!("Arena: expected List at {}", index),
506 }
507 }
508 pub fn get_tuple(&self, index: u32) -> &[NanValue] {
509 match self.get(index) {
510 ArenaEntry::Tuple(items) => items,
511 _ => panic!("Arena: expected Tuple at {}", index),
512 }
513 }
514 pub fn get_vector(&self, index: u32) -> &[NanValue] {
515 match self.get(index) {
516 ArenaEntry::Vector(items) => items,
517 _ => panic!("Arena: expected Vector at {}", index),
518 }
519 }
520 pub fn get_vector_mut(&mut self, index: u32) -> &mut Vec<NanValue> {
521 match self.get_mut(index) {
522 ArenaEntry::Vector(items) => items,
523 _ => panic!("Arena: expected Vector at {}", index),
524 }
525 }
526 pub fn vector_ref_value(&self, value: NanValue) -> &[NanValue] {
527 if value.is_empty_vector_immediate() {
528 return &[];
529 }
530 self.get_vector(value.arena_index())
531 }
532 pub fn clone_vector_value(&self, value: NanValue) -> Vec<NanValue> {
533 if value.is_empty_vector_immediate() {
534 Vec::new()
535 } else {
536 self.get_vector(value.arena_index()).to_vec()
537 }
538 }
539 pub fn take_vector_value(&mut self, value: NanValue) -> Vec<NanValue> {
541 if value.is_empty_vector_immediate() {
542 Vec::new()
543 } else {
544 let index = value.arena_index();
545 std::mem::take(self.get_vector_mut(index))
546 }
547 }
548 pub fn get_map(&self, index: u32) -> &T::Map {
549 match self.get(index) {
550 ArenaEntry::Map(map) => map,
551 _ => panic!("Arena: expected Map at {}", index),
552 }
553 }
554 pub fn get_map_mut(&mut self, index: u32) -> &mut T::Map {
555 match self.get_mut(index) {
556 ArenaEntry::Map(map) => map,
557 _ => panic!("Arena: expected Map at {}", index),
558 }
559 }
560 pub fn map_ref_value(&self, map: NanValue) -> &T::Map {
561 if map.is_empty_map_immediate() {
562 use core::sync::atomic::{AtomicPtr, Ordering as AtomicOrdering};
565 static EMPTY_MAP_PTR: AtomicPtr<()> = AtomicPtr::new(core::ptr::null_mut());
566
567 let ptr = EMPTY_MAP_PTR.load(AtomicOrdering::Acquire);
568 if !ptr.is_null() {
569 return unsafe { &*(ptr as *const T::Map) };
571 }
572 let boxed = alloc::boxed::Box::new(T::Map::new());
573 let leaked: &'static T::Map = alloc::boxed::Box::leak(boxed);
574 let new_ptr = leaked as *const T::Map as *mut ();
575 EMPTY_MAP_PTR.store(new_ptr, AtomicOrdering::Release);
577 leaked
578 } else {
579 self.get_map(map.arena_index())
580 }
581 }
582 pub fn clone_map_value(&self, map: NanValue) -> T::Map {
583 if map.is_empty_map_immediate() {
584 T::Map::new()
585 } else {
586 self.get_map(map.arena_index()).clone()
587 }
588 }
589 pub fn take_map_value(&mut self, map: NanValue) -> T::Map {
593 if map.is_empty_map_immediate() {
594 T::Map::new()
595 } else {
596 let index = map.arena_index();
597 std::mem::replace(self.get_map_mut(index), T::Map::new())
598 }
599 }
600 pub fn get_fn(&self, index: u32) -> &T::Fn {
601 match &self.symbol_entries[index as usize] {
602 ArenaSymbol::Fn(f) => f,
603 _ => panic!("Arena: expected Fn symbol at {}", index),
604 }
605 }
606 pub fn get_fn_rc(&self, index: u32) -> &Rc<T::Fn> {
607 match &self.symbol_entries[index as usize] {
608 ArenaSymbol::Fn(f) => f,
609 _ => panic!("Arena: expected Fn symbol at {}", index),
610 }
611 }
612 pub fn get_builtin(&self, index: u32) -> &str {
613 match &self.symbol_entries[index as usize] {
614 ArenaSymbol::Builtin(s) => s,
615 _ => panic!("Arena: expected Builtin symbol at {}", index),
616 }
617 }
618 pub fn get_namespace(&self, index: u32) -> (&str, &[(Rc<str>, NanValue)]) {
619 match &self.symbol_entries[index as usize] {
620 ArenaSymbol::Namespace { name, members } => (name, members),
621 _ => panic!("Arena: expected Namespace symbol at {}", index),
622 }
623 }
624 pub fn get_nullary_variant_ctor(&self, index: u32) -> u32 {
625 match &self.symbol_entries[index as usize] {
626 ArenaSymbol::NullaryVariant { ctor_id } => *ctor_id,
627 _ => panic!("Arena: expected NullaryVariant symbol at {}", index),
628 }
629 }
630
631 pub fn register_record_type(&mut self, name: &str, field_names: Vec<String>) -> u32 {
634 let id = self.type_names.len() as u32;
635 self.type_names.push(String::from(name));
636 self.type_field_names.push(field_names);
637 self.type_variant_names.push(Vec::new());
638 self.type_variant_ctor_ids.push(Vec::new());
639 id
640 }
641
642 pub fn register_sum_type(&mut self, name: &str, variant_names: Vec<String>) -> u32 {
643 let id = self.type_names.len() as u32;
644 self.type_names.push(String::from(name));
645 self.type_field_names.push(Vec::new());
646 let ctor_ids: Vec<u32> = (0..variant_names.len())
647 .map(|variant_idx| {
648 let ctor_id = self.ctor_to_type_variant.len() as u32;
649 self.ctor_to_type_variant.push((id, variant_idx as u16));
650 ctor_id
651 })
652 .collect();
653 self.type_variant_names.push(variant_names);
654 self.type_variant_ctor_ids.push(ctor_ids);
655 id
656 }
657
658 pub fn register_variant_name(&mut self, type_id: u32, variant_name: String) -> u16 {
659 let variants = &mut self.type_variant_names[type_id as usize];
660 let variant_id = variants.len() as u16;
661 variants.push(variant_name);
662
663 let ctor_id = self.ctor_to_type_variant.len() as u32;
664 self.ctor_to_type_variant.push((type_id, variant_id));
665 self.type_variant_ctor_ids[type_id as usize].push(ctor_id);
666
667 variant_id
668 }
669
670 pub fn get_type_name(&self, type_id: u32) -> &str {
671 &self.type_names[type_id as usize]
672 }
673 pub fn type_count(&self) -> u32 {
674 self.type_names.len() as u32
675 }
676 pub fn get_field_names(&self, type_id: u32) -> &[String] {
677 &self.type_field_names[type_id as usize]
678 }
679 pub fn get_variant_name(&self, type_id: u32, variant_id: u16) -> &str {
680 &self.type_variant_names[type_id as usize][variant_id as usize]
681 }
682 pub fn register_type_alias(&mut self, alias: &str, type_id: u32) {
683 self.type_aliases.push((alias.to_string(), type_id));
684 }
685
686 pub fn find_type_id(&self, name: &str) -> Option<u32> {
687 self.type_names
688 .iter()
689 .position(|n| n == name)
690 .map(|i| i as u32)
691 .or_else(|| {
692 self.type_aliases
693 .iter()
694 .find(|(alias, _)| alias == name)
695 .map(|(_, id)| *id)
696 })
697 }
698 pub fn find_variant_id(&self, type_id: u32, variant_name: &str) -> Option<u16> {
699 self.type_variant_names
700 .get(type_id as usize)?
701 .iter()
702 .position(|n| n == variant_name)
703 .map(|i| i as u16)
704 }
705
706 pub fn find_ctor_id(&self, type_id: u32, variant_id: u16) -> Option<u32> {
707 self.type_variant_ctor_ids
708 .get(type_id as usize)?
709 .get(variant_id as usize)
710 .copied()
711 }
712
713 pub fn get_ctor_parts(&self, ctor_id: u32) -> (u32, u16) {
714 self.ctor_to_type_variant
715 .get(ctor_id as usize)
716 .copied()
717 .unwrap_or_else(|| panic!("Arena: expected ctor id {} to be registered", ctor_id))
718 }
719
720 pub fn len(&self) -> usize {
721 self.young_entries.len()
722 + self.yard_entries.len()
723 + self.handoff_entries.len()
724 + self.stable_entries.len()
725 }
726 pub fn is_empty(&self) -> bool {
727 self.young_entries.is_empty()
728 && self.yard_entries.is_empty()
729 && self.handoff_entries.is_empty()
730 && self.stable_entries.is_empty()
731 }
732}
733
734impl<T: ArenaTypes> Default for Arena<T> {
735 fn default() -> Self {
736 Self::new()
737 }
738}