use alloc::string::String;
use alloc::vec;
use alloc::vec::Vec;
use core::iter;
use crate::core::indices::TypeIdx;
use crate::core::reader::span::Span;
use crate::core::reader::types::export::Export;
use crate::core::reader::types::global::Global;
use crate::core::reader::types::{MemType, TableType, ValType};
use crate::core::sidetable::Sidetable;
use crate::execution::value::{Ref, Value};
use crate::RefType;
pub struct Store {
pub funcs: Vec<FuncInst>,
pub mems: Vec<MemInst>,
pub globals: Vec<GlobalInst>,
pub data: Vec<DataInst>,
pub tables: Vec<TableInst>,
pub elements: Vec<ElemInst>,
pub passive_elem_indexes: Vec<usize>,
pub exports: Vec<Export>,
}
#[derive(Debug)]
pub enum FuncInst {
Local(LocalFuncInst),
Imported(ImportedFuncInst),
}
#[derive(Debug)]
pub struct LocalFuncInst {
pub ty: TypeIdx,
pub locals: Vec<ValType>,
pub code_expr: Span,
pub sidetable: Sidetable,
}
#[derive(Debug)]
pub struct ImportedFuncInst {
pub ty: TypeIdx,
pub module_name: String,
pub function_name: String,
}
impl FuncInst {
pub fn ty(&self) -> TypeIdx {
match self {
FuncInst::Local(f) => f.ty,
FuncInst::Imported(f) => f.ty,
}
}
pub fn try_into_local(&self) -> Option<&LocalFuncInst> {
match self {
FuncInst::Local(f) => Some(f),
FuncInst::Imported(_) => None,
}
}
pub fn try_into_imported(&self) -> Option<&ImportedFuncInst> {
match self {
FuncInst::Local(_) => None,
FuncInst::Imported(f) => Some(f),
}
}
}
#[derive(Clone, Debug)]
pub struct ElemInst {
pub ty: RefType,
pub references: Vec<Ref>,
}
impl ElemInst {
pub fn len(&self) -> usize {
self.references.len()
}
pub fn is_empty(&self) -> bool {
self.references.is_empty()
}
}
#[derive(Debug)]
pub struct TableInst {
pub ty: TableType,
pub elem: Vec<Ref>,
}
impl TableInst {
pub fn len(&self) -> usize {
self.elem.len()
}
pub fn is_empty(&self) -> bool {
self.elem.is_empty()
}
pub fn new(ty: TableType) -> Self {
Self {
ty,
elem: vec![Ref::default_from_ref_type(ty.et); ty.lim.min as usize],
}
}
}
pub struct MemInst {
#[allow(warnings)]
pub ty: MemType,
pub data: Vec<u8>,
}
impl MemInst {
pub fn new(ty: MemType) -> Self {
let initial_size = (crate::Limits::MEM_PAGE_SIZE as usize) * ty.limits.min as usize;
Self {
ty,
data: vec![0u8; initial_size],
}
}
pub fn grow(&mut self, delta_pages: usize) {
self.data
.extend(iter::repeat(0).take(delta_pages * (crate::Limits::MEM_PAGE_SIZE as usize)))
}
pub fn size(&self) -> usize {
self.data.len() / (crate::Limits::MEM_PAGE_SIZE as usize)
}
}
pub struct GlobalInst {
pub global: Global,
pub value: Value,
}
pub struct DataInst {
pub data: Vec<u8>,
}