use crate::entity::entity_impl;
use core::fmt;
use core::u32;
#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Block(u32);
entity_impl!(Block, "block");
impl Block {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Value(u32);
entity_impl!(Value, "v");
impl Value {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX / 2 {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Inst(u32);
entity_impl!(Inst, "inst");
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct StackSlot(u32);
entity_impl!(StackSlot, "ss");
impl StackSlot {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct DynamicStackSlot(u32);
entity_impl!(DynamicStackSlot, "dss");
impl DynamicStackSlot {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct DynamicType(u32);
entity_impl!(DynamicType, "dt");
impl DynamicType {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct GlobalValue(u32);
entity_impl!(GlobalValue, "gv");
impl GlobalValue {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Constant(u32);
entity_impl!(Constant, "const");
impl Constant {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Immediate(u32);
entity_impl!(Immediate, "imm");
impl Immediate {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct JumpTable(u32);
entity_impl!(JumpTable, "jt");
impl JumpTable {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct FuncRef(u32);
entity_impl!(FuncRef, "fn");
impl FuncRef {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct UserExternalNameRef(u32);
entity_impl!(UserExternalNameRef, "userextname");
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct SigRef(u32);
entity_impl!(SigRef, "sig");
impl SigRef {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Heap(u32);
entity_impl!(Heap, "heap");
impl Heap {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct Table(u32);
entity_impl!(Table, "table");
impl Table {
pub fn with_number(n: u32) -> Option<Self> {
if n < u32::MAX {
Some(Self(n))
} else {
None
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub enum AnyEntity {
Function,
Block(Block),
Inst(Inst),
Value(Value),
StackSlot(StackSlot),
DynamicStackSlot(DynamicStackSlot),
DynamicType(DynamicType),
GlobalValue(GlobalValue),
JumpTable(JumpTable),
Constant(Constant),
FuncRef(FuncRef),
SigRef(SigRef),
Heap(Heap),
Table(Table),
StackLimit,
}
impl fmt::Display for AnyEntity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::Function => write!(f, "function"),
Self::Block(r) => r.fmt(f),
Self::Inst(r) => r.fmt(f),
Self::Value(r) => r.fmt(f),
Self::StackSlot(r) => r.fmt(f),
Self::DynamicStackSlot(r) => r.fmt(f),
Self::DynamicType(r) => r.fmt(f),
Self::GlobalValue(r) => r.fmt(f),
Self::JumpTable(r) => r.fmt(f),
Self::Constant(r) => r.fmt(f),
Self::FuncRef(r) => r.fmt(f),
Self::SigRef(r) => r.fmt(f),
Self::Heap(r) => r.fmt(f),
Self::Table(r) => r.fmt(f),
Self::StackLimit => write!(f, "stack_limit"),
}
}
}
impl fmt::Debug for AnyEntity {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
(self as &dyn fmt::Display).fmt(f)
}
}
impl From<Block> for AnyEntity {
fn from(r: Block) -> Self {
Self::Block(r)
}
}
impl From<Inst> for AnyEntity {
fn from(r: Inst) -> Self {
Self::Inst(r)
}
}
impl From<Value> for AnyEntity {
fn from(r: Value) -> Self {
Self::Value(r)
}
}
impl From<StackSlot> for AnyEntity {
fn from(r: StackSlot) -> Self {
Self::StackSlot(r)
}
}
impl From<DynamicStackSlot> for AnyEntity {
fn from(r: DynamicStackSlot) -> Self {
Self::DynamicStackSlot(r)
}
}
impl From<DynamicType> for AnyEntity {
fn from(r: DynamicType) -> Self {
Self::DynamicType(r)
}
}
impl From<GlobalValue> for AnyEntity {
fn from(r: GlobalValue) -> Self {
Self::GlobalValue(r)
}
}
impl From<JumpTable> for AnyEntity {
fn from(r: JumpTable) -> Self {
Self::JumpTable(r)
}
}
impl From<Constant> for AnyEntity {
fn from(r: Constant) -> Self {
Self::Constant(r)
}
}
impl From<FuncRef> for AnyEntity {
fn from(r: FuncRef) -> Self {
Self::FuncRef(r)
}
}
impl From<SigRef> for AnyEntity {
fn from(r: SigRef) -> Self {
Self::SigRef(r)
}
}
impl From<Heap> for AnyEntity {
fn from(r: Heap) -> Self {
Self::Heap(r)
}
}
impl From<Table> for AnyEntity {
fn from(r: Table) -> Self {
Self::Table(r)
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::string::ToString;
use core::u32;
#[test]
fn value_with_number() {
assert_eq!(Value::with_number(0).unwrap().to_string(), "v0");
assert_eq!(Value::with_number(1).unwrap().to_string(), "v1");
assert_eq!(Value::with_number(u32::MAX / 2), None);
assert!(Value::with_number(u32::MAX / 2 - 1).is_some());
}
#[test]
fn memory() {
use crate::packed_option::PackedOption;
use core::mem;
assert_eq!(
mem::size_of::<Value>(),
mem::size_of::<PackedOption<Value>>()
);
}
#[test]
fn constant_with_number() {
assert_eq!(Constant::with_number(0).unwrap().to_string(), "const0");
assert_eq!(Constant::with_number(1).unwrap().to_string(), "const1");
}
}