1#![allow(clippy::mutex_atomic)] #![allow(clippy::new_without_default)] use std::os::raw;
5use std::ptr;
6use std::sync::Mutex;
7
8use crate::bindings;
9use crate::JitState;
10
11use std::marker::PhantomData;
12
13#[derive(Debug)]
14pub struct Jit<'a>(PhantomData<&'a ()>);
15
16lazy_static! {
17 static ref JITS_MADE: Mutex<usize> = Mutex::new(0);
18}
19
20impl<'a> Jit<'a> {
21 pub fn new() -> Jit<'a> {
22 let mut m = JITS_MADE.lock().unwrap();
23
24 if *m == 0 {
25 unsafe {
26 bindings::init_jit(ptr::null::<raw::c_char>());
28 }
29 }
30
31 *m += 1;
32 Jit(PhantomData)
33 }
34
35 pub fn new_state(&mut self) -> JitState {
38 JitState {
39 state: unsafe {
40 bindings::jit_new_state()
41 },
42 phantom: PhantomData,
43 }
44 }
45
46 pub fn r_num(&self) -> bindings::jit_gpr_t {
47 unsafe {
48 bindings::lgsys_JIT_R_NUM()
49 }
50 }
51
52 pub fn v_num(&self) -> bindings::jit_gpr_t {
53 unsafe {
54 bindings::lgsys_JIT_V_NUM()
55 }
56 }
57
58 pub fn f_num(&self) -> bindings::jit_gpr_t {
59 unsafe {
60 bindings::lgsys_JIT_F_NUM()
61 }
62 }
63
64}
65
66impl<'a> Drop for Jit<'a> {
67 fn drop(&mut self) {
68 let mut m = JITS_MADE.lock().unwrap();
69 *m -= 1;
70
71 if *m == 0 {
72 unsafe {
73 bindings::finish_jit();
74 }
75 }
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use crate::Jit;
82 use crate::Reg;
83 use crate::types::ToFFI;
84
85 #[test]
86 fn test_jit() {
87 {
88 let _jit = Jit::new();
89 Jit::new();
90 }
91
92 {
93 let _jit = Jit::new();
94 Jit::new();
95 }
96
97 }
98
99 #[test]
100 fn test_reg_num() {
101 let jit = Jit::new();
102 assert!(jit.r_num() >= 3);
103 assert!(jit.v_num() >= 3);
104 assert!(jit.f_num() >= 6);
105 }
106
107 #[test]
108 fn test_to_ffi() {
109 let jit = Jit::new();
110
111 assert!(std::panic::catch_unwind(|| Reg::R(jit.r_num()).to_ffi()).is_err());
112 Reg::R(jit.r_num()-1).to_ffi();
113 Reg::R(0).to_ffi();
114
115 assert!(std::panic::catch_unwind(|| Reg::V(jit.v_num()).to_ffi()).is_err());
116 Reg::V(jit.v_num()-1).to_ffi();
117 Reg::V(0).to_ffi();
118
119 assert!(std::panic::catch_unwind(|| Reg::F(jit.f_num()).to_ffi()).is_err());
120 Reg::F(jit.f_num()-1).to_ffi();
121 Reg::F(0).to_ffi();
122 }
123}