use super::{types, values};
#[derive(Debug)]
pub enum IUnOp {
Clz,
Ctz,
Popcnt,
}
#[derive(Debug)]
pub enum FUnOp {
Neg,
Abs,
Ceil,
Floor,
Trunc,
Nearest,
Sqrt,
}
#[derive(Debug)]
pub enum IBinOp {
Add,
Sub,
Mul,
DivS,
DivU,
RemS,
RemU,
And,
Or,
Xor,
Shl,
ShrS,
ShrU,
Rotl,
Rotr,
}
#[derive(Debug)]
pub enum FBinOp {
Add,
Sub,
Mul,
Div,
Min,
Max,
CopySign,
}
#[derive(Debug)]
pub enum ITestOp {
Eqz,
}
#[derive(Debug)]
pub enum IRelOp {
Eq_,
Ne,
LtS,
LtU,
GtS,
GtU,
LeS,
LeU,
GeS,
GeU,
}
#[derive(Debug)]
pub enum FRelOp {
Eq_,
Ne,
Lt,
Gt,
Le,
Ge,
}
#[derive(Debug)]
pub enum ConvertOp {
I32WrapI64,
I64ExtendUI32,
I64ExtendSI32,
Trunc {
from: types::Float,
to: types::Int,
signed: bool,
},
Convert {
from: types::Int,
to: types::Float,
signed: bool,
},
Reinterpret {
from: types::Value,
to: types::Value,
},
F32DemoteF64,
F64PromoteF32,
}
#[derive(Debug)]
pub struct MemOp<T> {
pub align: u32,
pub offset: u32,
pub type_: types::Value,
pub opt: Option<T>,
}
pub type LoadOp = MemOp<(u32, bool)>;
pub type StoreOp = MemOp<u32>;
#[derive(Debug)]
pub enum Instr {
Unreachable, Nop, Block(Vec<types::Value>, Vec<Instr>), Loop(Vec<types::Value>, Vec<Instr>), If(Vec<types::Value>, Vec<Instr>, Vec<Instr>), Br(Index), BrIf(Index), BrTable(Vec<Index>, Index), Return, Call(Index), CallIndirect(Index), Drop_, Select, GetLocal(Index), SetLocal(Index), TeeLocal(Index), GetGlobal(Index), SetGlobal(Index), Load(LoadOp), Store(StoreOp), CurrentMemory, GrowMemory, Const(values::Value), IUnary(types::Int, IUnOp), FUnary(types::Float, FUnOp), IBin(types::Int, IBinOp), FBin(types::Float, FBinOp), ITest(types::Int, ITestOp), IRel(types::Int, IRelOp), FRel(types::Float, FRelOp), Convert(ConvertOp), }
pub type Expr = Vec<Instr>;
#[derive(Debug)]
pub struct Module {
pub(crate) types: Vec<types::Func>,
pub(crate) funcs: Vec<Func>,
pub(crate) tables: Vec<Table>,
pub(crate) memories: Vec<Memory>,
pub(crate) globals: Vec<Global>,
pub(crate) elems: Vec<Segment<Index>>, pub(crate) data: Vec<Segment<u8>>, pub(crate) start: Option<Index>, pub(crate) imports: Vec<Import>,
pub(crate) exports: Vec<Export>,
}
pub type Index = u32;
#[derive(Debug)]
pub struct Func {
pub type_index: Index,
pub locals: Vec<types::Value>,
pub body: Expr,
}
#[derive(Debug)]
pub struct Table {
pub type_: types::Table,
}
#[derive(Debug)]
pub struct Memory {
pub type_: types::Memory,
}
#[derive(Debug)]
pub struct Global {
pub type_: types::Global,
pub value: Expr, }
#[derive(Debug)]
pub struct Segment<T> {
pub index: Index,
pub offset: Expr, pub init: Vec<T>,
}
#[derive(Debug)]
pub struct Export {
pub name: String,
pub desc: ExportDesc,
}
#[derive(Debug)]
pub enum ExportDesc {
Func(Index),
Table(Index),
Memory(Index),
Global(Index),
}
#[derive(Debug)]
pub struct Import {
pub module: String,
pub name: String,
pub desc: ImportDesc,
}
#[derive(Debug)]
pub enum ImportDesc {
Func(Index),
Table(types::Table),
Memory(types::Memory),
Global(types::Global),
}
impl Import {
pub fn type_(&self, module: &Module) -> types::Extern {
match &self.desc {
ImportDesc::Func(idx) => types::Extern::Func(module.types[*idx as usize].clone()),
ImportDesc::Table(t) => types::Extern::Table(t.clone()),
ImportDesc::Memory(t) => types::Extern::Memory(t.clone()),
ImportDesc::Global(t) => types::Extern::Global(t.clone()),
}
}
}
impl Module {
#[cfg(feature = "test")]
pub fn empty() -> Module {
Module {
types: Vec::new(),
funcs: Vec::new(),
tables: Vec::new(),
memories: Vec::new(),
globals: Vec::new(),
elems: Vec::new(),
data: Vec::new(),
start: None,
imports: Vec::new(),
exports: Vec::new(),
}
}
}