1#[derive(Debug)]
3pub struct InvokeArgs {
4 pub gas: i64,
5 pub regs: [u64; 13],
6}
7
8impl InvokeArgs {
9 pub fn new(gas: i64) -> Self {
11 Self { gas, regs: Default::default() }
12 }
13
14 pub fn reg(&self, reg: Reg) -> u64 {
16 self.regs[reg as usize]
17 }
18
19 pub fn set_reg(&mut self, reg: Reg, value: u64) {
21 self.regs[reg as usize] = value;
22 }
23
24 pub fn set_return_value<T: SetReturnValue>(&mut self, value: T) {
27 value.set_return_value(self);
28 }
29
30 pub fn get_arg_reg(&self, i: usize) -> u64 {
32 self.reg(Reg::ARG_REGS[i])
33 }
34
35 pub fn get_arg<T: Arg>(&mut self, i: &mut usize) -> T {
37 Arg::get(self, i)
38 }
39
40 pub fn set_arg_reg(&mut self, i: usize, value: u64) {
42 self.set_reg(Reg::ARG_REGS[i], value)
43 }
44
45 pub fn set_arg<T: Arg>(&mut self, i: &mut usize, value: T) {
47 value.set(self, i)
48 }
49}
50
51impl From<jam_types::InvokeArgs> for InvokeArgs {
52 fn from(other: jam_types::InvokeArgs) -> Self {
53 Self { gas: other.gas, regs: other.regs }
54 }
55}
56
57impl From<InvokeArgs> for jam_types::InvokeArgs {
58 fn from(other: InvokeArgs) -> Self {
59 Self { gas: other.gas, regs: other.regs }
60 }
61}
62
63#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
65#[repr(u32)]
66pub enum Reg {
67 RA = 0,
68 SP = 1,
69 T0 = 2,
70 T1 = 3,
71 T2 = 4,
72 S0 = 5,
73 S1 = 6,
74 A0 = 7,
75 A1 = 8,
76 A2 = 9,
77 A3 = 10,
78 A4 = 11,
79 A5 = 12,
80}
81
82impl Reg {
83 pub const ARG_REGS: [Reg; 9] =
84 [Reg::A0, Reg::A1, Reg::A2, Reg::A3, Reg::A4, Reg::A5, Reg::T0, Reg::T1, Reg::T2];
85}
86
87pub trait SetReturnValue {
88 fn set_return_value(self, args: &mut InvokeArgs);
89}
90
91impl SetReturnValue for () {
92 fn set_return_value(self, _args: &mut InvokeArgs) {}
93}
94
95impl SetReturnValue for u64 {
96 fn set_return_value(self, args: &mut InvokeArgs) {
97 args.set_reg(Reg::A0, self);
98 }
99}
100
101set_return_value_impl_as! {
102 bool => u64,
103 u8 => u64,
104 u16 => u64,
105 u32 => u64,
106 i8 => u64,
107 i16 => u64,
108 i32 => u64,
109 i64 => u64
110}
111
112pub trait Arg {
113 fn get(args: &InvokeArgs, i: &mut usize) -> Self
114 where
115 Self: Sized;
116
117 fn set(self, args: &mut InvokeArgs, i: &mut usize);
118}
119
120impl Arg for u64 {
121 fn get(args: &InvokeArgs, i: &mut usize) -> Self {
122 let value = args.get_arg_reg(*i);
123 *i += 1;
124 value
125 }
126
127 fn set(self, args: &mut InvokeArgs, i: &mut usize) {
128 args.set_arg_reg(*i, self);
129 *i += 1;
130 }
131}
132
133impl Arg for usize {
134 fn get(args: &InvokeArgs, i: &mut usize) -> Self {
135 u64::get(args, i) as usize
136 }
137
138 fn set(self, args: &mut InvokeArgs, i: &mut usize) {
139 (self as u64).set(args, i);
140 }
141}
142
143impl<T> Arg for *const T {
144 fn get(args: &InvokeArgs, i: &mut usize) -> Self {
145 usize::get(args, i) as Self
146 }
147
148 fn set(self, args: &mut InvokeArgs, i: &mut usize) {
149 (self as usize).set(args, i);
150 }
151}
152
153impl<T> Arg for *mut T {
154 fn get(args: &InvokeArgs, i: &mut usize) -> Self {
155 usize::get(args, i) as Self
156 }
157
158 fn set(self, args: &mut InvokeArgs, i: &mut usize) {
159 (self as usize).set(args, i);
160 }
161}
162
163impl Arg for bool {
164 fn get(args: &InvokeArgs, i: &mut usize) -> Self {
165 u64::get(args, i) != 0
166 }
167
168 fn set(self, args: &mut InvokeArgs, i: &mut usize) {
169 (self as u64).set(args, i);
170 }
171}
172
173arg_impl_as! {
174 u8 => u64,
175 u16 => u64,
176 i8 => u64,
177 i16 => u64,
178 i32 => u64,
179 i64 => u64
180}
181
182macro_rules! set_return_value_impl_as {
183 ($($type:ty => $as_type:ty),+) => {
184 $(
185 impl SetReturnValue for $type {
186 fn set_return_value(self, args: &mut InvokeArgs) {
187 (self as $as_type).set_return_value(args);
188 }
189 }
190 )+
191 };
192}
193
194use set_return_value_impl_as;
195
196macro_rules! arg_impl_as {
197 ($($type:ty => $as_type:ty),+) => {
198 $(
199 impl Arg for $type {
200 fn get(args: &InvokeArgs, i: &mut usize) -> Self {
201 <$as_type>::get(args, i) as Self
202 }
203
204 fn set(self, args: &mut InvokeArgs, i: &mut usize) {
205 (self as $as_type).set(args, i);
206 }
207 }
208 )+
209 };
210}
211
212use arg_impl_as;