1use serde::{Deserialize, Serialize};
38
39use super::*;
40use crate::bitvector::BV;
41
42#[derive(Clone, Serialize, Deserialize)]
43enum SInstr<A> {
44 Decl(A, Ty<A>),
45 Init(A, Ty<A>, Exp<A>),
46 Jump(Exp<A>, usize, String),
47 Goto(usize),
48 Copy(Loc<A>, Exp<A>),
49 Monomorphize(A),
50 Call(Loc<A>, bool, A, Vec<Exp<A>>),
51 Failure,
52 Arbitrary,
53 End,
54}
55
56impl<A> SInstr<A> {
57 fn into_instr<B: BV>(self) -> Instr<A, B> {
58 use SInstr::*;
59 match self {
60 Decl(id, ty) => Instr::Decl(id, ty),
61 Init(id, ty, exp) => Instr::Init(id, ty, exp),
62 Jump(exp, target, info) => Instr::Jump(exp, target, info),
63 Goto(target) => Instr::Goto(target),
64 Copy(loc, exp) => Instr::Copy(loc, exp),
65 Monomorphize(id) => Instr::Monomorphize(id),
66 Call(loc, ext, id, args) => Instr::Call(loc, ext, id, args),
67 Failure => Instr::Failure,
68 Arbitrary => Instr::Arbitrary,
69 End => Instr::End,
70 }
71 }
72
73 fn from_instr<B: BV>(instr: Instr<A, B>) -> Option<Self> {
74 use Instr::*;
75 Some(match instr {
76 Decl(id, ty) => SInstr::Decl(id, ty),
77 Init(id, ty, exp) => SInstr::Init(id, ty, exp),
78 Jump(exp, target, info) => SInstr::Jump(exp, target, info),
79 Goto(target) => SInstr::Goto(target),
80 Copy(loc, exp) => SInstr::Copy(loc, exp),
81 Monomorphize(id) => SInstr::Monomorphize(id),
82 Call(loc, ext, id, args) => SInstr::Call(loc, ext, id, args),
83 Failure => SInstr::Failure,
84 Arbitrary => SInstr::Arbitrary,
85 End => SInstr::End,
86 _ => return None,
87 })
88 }
89}
90
91#[derive(Clone, Serialize, Deserialize)]
92enum SDef<A> {
93 Register(A, Ty<A>),
94 Let(Vec<(A, Ty<A>)>, Vec<SInstr<A>>),
95 Enum(A, Vec<A>),
96 Struct(A, Vec<(A, Ty<A>)>),
97 Union(A, Vec<(A, Ty<A>)>),
98 Val(A, Vec<Ty<A>>, Ty<A>),
99 Extern(A, String, Vec<Ty<A>>, Ty<A>),
100 Fn(A, Vec<A>, Vec<SInstr<A>>),
101}
102
103impl<A> SDef<A> {
104 fn into_def<B: BV>(self) -> Def<A, B> {
105 use SDef::*;
106 match self {
107 Register(id, ty) => Def::Register(id, ty),
108 Let(bindings, mut setup) => Def::Let(bindings, setup.drain(..).map(SInstr::into_instr).collect()),
109 Enum(id, elems) => Def::Enum(id, elems),
110 Struct(id, members) => Def::Struct(id, members),
111 Union(id, ctors) => Def::Union(id, ctors),
112 Val(id, arg_tys, ret_ty) => Def::Val(id, arg_tys, ret_ty),
113 Extern(id, ext, arg_tys, ret_ty) => Def::Extern(id, ext, arg_tys, ret_ty),
114 Fn(id, args, mut instrs) => Def::Fn(id, args, instrs.drain(..).map(SInstr::into_instr).collect()),
115 }
116 }
117
118 fn from_def<B: BV>(def: Def<A, B>) -> Option<SDef<A>> {
119 use Def::*;
120 Some(match def {
121 Register(id, ty) => SDef::Register(id, ty),
122 Let(bindings, mut setup) => {
123 SDef::Let(bindings, setup.drain(..).map(SInstr::from_instr).collect::<Option<_>>()?)
124 }
125 Enum(id, elems) => SDef::Enum(id, elems),
126 Struct(id, members) => SDef::Struct(id, members),
127 Union(id, ctors) => SDef::Union(id, ctors),
128 Val(id, arg_tys, ret_ty) => SDef::Val(id, arg_tys, ret_ty),
129 Extern(id, ext, arg_tys, ret_ty) => SDef::Extern(id, ext, arg_tys, ret_ty),
130 Fn(id, args, mut instrs) => {
131 SDef::Fn(id, args, instrs.drain(..).map(SInstr::from_instr).collect::<Option<_>>()?)
132 }
133 })
134 }
135}
136
137pub fn serialize<B: BV>(mut defs: Vec<Def<Name, B>>) -> Option<Vec<u8>> {
138 let sdefs: Vec<SDef<Name>> = defs.drain(..).map(SDef::from_def).collect::<Option<_>>()?;
139 bincode::serialize(&sdefs).ok()
140}
141
142pub fn deserialize<B: BV>(bytes: &[u8]) -> Option<Vec<Def<Name, B>>> {
143 let mut sdefs: Vec<SDef<Name>> = bincode::deserialize(bytes).ok()?;
144 Some(sdefs.drain(..).map(SDef::into_def).collect())
145}