1use alloc::{format, string::String};
18use sha2::{Digest, Sha256};
19
20pub trait ArgVisitor {
23 fn visit_ptr(&mut self, ptr: *mut core::ffi::c_void);
25 fn visit_bool(&mut self, val: bool);
27 fn visit_i8(&mut self, val: i8);
29 fn visit_i16(&mut self, val: i16);
31 fn visit_i32(&mut self, val: i32);
33 fn visit_i64(&mut self, val: i64);
35 fn visit_u8(&mut self, val: u8);
37 fn visit_u16(&mut self, val: u16);
39 fn visit_u32(&mut self, val: u32);
41 fn visit_u64(&mut self, val: u64);
43 fn visit_f32(&mut self, val: f32);
45 fn visit_f64(&mut self, val: f64);
47}
48
49pub trait KernelArg {
52 fn visit<V: ArgVisitor>(&self, visitor: &mut V);
54}
55
56impl<T> KernelArg for *mut T {
57 #[inline]
58 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
59 visitor.visit_ptr(*self as *mut core::ffi::c_void);
60 }
61}
62
63impl KernelArg for bool {
64 #[inline]
65 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
66 visitor.visit_bool(*self);
67 }
68}
69
70impl KernelArg for i8 {
71 #[inline]
72 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
73 visitor.visit_i8(*self);
74 }
75}
76
77impl KernelArg for i16 {
78 #[inline]
79 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
80 visitor.visit_i16(*self);
81 }
82}
83
84impl KernelArg for i32 {
85 #[inline]
86 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
87 visitor.visit_i32(*self);
88 }
89}
90
91impl KernelArg for i64 {
92 #[inline]
93 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
94 visitor.visit_i64(*self);
95 }
96}
97
98impl KernelArg for u8 {
99 #[inline]
100 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
101 visitor.visit_u8(*self);
102 }
103}
104
105impl KernelArg for u16 {
106 #[inline]
107 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
108 visitor.visit_u16(*self);
109 }
110}
111
112impl KernelArg for u32 {
113 #[inline]
114 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
115 visitor.visit_u32(*self);
116 }
117}
118
119impl KernelArg for u64 {
120 #[inline]
121 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
122 visitor.visit_u64(*self);
123 }
124}
125
126impl KernelArg for f32 {
127 #[inline]
128 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
129 visitor.visit_f32(*self);
130 }
131}
132
133impl KernelArg for f64 {
134 #[inline]
135 fn visit<V: ArgVisitor>(&self, visitor: &mut V) {
136 visitor.visit_f64(*self);
137 }
138}
139
140pub trait KernelArgs {
144 fn visit_args<V: ArgVisitor>(&self, visitor: &mut V);
146}
147
148impl KernelArgs for () {
149 #[inline]
150 fn visit_args<V: ArgVisitor>(&self, _visitor: &mut V) {}
151}
152
153macro_rules! impl_kernel_args {
154 ($( $T:ident : $idx:tt ),+) => {
155 impl<$($T: KernelArg),+> KernelArgs for ($($T,)+) {
156 #[inline]
157 fn visit_args<V: ArgVisitor>(&self, visitor: &mut V) {
158 $( self.$idx.visit(visitor); )+
159 }
160 }
161 };
162}
163
164impl_kernel_args!(A:0);
165impl_kernel_args!(A:0, B:1);
166impl_kernel_args!(A:0, B:1, C:2);
167impl_kernel_args!(A:0, B:1, C:2, D:3);
168impl_kernel_args!(A:0, B:1, C:2, D:3, E:4);
169impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5);
170impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6);
171impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7);
172impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8);
173impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9);
174impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10);
175impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11);
176impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12);
177impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13);
178impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14);
179impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15);
180impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16);
181impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17);
182impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18);
183impl_kernel_args!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, Ty:19);
184
185pub trait Kernel {
187 type Args<'a>: KernelArgs;
189
190 fn id(&self) -> String {
192 let mut hasher = Sha256::new();
193 hasher.update(self.source().as_bytes());
194 hasher
195 .finalize()
196 .iter()
197 .map(|b| format!("{:02x}", b))
198 .collect()
199 }
200
201 fn name(&self) -> &str;
203
204 fn source(&self) -> &str;
206
207 fn kernel_source(&self) -> &str;
209
210 fn entry_point_source(&self) -> &str;
212
213 fn entry_point_name(&self) -> String {
215 format!("{}_entry_point", self.name())
216 }
217}
218
219pub trait Program<'a, K: Kernel>: Sized {}