use std::{marker::PhantomData, num::NonZeroUsize};
use wasmer_types::StoreId;
use crate::jsc::vm::{VMFunctionEnvironment, VMGlobal};
use super::InternalStoreHandle;
pub trait StoreObject: Sized {
fn list(store: &StoreObjects) -> &Vec<Self>;
fn list_mut(store: &mut StoreObjects) -> &mut Vec<Self>;
}
macro_rules! impl_store_object {
($($field:ident => $ty:ty,)*) => {
$(
impl StoreObject for $ty {
fn list(store: &StoreObjects) -> &Vec<Self> {
&store.$field
}
fn list_mut(store: &mut StoreObjects) -> &mut Vec<Self> {
&mut store.$field
}
}
)*
};
}
impl_store_object! {
globals => VMGlobal,
function_environments => VMFunctionEnvironment,
}
#[derive(Default, Debug)]
pub struct StoreObjects {
id: StoreId,
globals: Vec<VMGlobal>,
function_environments: Vec<VMFunctionEnvironment>,
}
impl StoreObjects {
pub fn id(&self) -> StoreId {
self.id
}
pub fn set_id(&mut self, id: StoreId) {
self.id = id;
}
pub fn get_2_mut<T: StoreObject>(
&mut self,
a: InternalStoreHandle<T>,
b: InternalStoreHandle<T>,
) -> (&mut T, &mut T) {
assert_ne!(a.index(), b.index());
let list = T::list_mut(self);
if a.index() < b.index() {
let (low, high) = list.split_at_mut(b.index());
(&mut low[a.index()], &mut high[0])
} else {
let (low, high) = list.split_at_mut(a.index());
(&mut high[0], &mut low[a.index()])
}
}
pub fn iter_globals<'a>(&'a self) -> core::slice::Iter<'a, VMGlobal> {
self.globals.iter()
}
pub fn as_u128_globals(&self) -> Vec<u128> {
vec![]
}
pub fn set_global_unchecked(&self, idx: usize, new_val: u128) {
assert!(idx < self.globals.len());
}
}
impl crate::StoreObjects {
pub fn into_jsc(self) -> crate::backend::jsc::store::StoreObjects {
match self {
Self::Jsc(s) => s,
_ => panic!("Not a `jsc` store!"),
}
}
pub fn as_jsc(&self) -> &crate::backend::jsc::store::StoreObjects {
match self {
Self::Jsc(s) => s,
_ => panic!("Not a `jsc` store!"),
}
}
pub fn as_jsc_mut(&mut self) -> &mut crate::backend::jsc::store::StoreObjects {
match self {
Self::Jsc(s) => s,
_ => panic!("Not a `jsc` store!"),
}
}
}