Add serde serialization support for the full clif ir
This commit is contained in:
@@ -781,6 +781,86 @@ impl<'f> DoubleEndedIterator for Insts<'f> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "enable-serde")]
|
||||
mod serde {
|
||||
use ::serde::de::{Deserializer, Error, SeqAccess, Visitor};
|
||||
use ::serde::ser::{SerializeSeq, Serializer};
|
||||
use ::serde::{Deserialize, Serialize};
|
||||
use core::convert::TryFrom;
|
||||
use core::fmt;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl Serialize for Layout {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let size = self.blocks().count() * 2
|
||||
+ self
|
||||
.blocks()
|
||||
.map(|block| self.block_insts(block).count())
|
||||
.sum::<usize>();
|
||||
let mut seq = serializer.serialize_seq(Some(size))?;
|
||||
for block in self.blocks() {
|
||||
seq.serialize_element(&block)?;
|
||||
seq.serialize_element(&u32::try_from(self.block_insts(block).count()).unwrap())?;
|
||||
for inst in self.block_insts(block) {
|
||||
seq.serialize_element(&inst)?;
|
||||
}
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Layout {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_seq(LayoutVisitor {
|
||||
marker: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct LayoutVisitor {
|
||||
marker: PhantomData<fn() -> Layout>,
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for LayoutVisitor {
|
||||
type Value = Layout;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "a `cranelift_codegen::ir::Layout`")
|
||||
}
|
||||
|
||||
fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: SeqAccess<'de>,
|
||||
{
|
||||
let mut layout = Layout::new();
|
||||
|
||||
while let Some(block) = access.next_element::<Block>()? {
|
||||
layout.append_block(block);
|
||||
|
||||
let count = access
|
||||
.next_element::<u32>()?
|
||||
.ok_or_else(|| Error::missing_field("count"))?;
|
||||
for _ in 0..count {
|
||||
let inst = access
|
||||
.next_element::<Inst>()?
|
||||
.ok_or_else(|| Error::missing_field("inst"))?;
|
||||
layout.append_inst(inst, block);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Layout;
|
||||
|
||||
Reference in New Issue
Block a user