use crate::ir::id::{ImportsID, MemoryID};
use crate::ir::module::{AsVec, GetID, LocalOrImport};
use crate::ir::types::{InjectTag, Tag, TagUtils};
use wasmparser::MemoryType;
#[allow(dead_code)]
#[derive(Clone, Debug, Default)]
pub struct Memories {
memories: Vec<Memory>,
pub(crate) recalculate_ids: bool,
}
impl AsVec<Memory> for Memories {
fn as_vec(&self) -> &Vec<Memory> {
&self.memories
}
fn as_vec_mut(&mut self) -> &mut Vec<Memory> {
&mut self.memories
}
}
impl Memories {
pub fn new(memories: Vec<Memory>) -> Self {
Self {
memories,
recalculate_ids: false,
}
}
pub fn iter(&self) -> std::slice::Iter<'_, Memory> {
self.memories.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, Memory> {
self.memories.iter_mut()
}
pub fn get_mem_by_id(&self, mem_id: MemoryID) -> Option<&Memory> {
if *mem_id < self.memories.len() as u32 {
return Some(&self.memories[*mem_id as usize]);
}
None
}
pub fn is_empty(&self) -> bool {
self.memories.is_empty()
}
pub fn get_kind(&self, mem_id: MemoryID) -> &MemKind {
&self.memories[*mem_id as usize].kind
}
pub fn get_mut(&mut self, mem_id: MemoryID) -> Option<&mut Memory> {
if *mem_id < self.memories.len() as u32 {
return Some(&mut self.memories[*mem_id as usize]);
}
None
}
pub fn is_local(&self, mem_id: MemoryID) -> bool {
self.memories[*mem_id as usize].is_local()
}
pub fn is_import(&self, mem_id: MemoryID) -> bool {
self.memories[*mem_id as usize].is_import()
}
pub fn is_deleted(&self, mem_id: MemoryID) -> bool {
self.memories[*mem_id as usize].is_deleted()
}
pub(crate) fn delete(&mut self, mem_id: MemoryID) {
self.recalculate_ids = true;
if *mem_id < self.memories.len() as u32 {
self.memories[*mem_id as usize].delete();
}
}
fn next_id(&self) -> MemoryID {
MemoryID(self.memories.len() as u32)
}
pub(crate) fn add_local_mem(
&mut self,
mut local_mem: LocalMemory,
ty: MemoryType,
tag: InjectTag,
) -> MemoryID {
self.recalculate_ids = true;
let id = self.next_id();
local_mem.mem_id = id;
self.memories.push(Memory {
ty,
kind: MemKind::Local(local_mem),
deleted: false,
tag,
});
id
}
pub(crate) fn add_import_mem(
&mut self,
imp_id: ImportsID,
ty: MemoryType,
imp_mem_id: u32,
tag: InjectTag,
) {
self.recalculate_ids = true;
assert_eq!(*self.next_id(), imp_mem_id);
self.memories.push(Memory {
ty,
kind: MemKind::Import(ImportedMemory {
import_id: imp_id,
import_mem_id: MemoryID(imp_mem_id),
}),
deleted: false,
tag,
});
}
}
#[derive(Clone, Debug)]
pub struct Memory {
pub ty: MemoryType,
pub(crate) kind: MemKind,
pub(crate) deleted: bool,
pub tag: InjectTag,
}
impl GetID for Memory {
fn get_id(&self) -> u32 {
match &self.kind {
MemKind::Import(i) => *i.import_mem_id,
MemKind::Local(l) => *l.mem_id,
}
}
}
impl LocalOrImport for Memory {
fn is_local(&self) -> bool {
matches!(&self.kind, MemKind::Local(_))
}
fn is_import(&self) -> bool {
matches!(&self.kind, MemKind::Import(_))
}
fn is_deleted(&self) -> bool {
self.deleted
}
}
impl TagUtils for Memory {
fn get_or_create_tag(&mut self) -> &mut Tag {
self.tag.get_or_insert_default()
}
fn get_tag(&self) -> &Option<Tag> {
&self.tag
}
}
impl Memory {
pub fn new(ty: MemoryType, kind: MemKind, tag: InjectTag) -> Self {
Self {
ty,
kind,
deleted: false,
tag,
}
}
pub fn kind(&self) -> &MemKind {
&self.kind
}
pub fn unwrap_local(&self) -> &LocalMemory {
self.kind.unwrap_local()
}
pub fn unwrap_local_mut(&mut self) -> &mut LocalMemory {
self.kind.unwrap_local_mut()
}
pub(crate) fn delete(&mut self) {
self.deleted = true;
}
}
#[derive(Clone, Debug)]
pub enum MemKind {
Local(LocalMemory),
Import(ImportedMemory),
}
impl MemKind {
pub fn unwrap_local(&self) -> &LocalMemory {
match &self {
MemKind::Local(l) => l,
MemKind::Import(_) => panic!("Attempting to unwrap an imported memory as a local!!"),
}
}
pub fn unwrap_local_mut(&mut self) -> &mut LocalMemory {
match self {
MemKind::Local(l) => l,
MemKind::Import(_) => panic!("Attempting to unwrap an imported memory as a local!!"),
}
}
}
#[derive(Clone, Debug)]
pub struct LocalMemory {
pub mem_id: MemoryID,
}
#[derive(Clone, Debug)]
pub struct ImportedMemory {
pub import_id: ImportsID, pub(crate) import_mem_id: MemoryID, }