luaur_analysis/methods/
cfg_builder_emit.rs1use crate::records::assign::Assign;
4use crate::records::block::Block;
5use crate::records::cfg_builder::CfgBuilder;
6use crate::records::declare::Declare;
7use crate::records::join::Join;
8use crate::records::refine::Refine;
9use crate::type_aliases::def_id_control_flow_graph::DefId;
10use crate::type_aliases::instruction::{Instruction, InstructionMember};
11use crate::type_aliases::refinement_control_flow_graph::Refinement;
12use luaur_ast::records::ast_stat_assign::AstStatAssign;
13use luaur_ast::records::ast_stat_local::AstStatLocal;
14
15pub trait IntoInstruction<T> {
19 fn into_instruction(self) -> Instruction;
20}
21
22impl IntoInstruction<Declare> for (DefId, *mut AstStatLocal) {
24 fn into_instruction(self) -> Instruction {
25 Instruction::Declare(Declare::declare(self.0, self.1))
26 }
27}
28
29impl IntoInstruction<Assign> for (DefId, *mut AstStatAssign) {
31 fn into_instruction(self) -> Instruction {
32 Instruction::Assign(Assign::assign(self.0, self.1))
33 }
34}
35
36impl IntoInstruction<Join> for DefId {
38 fn into_instruction(self) -> Instruction {
39 Instruction::Join(Join {
41 definition: self,
42 operands: alloc::vec::Vec::new(),
43 })
44 }
45}
46
47impl IntoInstruction<Refine> for (DefId, *const Refinement) {
49 fn into_instruction(self) -> Instruction {
50 Instruction::Refine(Refine {
51 definition: self.0,
52 prop: self.1,
53 })
54 }
55}
56
57impl CfgBuilder {
58 pub fn emit<T, Args>(&mut self, block: *mut Block, args: Args) -> *mut T
61 where
62 Args: IntoInstruction<T>,
63 T: InstructionMember,
64 {
65 let allocator = unsafe { &mut *self.allocator };
70 let inst = allocator.new_instruction(args.into_instruction());
71 unsafe {
72 (*block).instructions.push(inst);
73 <T as InstructionMember>::get_if_mut(&mut *inst).unwrap() as *mut T
74 }
75 }
76}