1use super::{AsContext, AsContextMut, Stored};
2use crate::{
3 collections::arena::ArenaIndex,
4 core::CoreGlobal,
5 errors::GlobalError,
6 GlobalType,
7 Mutability,
8 Val,
9};
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
13pub struct GlobalIdx(u32);
14
15impl ArenaIndex for GlobalIdx {
16 fn into_usize(self) -> usize {
17 self.0 as usize
18 }
19
20 fn from_usize(value: usize) -> Self {
21 let value = value.try_into().unwrap_or_else(|error| {
22 panic!("index {value} is out of bounds as global index: {error}")
23 });
24 Self(value)
25 }
26}
27
28#[derive(Debug, Copy, Clone)]
30#[repr(transparent)]
31pub struct Global(Stored<GlobalIdx>);
32
33impl Global {
34 pub(super) fn from_inner(stored: Stored<GlobalIdx>) -> Self {
42 Self(stored)
43 }
44
45 pub(super) fn as_inner(&self) -> &Stored<GlobalIdx> {
47 &self.0
48 }
49
50 pub fn new(mut ctx: impl AsContextMut, initial_value: Val, mutability: Mutability) -> Self {
52 ctx.as_context_mut()
53 .store
54 .inner
55 .alloc_global(CoreGlobal::new(initial_value.into(), mutability))
56 }
57
58 pub fn ty(&self, ctx: impl AsContext) -> GlobalType {
60 ctx.as_context().store.inner.resolve_global(self).ty()
61 }
62
63 pub fn set(&self, mut ctx: impl AsContextMut, new_value: Val) -> Result<(), GlobalError> {
74 ctx.as_context_mut()
75 .store
76 .inner
77 .resolve_global_mut(self)
78 .set(new_value.into())
79 }
80
81 pub fn get(&self, ctx: impl AsContext) -> Val {
87 ctx.as_context()
88 .store
89 .inner
90 .resolve_global(self)
91 .get()
92 .into()
93 }
94}