1 use cranelift_codegen::ir::{Block, Function, Inst, InstructionData, Signature};
2 use serde_derive::{Deserialize, Serialize};
3 
4 /// Serializable version of the original Cranelift IR
5 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
6 pub enum SerInstData {
7     Unary {
8         opcode: String,
9         arg: String,
10     },
11     UnaryImm {
12         opcode: String,
13         imm: String,
14     },
15     UnaryIeee32 {
16         opcode: String,
17         imm: String,
18     },
19     UnaryIeee64 {
20         opcode: String,
21         imm: String,
22     },
23     UnaryBool {
24         opcode: String,
25         imm: bool,
26     },
27     UnaryGlobalValue {
28         opcode: String,
29         global_value: String,
30     },
31     Binary {
32         opcode: String,
33         args: [String; 2],
34     },
35     BinaryImm8 {
36         opcode: String,
37         arg: String,
38         imm: String,
39     },
40     BinaryImm64 {
41         opcode: String,
42         arg: String,
43         imm: String,
44     },
45     Ternary {
46         opcode: String,
47         args: [String; 3],
48     },
49     TernaryImm8 {
50         opcode: String,
51         args: [String; 2],
52         imm: String,
53     },
54     MultiAry {
55         opcode: String,
56         args: Vec<String>,
57     },
58     NullAry {
59         opcode: String,
60     },
61     Shuffle {
62         opcode: String,
63         args: [String; 2],
64         mask: String,
65     },
66     IntCompare {
67         opcode: String,
68         args: [String; 2],
69         cond: String,
70     },
71     IntCompareImm {
72         opcode: String,
73         arg: String,
74         cond: String,
75         imm: String,
76     },
77     IntCond {
78         opcode: String,
79         arg: String,
80         cond: String,
81     },
82     FloatCompare {
83         opcode: String,
84         args: [String; 2],
85         cond: String,
86     },
87     FloatCond {
88         opcode: String,
89         arg: String,
90         cond: String,
91     },
92     IntSelect {
93         opcode: String,
94         args: [String; 3],
95         cond: String,
96     },
97     Jump {
98         opcode: String,
99         args: Vec<String>,
100         destination: String,
101     },
102     Branch {
103         opcode: String,
104         args: Vec<String>,
105         destination: String,
106     },
107     BranchInt {
108         opcode: String,
109         args: Vec<String>,
110         cond: String,
111         destination: String,
112     },
113     BranchFloat {
114         opcode: String,
115         args: Vec<String>,
116         cond: String,
117         destination: String,
118     },
119     BranchIcmp {
120         opcode: String,
121         args: Vec<String>,
122         cond: String,
123         destination: String,
124     },
125     BranchTable {
126         opcode: String,
127         arg: String,
128         destination: String,
129         table: String,
130     },
131     BranchTableEntry {
132         opcode: String,
133         args: [String; 2],
134         imm: String,
135         table: String,
136     },
137     BranchTableBase {
138         opcode: String,
139         table: String,
140     },
141     IndirectJump {
142         opcode: String,
143         arg: String,
144         table: String,
145     },
146     Call {
147         opcode: String,
148         args: Vec<String>,
149         func_ref: String,
150     },
151     CallIndirect {
152         opcode: String,
153         args: Vec<String>,
154         sig_ref: String,
155     },
156     FuncAddr {
157         opcode: String,
158         func_ref: String,
159     },
160     Load {
161         opcode: String,
162         arg: String,
163         flags: String,
164         offset: String,
165     },
166     LoadComplex {
167         opcode: String,
168         args: Vec<String>,
169         flags: String,
170         offset: String,
171     },
172     Store {
173         opcode: String,
174         args: [String; 2],
175         flags: String,
176         offset: String,
177     },
178     StoreComplex {
179         opcode: String,
180         args: Vec<String>,
181         flags: String,
182         offset: String,
183     },
184     StackLoad {
185         opcode: String,
186         stack_slot: String,
187         offset: String,
188     },
189     StackStore {
190         opcode: String,
191         arg: String,
192         stack_slot: String,
193         offset: String,
194     },
195     HeapAddr {
196         opcode: String,
197         arg: String,
198         heap: String,
199         imm: String,
200     },
201     TableAddr {
202         opcode: String,
203         arg: String,
204         table: String,
205         offset: String,
206     },
207     RegMove {
208         opcode: String,
209         arg: String,
210         src: String,
211         dst: String,
212     },
213     CopySpecial {
214         opcode: String,
215         src: String,
216         dst: String,
217     },
218     CopyToSsa {
219         opcode: String,
220         src: String,
221     },
222     RegSpill {
223         opcode: String,
224         arg: String,
225         src: String,
226         dst: String,
227     },
228     RegFill {
229         opcode: String,
230         arg: String,
231         src: String,
232         dst: String,
233     },
234     Trap {
235         opcode: String,
236         code: String,
237     },
238     CondTrap {
239         opcode: String,
240         arg: String,
241         code: String,
242     },
243     IntCondTrap {
244         opcode: String,
245         arg: String,
246         cond: String,
247         code: String,
248     },
249     FloatCondTrap {
250         opcode: String,
251         arg: String,
252         cond: String,
253         code: String,
254     },
255 }
256 
257 /// Convert Cranelift IR instructions to JSON format.
get_inst_data(inst_index: Inst, func: &Function) -> SerInstData258 pub fn get_inst_data(inst_index: Inst, func: &Function) -> SerInstData {
259     let inst = &func.dfg[inst_index];
260     match *inst {
261         InstructionData::Unary { opcode, arg } => SerInstData::Unary {
262             opcode: opcode.to_string(),
263             arg: arg.to_string(),
264         },
265         InstructionData::UnaryImm { opcode, imm } => SerInstData::UnaryImm {
266             opcode: opcode.to_string(),
267             imm: imm.to_string(),
268         },
269         InstructionData::UnaryIeee32 { opcode, imm } => SerInstData::UnaryIeee32 {
270             opcode: opcode.to_string(),
271             imm: imm.to_string(),
272         },
273         InstructionData::UnaryIeee64 { opcode, imm } => SerInstData::UnaryIeee64 {
274             opcode: opcode.to_string(),
275             imm: imm.to_string(),
276         },
277         InstructionData::UnaryBool { opcode, imm } => SerInstData::UnaryBool {
278             opcode: opcode.to_string(),
279             imm,
280         },
281         InstructionData::UnaryGlobalValue {
282             opcode,
283             global_value,
284         } => SerInstData::UnaryGlobalValue {
285             opcode: opcode.to_string(),
286             global_value: global_value.to_string(),
287         },
288         InstructionData::Binary { opcode, args } => {
289             let hold_args = [args[0].to_string(), args[1].to_string()];
290             SerInstData::Binary {
291                 opcode: opcode.to_string(),
292                 args: hold_args,
293             }
294         }
295         InstructionData::BinaryImm8 { opcode, arg, imm } => SerInstData::BinaryImm8 {
296             opcode: opcode.to_string(),
297             arg: arg.to_string(),
298             imm: imm.to_string(),
299         },
300         InstructionData::BinaryImm64 { opcode, arg, imm } => SerInstData::BinaryImm64 {
301             opcode: opcode.to_string(),
302             arg: arg.to_string(),
303             imm: imm.to_string(),
304         },
305         InstructionData::Ternary { opcode, args } => {
306             let hold_args = [
307                 args[0].to_string(),
308                 args[1].to_string(),
309                 args[2].to_string(),
310             ];
311             SerInstData::Ternary {
312                 opcode: opcode.to_string(),
313                 args: hold_args,
314             }
315         }
316         InstructionData::MultiAry { opcode, ref args } => {
317             let mut hold_args = Vec::new();
318             let args_iter = args.as_slice(&func.dfg.value_lists);
319             for arg in args_iter {
320                 hold_args.push(arg.to_string());
321             }
322 
323             SerInstData::MultiAry {
324                 opcode: opcode.to_string(),
325                 args: hold_args,
326             }
327         }
328         InstructionData::NullAry { opcode } => SerInstData::NullAry {
329             opcode: opcode.to_string(),
330         },
331         InstructionData::TernaryImm8 { opcode, args, imm } => {
332             let hold_args = [args[0].to_string(), args[1].to_string()];
333             SerInstData::TernaryImm8 {
334                 opcode: opcode.to_string(),
335                 args: hold_args,
336                 imm: imm.to_string(),
337             }
338         }
339         InstructionData::UnaryConst {
340             opcode,
341             constant_handle,
342         } => {
343             let constant = func.dfg.constants.get(constant_handle);
344             SerInstData::UnaryImm {
345                 opcode: opcode.to_string(),
346                 imm: format!("{:?}", constant),
347             }
348         }
349         InstructionData::Shuffle { opcode, args, mask } => {
350             let mask = func
351                 .dfg
352                 .immediates
353                 .get(mask)
354                 .expect("Expected shuffle mask to already be inserted in immediate mapping");
355             SerInstData::Shuffle {
356                 opcode: opcode.to_string(),
357                 args: [args[0].to_string(), args[1].to_string()],
358                 mask: format!("{:?}", mask),
359             }
360         }
361         InstructionData::IntCompare { opcode, args, cond } => {
362             let hold_args = [args[0].to_string(), args[1].to_string()];
363             SerInstData::IntCompare {
364                 opcode: opcode.to_string(),
365                 args: hold_args,
366                 cond: cond.to_string(),
367             }
368         }
369         InstructionData::IntCompareImm {
370             opcode,
371             arg,
372             cond,
373             imm,
374         } => SerInstData::IntCompareImm {
375             opcode: opcode.to_string(),
376             arg: arg.to_string(),
377             cond: cond.to_string(),
378             imm: imm.to_string(),
379         },
380         InstructionData::IntCond { opcode, arg, cond } => SerInstData::IntCond {
381             opcode: opcode.to_string(),
382             arg: arg.to_string(),
383             cond: cond.to_string(),
384         },
385         InstructionData::FloatCompare { opcode, args, cond } => {
386             let hold_args = [args[0].to_string(), args[1].to_string()];
387             SerInstData::FloatCompare {
388                 opcode: opcode.to_string(),
389                 args: hold_args,
390                 cond: cond.to_string(),
391             }
392         }
393         InstructionData::FloatCond { opcode, arg, cond } => SerInstData::FloatCond {
394             opcode: opcode.to_string(),
395             arg: arg.to_string(),
396             cond: cond.to_string(),
397         },
398         InstructionData::IntSelect { opcode, args, cond } => {
399             let hold_args = [
400                 args[0].to_string(),
401                 args[1].to_string(),
402                 args[2].to_string(),
403             ];
404             SerInstData::IntSelect {
405                 opcode: opcode.to_string(),
406                 args: hold_args,
407                 cond: cond.to_string(),
408             }
409         }
410         InstructionData::Jump {
411             opcode,
412             ref args,
413             destination,
414         } => {
415             let mut hold_args = Vec::new();
416             let args_iter = args.as_slice(&func.dfg.value_lists);
417             for arg in args_iter {
418                 hold_args.push(arg.to_string());
419             }
420             SerInstData::Jump {
421                 opcode: opcode.to_string(),
422                 args: hold_args,
423                 destination: destination.to_string(),
424             }
425         }
426         InstructionData::Branch {
427             opcode,
428             ref args,
429             destination,
430         } => {
431             let mut hold_args = Vec::new();
432             let args_iter = args.as_slice(&func.dfg.value_lists);
433             for arg in args_iter {
434                 hold_args.push(arg.to_string());
435             }
436             SerInstData::Branch {
437                 opcode: opcode.to_string(),
438                 args: hold_args,
439                 destination: destination.to_string(),
440             }
441         }
442         InstructionData::BranchInt {
443             opcode,
444             ref args,
445             cond,
446             destination,
447         } => {
448             let mut hold_args = Vec::new();
449             let args_iter = args.as_slice(&func.dfg.value_lists);
450             for arg in args_iter {
451                 hold_args.push(arg.to_string());
452             }
453             SerInstData::BranchInt {
454                 opcode: opcode.to_string(),
455                 args: hold_args,
456                 cond: cond.to_string(),
457                 destination: destination.to_string(),
458             }
459         }
460         InstructionData::BranchFloat {
461             opcode,
462             ref args,
463             cond,
464             destination,
465         } => {
466             let mut hold_args = Vec::new();
467             let args_iter = args.as_slice(&func.dfg.value_lists);
468             for arg in args_iter {
469                 hold_args.push(arg.to_string());
470             }
471             SerInstData::BranchFloat {
472                 opcode: opcode.to_string(),
473                 args: hold_args,
474                 cond: cond.to_string(),
475                 destination: destination.to_string(),
476             }
477         }
478         InstructionData::BranchIcmp {
479             opcode,
480             ref args,
481             cond,
482             destination,
483         } => {
484             let mut hold_args = Vec::new();
485             let args_iter = args.as_slice(&func.dfg.value_lists);
486             for arg in args_iter {
487                 hold_args.push(arg.to_string());
488             }
489             SerInstData::BranchIcmp {
490                 opcode: opcode.to_string(),
491                 args: hold_args,
492                 cond: cond.to_string(),
493                 destination: destination.to_string(),
494             }
495         }
496         InstructionData::BranchTable {
497             opcode,
498             arg,
499             destination,
500             table,
501         } => SerInstData::BranchTable {
502             opcode: opcode.to_string(),
503             arg: arg.to_string(),
504             destination: destination.to_string(),
505             table: table.to_string(),
506         },
507         InstructionData::BranchTableBase { opcode, table } => SerInstData::BranchTableBase {
508             opcode: opcode.to_string(),
509             table: table.to_string(),
510         },
511         InstructionData::BranchTableEntry {
512             opcode,
513             args,
514             imm,
515             table,
516         } => {
517             let hold_args = [args[0].to_string(), args[1].to_string()];
518             SerInstData::BranchTableEntry {
519                 opcode: opcode.to_string(),
520                 args: hold_args,
521                 imm: imm.to_string(),
522                 table: table.to_string(),
523             }
524         }
525         InstructionData::IndirectJump { opcode, arg, table } => SerInstData::IndirectJump {
526             opcode: opcode.to_string(),
527             arg: arg.to_string(),
528             table: table.to_string(),
529         },
530         InstructionData::Call {
531             opcode,
532             ref args,
533             func_ref,
534         } => {
535             let mut hold_args = Vec::new();
536             let args_iter = args.as_slice(&func.dfg.value_lists);
537             for arg in args_iter {
538                 hold_args.push(arg.to_string());
539             }
540             SerInstData::Call {
541                 opcode: opcode.to_string(),
542                 args: hold_args,
543                 func_ref: func_ref.to_string(),
544             }
545         }
546         InstructionData::CallIndirect {
547             opcode,
548             ref args,
549             sig_ref,
550         } => {
551             let mut hold_args = Vec::new();
552             let args_iter = args.as_slice(&func.dfg.value_lists);
553             for arg in args_iter {
554                 hold_args.push(arg.to_string());
555             }
556             SerInstData::CallIndirect {
557                 opcode: opcode.to_string(),
558                 args: hold_args,
559                 sig_ref: sig_ref.to_string(),
560             }
561         }
562         InstructionData::FuncAddr { opcode, func_ref } => SerInstData::FuncAddr {
563             opcode: opcode.to_string(),
564             func_ref: func_ref.to_string(),
565         },
566         InstructionData::Load {
567             opcode,
568             arg,
569             flags,
570             offset,
571         } => SerInstData::Load {
572             opcode: opcode.to_string(),
573             arg: arg.to_string(),
574             flags: flags.to_string(),
575             offset: offset.to_string(),
576         },
577         InstructionData::LoadComplex {
578             opcode,
579             ref args,
580             flags,
581             offset,
582         } => {
583             let mut hold_args = Vec::new();
584             let args_iter = args.as_slice(&func.dfg.value_lists);
585             for arg in args_iter {
586                 hold_args.push(arg.to_string());
587             }
588             SerInstData::LoadComplex {
589                 opcode: opcode.to_string(),
590                 args: hold_args,
591                 flags: flags.to_string(),
592                 offset: offset.to_string(),
593             }
594         }
595         InstructionData::Store {
596             opcode,
597             args,
598             flags,
599             offset,
600         } => {
601             let hold_args = [args[0].to_string(), args[1].to_string()];
602             SerInstData::Store {
603                 opcode: opcode.to_string(),
604                 args: hold_args,
605                 flags: flags.to_string(),
606                 offset: offset.to_string(),
607             }
608         }
609         InstructionData::StoreComplex {
610             opcode,
611             ref args,
612             flags,
613             offset,
614         } => {
615             let mut hold_args = Vec::new();
616             let args_iter = args.as_slice(&func.dfg.value_lists);
617             for arg in args_iter {
618                 hold_args.push(arg.to_string());
619             }
620             SerInstData::StoreComplex {
621                 opcode: opcode.to_string(),
622                 args: hold_args,
623                 flags: flags.to_string(),
624                 offset: offset.to_string(),
625             }
626         }
627         InstructionData::StackLoad {
628             opcode,
629             stack_slot,
630             offset,
631         } => SerInstData::StackLoad {
632             opcode: opcode.to_string(),
633             stack_slot: stack_slot.to_string(),
634             offset: offset.to_string(),
635         },
636         InstructionData::StackStore {
637             opcode,
638             arg,
639             stack_slot,
640             offset,
641         } => SerInstData::StackStore {
642             opcode: opcode.to_string(),
643             arg: arg.to_string(),
644             stack_slot: stack_slot.to_string(),
645             offset: offset.to_string(),
646         },
647         InstructionData::HeapAddr {
648             opcode,
649             arg,
650             heap,
651             imm,
652         } => SerInstData::HeapAddr {
653             opcode: opcode.to_string(),
654             arg: arg.to_string(),
655             heap: heap.to_string(),
656             imm: imm.to_string(),
657         },
658         InstructionData::TableAddr {
659             opcode,
660             arg,
661             table,
662             offset,
663         } => SerInstData::TableAddr {
664             opcode: opcode.to_string(),
665             arg: arg.to_string(),
666             table: table.to_string(),
667             offset: offset.to_string(),
668         },
669         InstructionData::RegMove {
670             opcode,
671             arg,
672             src,
673             dst,
674         } => SerInstData::RegMove {
675             opcode: opcode.to_string(),
676             arg: arg.to_string(),
677             src: src.to_string(),
678             dst: dst.to_string(),
679         },
680         InstructionData::CopySpecial { opcode, src, dst } => SerInstData::CopySpecial {
681             opcode: opcode.to_string(),
682             src: src.to_string(),
683             dst: dst.to_string(),
684         },
685         InstructionData::CopyToSsa { opcode, src } => SerInstData::CopyToSsa {
686             opcode: opcode.to_string(),
687             src: src.to_string(),
688         },
689         InstructionData::RegSpill {
690             opcode,
691             arg,
692             src,
693             dst,
694         } => SerInstData::RegSpill {
695             opcode: opcode.to_string(),
696             arg: arg.to_string(),
697             src: src.to_string(),
698             dst: dst.to_string(),
699         },
700         InstructionData::RegFill {
701             opcode,
702             arg,
703             src,
704             dst,
705         } => SerInstData::RegFill {
706             opcode: opcode.to_string(),
707             arg: arg.to_string(),
708             src: src.to_string(),
709             dst: dst.to_string(),
710         },
711         InstructionData::Trap { opcode, code } => SerInstData::Trap {
712             opcode: opcode.to_string(),
713             code: code.to_string(),
714         },
715         InstructionData::CondTrap { opcode, arg, code } => SerInstData::CondTrap {
716             opcode: opcode.to_string(),
717             arg: arg.to_string(),
718             code: code.to_string(),
719         },
720         InstructionData::IntCondTrap {
721             opcode,
722             arg,
723             cond,
724             code,
725         } => SerInstData::IntCondTrap {
726             opcode: opcode.to_string(),
727             arg: arg.to_string(),
728             cond: cond.to_string(),
729             code: code.to_string(),
730         },
731         InstructionData::FloatCondTrap {
732             opcode,
733             arg,
734             cond,
735             code,
736         } => SerInstData::FloatCondTrap {
737             opcode: opcode.to_string(),
738             arg: arg.to_string(),
739             cond: cond.to_string(),
740             code: code.to_string(),
741         },
742     }
743 }
744 
745 /// Serializable version of Cranelift IR instructions.
746 #[derive(Clone, Deserialize, Serialize, Debug)]
747 pub struct SerInst {
748     pub inst_name: String,
749     pub inst_data: SerInstData,
750 }
751 
752 impl SerInst {
new(inst: Inst, func: &Function) -> Self753     pub fn new(inst: Inst, func: &Function) -> Self {
754         Self {
755             inst_name: inst.to_string(),
756             inst_data: get_inst_data(inst, func),
757         }
758     }
759 }
760 
761 /// Serializable version of Cranelift IR Blocks.
762 #[derive(Clone, Deserialize, Serialize, Debug)]
763 pub struct SerBlock {
764     pub block: String,
765     pub params: Vec<String>,
766     pub insts: Vec<SerInst>,
767 }
768 
769 impl SerBlock {
new(name: String) -> Self770     pub fn new(name: String) -> Self {
771         Self {
772             block: name,
773             params: Vec::new(),
774             insts: Vec::new(),
775         }
776     }
777 }
778 
populate_inst(func: &Function, block: Block) -> Vec<SerInst>779 pub fn populate_inst(func: &Function, block: Block) -> Vec<SerInst> {
780     let mut ser_vec: Vec<SerInst> = Vec::new();
781     let ret_iter = func.layout.block_insts(block);
782     for inst in ret_iter {
783         let ser_inst: SerInst = SerInst::new(inst, &func);
784         ser_vec.push(ser_inst);
785     }
786     ser_vec
787 }
788 
789 /// Translating Block parameters into serializable parameters.
populate_params(func: &Function, block: Block) -> Vec<String>790 pub fn populate_params(func: &Function, block: Block) -> Vec<String> {
791     let mut ser_vec: Vec<String> = Vec::new();
792     let parameters = func.dfg.block_params(block);
793     for param in parameters {
794         ser_vec.push(param.to_string());
795     }
796     ser_vec
797 }
798 
799 /// Serializable Data Flow Graph.
800 #[derive(Deserialize, Serialize, Debug)]
801 pub struct SerDataFlowGraph {
802     blocks: Vec<SerBlock>,
803 }
804 
805 /// Serialize all parts of the Cranelift Block data structure, this includes name, parameters, and
806 /// instructions.
populate_blocks(func: &Function) -> Vec<SerBlock>807 pub fn populate_blocks(func: &Function) -> Vec<SerBlock> {
808     let mut block_vec: Vec<SerBlock> = Vec::new();
809     for block in func.layout.blocks() {
810         let mut ser_block: SerBlock = SerBlock::new(block.to_string());
811         ser_block.params = populate_params(&func, block);
812         ser_block.insts = populate_inst(&func, block);
813         block_vec.push(ser_block);
814     }
815     block_vec
816 }
817 
818 /// Serializable Cranelift IR data flow graph, including all blocks.
819 impl SerDataFlowGraph {
create_new(func: &Function) -> Self820     pub fn create_new(func: &Function) -> Self {
821         Self {
822             blocks: populate_blocks(func),
823         }
824     }
825 
new(func: &Function) -> Self826     pub fn new(func: &Function) -> Self {
827         Self::create_new(func)
828     }
829 }
830 
831 /// Serializable signature including function parameters and returns.
832 #[derive(Serialize, Deserialize, Debug)]
833 pub struct SerSignature {
834     pub func_params: Vec<String>,
835     pub func_returns: Vec<String>,
836 }
837 
838 impl SerSignature {
839     /// Creating serializable signature data structure from all Cranelift IR functions.
create_new(sig: &Signature) -> Self840     fn create_new(sig: &Signature) -> Self {
841         let mut params_vec: Vec<String> = Vec::new();
842         let mut returns_vec: Vec<String> = Vec::new();
843         for param in &sig.params {
844             params_vec.push(param.to_string());
845         }
846         for ret in &sig.returns {
847             returns_vec.push(ret.to_string());
848         }
849         Self {
850             func_params: params_vec,
851             func_returns: returns_vec,
852         }
853     }
854 
new(func: &Function) -> Self855     pub fn new(func: &Function) -> Self {
856         Self::create_new(&func.signature)
857     }
858 }
859 
860 /// Serializable Function type, including name, signature, global values, and data flow graph.
861 #[derive(Serialize, Deserialize, Debug)]
862 pub struct SerFunction {
863     pub name: String,
864     pub signature: SerSignature,
865     pub globals: Vec<String>,
866     pub dfg: SerDataFlowGraph,
867 }
868 
869 impl SerFunction {
870     /// Creates serializable global values, as well as the functions signature, name, and data flow
871     /// graph.
create_new(func: &Function) -> Self872     fn create_new(func: &Function) -> Self {
873         let mut global_vec: Vec<String> = Vec::new();
874         for (glob_name, _) in func.global_values.iter() {
875             global_vec.push(glob_name.to_string());
876         }
877         Self {
878             name: func.name.to_string(),
879             signature: SerSignature::new(&func),
880             globals: global_vec,
881             dfg: SerDataFlowGraph::new(&func),
882         }
883     }
884 
new(func: &Function) -> Self885     pub fn new(func: &Function) -> Self {
886         Self::create_new(func)
887     }
888 }
889 
890 /// Must have SerObj for deserialization, contains all of the functions from inside the file to be
891 /// serialized. Files have one SerObj each, with all SerFunctions contained inside that SerObj.
892 #[derive(Serialize, Deserialize, Debug)]
893 pub struct SerObj {
894     pub functions: Vec<SerFunction>,
895 }
896 
897 impl SerObj {
create_new(funcs: Vec<SerFunction>) -> Self898     fn create_new(funcs: Vec<SerFunction>) -> Self {
899         Self { functions: funcs }
900     }
901 
new(funcs: &[Function]) -> Self902     pub fn new(funcs: &[Function]) -> Self {
903         let mut func_vec: Vec<SerFunction> = Vec::new();
904         for func in funcs {
905             let ser_func: SerFunction = SerFunction::new(&func);
906             func_vec.push(ser_func);
907         }
908         Self::create_new(func_vec)
909     }
910 }
911