1use core::ops::{
2 Add, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, Mul, Rem, Sub,
3};
4
5use crate::runtime::{InstArithmeticOp, InstBitwiseOp, InstShiftOp, Protocol, VmErrorKind};
6
7pub(super) struct ArithmeticOps {
8 pub(super) protocol: Protocol,
9 pub(super) error: fn() -> VmErrorKind,
10 pub(super) i64: fn(i64, i64) -> Option<i64>,
11 pub(super) u64: fn(u64, u64) -> Option<u64>,
12 pub(super) f64: fn(f64, f64) -> f64,
13}
14
15impl ArithmeticOps {
16 pub(super) fn from_op(op: InstArithmeticOp) -> &'static Self {
17 match op {
18 InstArithmeticOp::Add => &Self {
19 protocol: Protocol::ADD,
20 error: || VmErrorKind::Overflow,
21 i64: i64::checked_add,
22 u64: u64::checked_add,
23 f64: f64::add,
24 },
25 InstArithmeticOp::Sub => &Self {
26 protocol: Protocol::SUB,
27 error: || VmErrorKind::Underflow,
28 i64: i64::checked_sub,
29 u64: u64::checked_sub,
30 f64: f64::sub,
31 },
32 InstArithmeticOp::Mul => &Self {
33 protocol: Protocol::MUL,
34 error: || VmErrorKind::Overflow,
35 i64: i64::checked_mul,
36 u64: u64::checked_mul,
37 f64: f64::mul,
38 },
39 InstArithmeticOp::Div => &Self {
40 protocol: Protocol::DIV,
41 error: || VmErrorKind::DivideByZero,
42 i64: i64::checked_div,
43 u64: u64::checked_div,
44 f64: f64::div,
45 },
46 InstArithmeticOp::Rem => &Self {
47 protocol: Protocol::REM,
48 error: || VmErrorKind::DivideByZero,
49 i64: i64::checked_rem,
50 u64: u64::checked_rem,
51 f64: f64::rem,
52 },
53 }
54 }
55}
56
57pub(super) struct AssignArithmeticOps {
58 pub(super) protocol: Protocol,
59 pub(super) error: fn() -> VmErrorKind,
60 pub(super) i64: fn(i64, i64) -> Option<i64>,
61 pub(super) u64: fn(u64, u64) -> Option<u64>,
62 pub(super) f64: fn(f64, f64) -> f64,
63}
64
65impl AssignArithmeticOps {
66 pub(super) fn from_op(op: InstArithmeticOp) -> &'static AssignArithmeticOps {
67 match op {
68 InstArithmeticOp::Add => &Self {
69 protocol: Protocol::ADD_ASSIGN,
70 error: || VmErrorKind::Overflow,
71 i64: i64::checked_add,
72 u64: u64::checked_add,
73 f64: f64::add,
74 },
75 InstArithmeticOp::Sub => &Self {
76 protocol: Protocol::SUB_ASSIGN,
77 error: || VmErrorKind::Underflow,
78 i64: i64::checked_sub,
79 u64: u64::checked_sub,
80 f64: f64::sub,
81 },
82 InstArithmeticOp::Mul => &Self {
83 protocol: Protocol::MUL_ASSIGN,
84 error: || VmErrorKind::Overflow,
85 i64: i64::checked_mul,
86 u64: u64::checked_mul,
87 f64: f64::mul,
88 },
89 InstArithmeticOp::Div => &Self {
90 protocol: Protocol::DIV_ASSIGN,
91 error: || VmErrorKind::DivideByZero,
92 i64: i64::checked_div,
93 u64: u64::checked_div,
94 f64: f64::div,
95 },
96 InstArithmeticOp::Rem => &Self {
97 protocol: Protocol::REM_ASSIGN,
98 error: || VmErrorKind::DivideByZero,
99 i64: i64::checked_rem,
100 u64: u64::checked_rem,
101 f64: f64::rem,
102 },
103 }
104 }
105}
106
107pub(super) struct AssignBitwiseOps {
108 pub(super) protocol: Protocol,
109 pub(super) i64: fn(&mut i64, i64),
110 pub(super) u64: fn(&mut u64, u64),
111 pub(super) bool: fn(&mut bool, bool),
112}
113
114impl AssignBitwiseOps {
115 pub(super) fn from_ops(op: InstBitwiseOp) -> &'static Self {
116 match op {
117 InstBitwiseOp::BitAnd => &Self {
118 protocol: Protocol::BIT_AND_ASSIGN,
119 i64: i64::bitand_assign,
120 u64: u64::bitand_assign,
121 bool: bool::bitand_assign,
122 },
123 InstBitwiseOp::BitXor => &Self {
124 protocol: Protocol::BIT_XOR_ASSIGN,
125 i64: i64::bitxor_assign,
126 u64: u64::bitxor_assign,
127 bool: bool::bitxor_assign,
128 },
129 InstBitwiseOp::BitOr => &Self {
130 protocol: Protocol::BIT_OR_ASSIGN,
131 i64: i64::bitor_assign,
132 u64: u64::bitor_assign,
133 bool: bool::bitor_assign,
134 },
135 }
136 }
137}
138
139pub(super) struct BitwiseOps {
140 pub(super) protocol: Protocol,
141 pub(super) i64: fn(i64, i64) -> i64,
142 pub(super) u64: fn(u64, u64) -> u64,
143 pub(super) bool: fn(bool, bool) -> bool,
144}
145
146impl BitwiseOps {
147 pub(super) fn from_op(op: InstBitwiseOp) -> &'static BitwiseOps {
148 match op {
149 InstBitwiseOp::BitAnd => &BitwiseOps {
150 protocol: Protocol::BIT_AND,
151 i64: i64::bitand,
152 u64: u64::bitand,
153 bool: bool::bitand,
154 },
155 InstBitwiseOp::BitXor => &BitwiseOps {
156 protocol: Protocol::BIT_XOR,
157 i64: i64::bitxor,
158 u64: u64::bitxor,
159 bool: bool::bitxor,
160 },
161 InstBitwiseOp::BitOr => &BitwiseOps {
162 protocol: Protocol::BIT_OR,
163 i64: i64::bitor,
164 u64: u64::bitor,
165 bool: bool::bitor,
166 },
167 }
168 }
169}
170
171pub(super) struct AssignShiftOps {
172 pub(super) protocol: Protocol,
173 pub(super) error: fn() -> VmErrorKind,
174 pub(super) i64: fn(i64, u32) -> Option<i64>,
175 pub(super) u64: fn(u64, u32) -> Option<u64>,
176}
177
178impl AssignShiftOps {
179 pub(super) fn from_op(op: InstShiftOp) -> &'static AssignShiftOps {
180 match op {
181 InstShiftOp::Shl => &Self {
182 protocol: Protocol::SHL_ASSIGN,
183 error: || VmErrorKind::Overflow,
184 i64: i64::checked_shl,
185 u64: u64::checked_shl,
186 },
187 InstShiftOp::Shr => &Self {
188 protocol: Protocol::SHR_ASSIGN,
189 error: || VmErrorKind::Underflow,
190 i64: i64::checked_shr,
191 u64: u64::checked_shr,
192 },
193 }
194 }
195}
196
197pub(super) struct ShiftOps {
198 pub(super) protocol: Protocol,
199 pub(super) error: fn() -> VmErrorKind,
200 pub(super) i64: fn(i64, u32) -> Option<i64>,
201 pub(super) u64: fn(u64, u32) -> Option<u64>,
202}
203
204impl ShiftOps {
205 pub(super) fn from_op(op: InstShiftOp) -> &'static Self {
206 match op {
207 InstShiftOp::Shl => &Self {
208 protocol: Protocol::SHL,
209 error: || VmErrorKind::Overflow,
210 i64: i64::checked_shl,
211 u64: u64::checked_shl,
212 },
213 InstShiftOp::Shr => &Self {
214 protocol: Protocol::SHR,
215 error: || VmErrorKind::Underflow,
216 i64: i64::checked_shr,
217 u64: u64::checked_shr,
218 },
219 }
220 }
221}