1use crate::{
18 BinaryOperation,
19 FromStrRadix as _,
20 IntegerType,
21 Literal,
22 LiteralVariant,
23 Node as _,
24 Type,
25 UnaryOperation,
26 halt,
27 halt_no_span,
28 interpreter_value::{
29 StructContents,
30 SvmAddress,
31 SvmBoolean,
32 SvmField,
33 SvmGroup,
34 SvmIdentifier,
35 SvmInteger,
36 SvmScalar,
37 Value,
38 util::ExpectTc,
39 },
40 tc_fail,
41};
42use leo_errors::{InterpreterHalt, Result};
43use leo_span::Span;
44
45use snarkvm::prelude::{
46 Cast,
47 Double as _,
48 FromBits as _,
49 Inverse as _,
50 Literal as SvmLiteral,
51 Plaintext,
52 Pow as _,
53 ProgramID,
54 Square as _,
55 SquareRoot as _,
56 TestnetV0,
58 ToBits,
59};
60use std::str::FromStr as _;
61
62impl Value {
63 pub fn to_fields(&self) -> Vec<SvmField> {
64 let mut bits = self.to_bits_le();
65 bits.push(true);
66 bits.chunks(SvmField::SIZE_IN_DATA_BITS)
67 .map(|bits| SvmField::from_bits_le(bits).expect("conversion should work"))
68 .collect()
69 }
70
71 pub fn gte(&self, rhs: &Self) -> Result<bool> {
72 rhs.gt(self).map(|v| !v)
73 }
74
75 pub fn lte(&self, rhs: &Self) -> Result<bool> {
76 rhs.lt(self).map(|v| !v)
77 }
78
79 pub fn lt(&self, rhs: &Self) -> Result<bool> {
80 use Value::*;
81 Ok(match (self, rhs) {
82 (U8(x), U8(y)) => x < y,
83 (U16(x), U16(y)) => x < y,
84 (U32(x), U32(y)) => x < y,
85 (U64(x), U64(y)) => x < y,
86 (U128(x), U128(y)) => x < y,
87 (I8(x), I8(y)) => x < y,
88 (I16(x), I16(y)) => x < y,
89 (I32(x), I32(y)) => x < y,
90 (I64(x), I64(y)) => x < y,
91 (I128(x), I128(y)) => x < y,
92 (Field(x), Field(y)) => x < y,
93 (a, b) => halt_no_span!("Type failure: {a} < {b}"),
94 })
95 }
96
97 pub fn gt(&self, rhs: &Self) -> Result<bool> {
98 use Value::*;
99 Ok(match (self, rhs) {
100 (U8(x), U8(y)) => x > y,
101 (U16(x), U16(y)) => x > y,
102 (U32(x), U32(y)) => x > y,
103 (U64(x), U64(y)) => x > y,
104 (U128(x), U128(y)) => x > y,
105 (I8(x), I8(y)) => x > y,
106 (I16(x), I16(y)) => x > y,
107 (I32(x), I32(y)) => x > y,
108 (I64(x), I64(y)) => x > y,
109 (I128(x), I128(y)) => x > y,
110 (Field(x), Field(y)) => x > y,
111 (a, b) => halt_no_span!("Type failure: {a} > {b}"),
112 })
113 }
114
115 pub fn neq(&self, rhs: &Self) -> Result<bool> {
116 self.eq(rhs).map(|v| !v)
117 }
118
119 pub fn eq(&self, rhs: &Self) -> Result<bool> {
125 use Value::*;
126 Ok(match (self, rhs) {
127 (Unit, Unit) => true,
128 (Bool(x), Bool(y)) => x == y,
129 (U8(x), U8(y)) => x == y,
130 (U16(x), U16(y)) => x == y,
131 (U32(x), U32(y)) => x == y,
132 (U64(x), U64(y)) => x == y,
133 (U128(x), U128(y)) => x == y,
134 (I8(x), I8(y)) => x == y,
135 (I16(x), I16(y)) => x == y,
136 (I32(x), I32(y)) => x == y,
137 (I64(x), I64(y)) => x == y,
138 (I128(x), I128(y)) => x == y,
139 (Field(x), Field(y)) => x == y,
140 (Group(x), Group(y)) => x == y,
141 (Array(x), Array(y)) => {
142 if x.len() != y.len() {
143 return Ok(false);
144 }
145 for (lhs, rhs) in x.iter().zip(y.iter()) {
146 match lhs.eq(rhs) {
147 Ok(true) => {}
148 Ok(false) => return Ok(false),
149 Err(e) => return Err(e),
150 }
151 }
152 true
153 }
154 (a, b) => halt_no_span!("Type failure: {a} == {b}"),
155 })
156 }
157
158 pub fn inc_wrapping(&self) -> Self {
159 match self {
160 Value::U8(x) => Value::U8(x.wrapping_add(1)),
161 Value::U16(x) => Value::U16(x.wrapping_add(1)),
162 Value::U32(x) => Value::U32(x.wrapping_add(1)),
163 Value::U64(x) => Value::U64(x.wrapping_add(1)),
164 Value::U128(x) => Value::U128(x.wrapping_add(1)),
165 Value::I8(x) => Value::I8(x.wrapping_add(1)),
166 Value::I16(x) => Value::I16(x.wrapping_add(1)),
167 Value::I32(x) => Value::I32(x.wrapping_add(1)),
168 Value::I64(x) => Value::I64(x.wrapping_add(1)),
169 Value::I128(x) => Value::I128(x.wrapping_add(1)),
170 _ => tc_fail!(),
171 }
172 }
173
174 pub fn generator() -> Self {
176 Value::Group(SvmGroup::generator())
177 }
178
179 pub fn simple_shl(&self, shift: u32) -> Self {
182 match self {
183 Value::U8(x) => Value::U8(x << shift),
184 Value::U16(x) => Value::U16(x << shift),
185 Value::U32(x) => Value::U32(x << shift),
186 Value::U64(x) => Value::U64(x << shift),
187 Value::U128(x) => Value::U128(x << shift),
188 Value::I8(x) => Value::I8(x << shift),
189 Value::I16(x) => Value::I16(x << shift),
190 Value::I32(x) => Value::I32(x << shift),
191 Value::I64(x) => Value::I64(x << shift),
192 Value::I128(x) => Value::I128(x << shift),
193 _ => tc_fail!(),
194 }
195 }
196
197 pub fn simple_shr(&self, shift: u32) -> Self {
198 match self {
199 Value::U8(x) => Value::U8(x >> shift),
200 Value::U16(x) => Value::U16(x >> shift),
201 Value::U32(x) => Value::U32(x >> shift),
202 Value::U64(x) => Value::U64(x >> shift),
203 Value::U128(x) => Value::U128(x >> shift),
204 Value::I8(x) => Value::I8(x >> shift),
205 Value::I16(x) => Value::I16(x >> shift),
206 Value::I32(x) => Value::I32(x >> shift),
207 Value::I64(x) => Value::I64(x >> shift),
208 Value::I128(x) => Value::I128(x >> shift),
209 _ => tc_fail!(),
210 }
211 }
212
213 pub fn cast(&self, cast_type: &Type) -> Option<Value> {
215 match self {
216 Value::Bool(b) => really_cast(SvmBoolean::new(*b), cast_type),
217 Value::U8(x) => really_cast(SvmInteger::new(*x), cast_type),
218 Value::U16(x) => really_cast(SvmInteger::new(*x), cast_type),
219 Value::U32(x) => really_cast(SvmInteger::new(*x), cast_type),
220 Value::U64(x) => really_cast(SvmInteger::new(*x), cast_type),
221 Value::U128(x) => really_cast(SvmInteger::new(*x), cast_type),
222 Value::I8(x) => really_cast(SvmInteger::new(*x), cast_type),
223 Value::I16(x) => really_cast(SvmInteger::new(*x), cast_type),
224 Value::I32(x) => really_cast(SvmInteger::new(*x), cast_type),
225 Value::I64(x) => really_cast(SvmInteger::new(*x), cast_type),
226 Value::I128(x) => really_cast(SvmInteger::new(*x), cast_type),
227 Value::Group(g) => really_cast(g.to_x_coordinate(), cast_type),
228 Value::Field(f) => really_cast(*f, cast_type),
229 Value::Scalar(s) => really_cast(*s, cast_type),
230 Value::Address(a) => really_cast(a.to_group().to_x_coordinate(), cast_type),
231 _ => None,
232 }
233 }
234}
235
236impl ToBits for Value {
237 fn write_bits_le(&self, vec: &mut Vec<bool>) {
238 use Value::*;
239
240 let plaintext: Plaintext<TestnetV0> = match self {
241 Bool(x) => SvmLiteral::Boolean(SvmBoolean::new(*x)).into(),
242 U8(x) => SvmLiteral::U8(SvmInteger::new(*x)).into(),
243 U16(x) => SvmLiteral::U16(SvmInteger::new(*x)).into(),
244 U32(x) => SvmLiteral::U32(SvmInteger::new(*x)).into(),
245 U64(x) => SvmLiteral::U64(SvmInteger::new(*x)).into(),
246 U128(x) => SvmLiteral::U128(SvmInteger::new(*x)).into(),
247 I8(x) => SvmLiteral::I8(SvmInteger::new(*x)).into(),
248 I16(x) => SvmLiteral::I16(SvmInteger::new(*x)).into(),
249 I32(x) => SvmLiteral::I32(SvmInteger::new(*x)).into(),
250 I64(x) => SvmLiteral::I64(SvmInteger::new(*x)).into(),
251 I128(x) => SvmLiteral::I128(SvmInteger::new(*x)).into(),
252 Group(x) => SvmLiteral::Group(*x).into(),
253 Field(x) => SvmLiteral::Field(*x).into(),
254 Scalar(x) => SvmLiteral::Scalar(*x).into(),
255 Address(x) => SvmLiteral::Address(*x).into(),
256 Struct(StructContents { name: _, contents }) => {
257 (contents.len() as u8).write_bits_le(vec);
258 for (name, value) in contents.iter() {
259 let name_s = name.to_string();
260 let identifier = SvmIdentifier::from_str(&name_s).expect("identifier should parse");
261 identifier.size_in_bits().write_bits_le(vec);
262 identifier.write_bits_le(vec);
263 let value_bits = value.to_bits_le();
264 (value_bits.len() as u16).write_bits_le(vec);
265 vec.extend_from_slice(&value_bits);
266 }
267 return;
268 }
269
270 Array(array) => {
271 for element in array.iter() {
272 let bits = element.to_bits_le();
273 (bits.len() as u16).write_bits_le(vec);
274 vec.extend_from_slice(&bits);
275 }
276 return;
277 }
278 _ => tc_fail!(),
279 };
280
281 plaintext.write_bits_le(vec);
282 }
283
284 fn write_bits_be(&self, _vec: &mut Vec<bool>) {
285 todo!()
286 }
287}
288
289pub fn literal_to_value(literal: &Literal, ty: &Option<Type>) -> Result<Value> {
290 fn prepare_snarkvm_string(s: &str, suffix: &str) -> String {
293 let (neg, rest) = s.strip_prefix("-").map(|rest| ("-", rest)).unwrap_or(("", s));
295 let mut rest = rest.trim_start_matches('0');
297 if rest.is_empty() {
298 rest = "0";
299 }
300 format!("{neg}{rest}{suffix}")
301 }
302
303 let value = match &literal.variant {
304 LiteralVariant::Boolean(b) => Value::Bool(*b),
305 LiteralVariant::Integer(IntegerType::U8, s, ..) => {
306 let s = s.replace("_", "");
307 Value::U8(u8::from_str_by_radix(&s).expect("Parsing guarantees this works."))
308 }
309 LiteralVariant::Integer(IntegerType::U16, s, ..) => {
310 let s = s.replace("_", "");
311 Value::U16(u16::from_str_by_radix(&s).expect("Parsing guarantees this works."))
312 }
313 LiteralVariant::Integer(IntegerType::U32, s, ..) => {
314 let s = s.replace("_", "");
315 Value::U32(u32::from_str_by_radix(&s).expect("Parsing guarantees this works."))
316 }
317 LiteralVariant::Integer(IntegerType::U64, s, ..) => {
318 let s = s.replace("_", "");
319 Value::U64(u64::from_str_by_radix(&s).expect("Parsing guarantees this works."))
320 }
321 LiteralVariant::Integer(IntegerType::U128, s, ..) => {
322 let s = s.replace("_", "");
323 Value::U128(u128::from_str_by_radix(&s).expect("Parsing guarantees this works."))
324 }
325 LiteralVariant::Integer(IntegerType::I8, s, ..) => {
326 let s = s.replace("_", "");
327 Value::I8(i8::from_str_by_radix(&s).expect("Parsing guarantees this works."))
328 }
329 LiteralVariant::Integer(IntegerType::I16, s, ..) => {
330 let s = s.replace("_", "");
331 Value::I16(i16::from_str_by_radix(&s).expect("Parsing guarantees this works."))
332 }
333 LiteralVariant::Integer(IntegerType::I32, s, ..) => {
334 let s = s.replace("_", "");
335 Value::I32(i32::from_str_by_radix(&s).expect("Parsing guarantees this works."))
336 }
337 LiteralVariant::Integer(IntegerType::I64, s, ..) => {
338 let s = s.replace("_", "");
339 Value::I64(i64::from_str_by_radix(&s).expect("Parsing guarantees this works."))
340 }
341 LiteralVariant::Integer(IntegerType::I128, s, ..) => {
342 let s = s.replace("_", "");
343 Value::I128(i128::from_str_by_radix(&s).expect("Parsing guarantees this works."))
344 }
345 LiteralVariant::Field(s) => Value::Field(prepare_snarkvm_string(s, "field").parse().expect_tc(literal.span())?),
346 LiteralVariant::Group(s) => Value::Group(prepare_snarkvm_string(s, "group").parse().expect_tc(literal.span())?),
347 LiteralVariant::Address(s) => {
348 if s.ends_with(".aleo") {
349 let program_id = ProgramID::from_str(s)?;
350 Value::Address(program_id.to_address()?)
351 } else {
352 Value::Address(s.parse().expect_tc(literal.span())?)
353 }
354 }
355 LiteralVariant::Scalar(s) => {
356 Value::Scalar(prepare_snarkvm_string(s, "scalar").parse().expect_tc(literal.span())?)
357 }
358 LiteralVariant::Unsuffixed(s) => match ty {
359 Some(Type::Integer(IntegerType::U8)) => {
360 let s = s.replace("_", "");
361 Value::U8(u8::from_str_by_radix(&s).expect("Parsing guarantees this works."))
362 }
363 Some(Type::Integer(IntegerType::U16)) => {
364 let s = s.replace("_", "");
365 Value::U16(u16::from_str_by_radix(&s).expect("Parsing guarantees this works."))
366 }
367 Some(Type::Integer(IntegerType::U32)) => {
368 let s = s.replace("_", "");
369 Value::U32(u32::from_str_by_radix(&s).expect("Parsing guarantees this works."))
370 }
371 Some(Type::Integer(IntegerType::U64)) => {
372 let s = s.replace("_", "");
373 Value::U64(u64::from_str_by_radix(&s).expect("Parsing guarantees this works."))
374 }
375 Some(Type::Integer(IntegerType::U128)) => {
376 let s = s.replace("_", "");
377 Value::U128(u128::from_str_by_radix(&s).expect("Parsing guarantees this works."))
378 }
379 Some(Type::Integer(IntegerType::I8)) => {
380 let s = s.replace("_", "");
381 Value::I8(i8::from_str_by_radix(&s).expect("Parsing guarantees this works."))
382 }
383 Some(Type::Integer(IntegerType::I16)) => {
384 let s = s.replace("_", "");
385 Value::I16(i16::from_str_by_radix(&s).expect("Parsing guarantees this works."))
386 }
387 Some(Type::Integer(IntegerType::I32)) => {
388 let s = s.replace("_", "");
389 Value::I32(i32::from_str_by_radix(&s).expect("Parsing guarantees this works."))
390 }
391 Some(Type::Integer(IntegerType::I64)) => {
392 let s = s.replace("_", "");
393 Value::I64(i64::from_str_by_radix(&s).expect("Parsing guarantees this works."))
394 }
395 Some(Type::Integer(IntegerType::I128)) => {
396 let s = s.replace("_", "");
397 Value::I128(i128::from_str_by_radix(&s).expect("Parsing guarantees this works."))
398 }
399 Some(Type::Field) => Value::Field(prepare_snarkvm_string(s, "field").parse().expect_tc(literal.span())?),
400 Some(Type::Group) => Value::Group(prepare_snarkvm_string(s, "group").parse().expect_tc(literal.span())?),
401 Some(Type::Scalar) => Value::Scalar(prepare_snarkvm_string(s, "scalar").parse().expect_tc(literal.span())?),
402 _ => {
403 halt!(literal.span(), "cannot infer type of unsuffixed literal")
404 }
405 },
406 LiteralVariant::String(..) => tc_fail!(),
407 };
408
409 Ok(value)
410}
411
412pub fn evaluate_unary(span: Span, op: UnaryOperation, value: &Value) -> Result<Value> {
414 let value_result = match op {
415 UnaryOperation::Abs => match value {
416 Value::I8(x) => {
417 if *x == i8::MIN {
418 halt!(span, "abs overflow");
419 } else {
420 Value::I8(x.abs())
421 }
422 }
423 Value::I16(x) => {
424 if *x == i16::MIN {
425 halt!(span, "abs overflow");
426 } else {
427 Value::I16(x.abs())
428 }
429 }
430 Value::I32(x) => {
431 if *x == i32::MIN {
432 halt!(span, "abs overflow");
433 } else {
434 Value::I32(x.abs())
435 }
436 }
437 Value::I64(x) => {
438 if *x == i64::MIN {
439 halt!(span, "abs overflow");
440 } else {
441 Value::I64(x.abs())
442 }
443 }
444 Value::I128(x) => {
445 if *x == i128::MIN {
446 halt!(span, "abs overflow");
447 } else {
448 Value::I128(x.abs())
449 }
450 }
451 _ => halt!(span, "Type error"),
452 },
453 UnaryOperation::AbsWrapped => match value {
454 Value::I8(x) => Value::I8(x.unsigned_abs() as i8),
455 Value::I16(x) => Value::I16(x.unsigned_abs() as i16),
456 Value::I32(x) => Value::I32(x.unsigned_abs() as i32),
457 Value::I64(x) => Value::I64(x.unsigned_abs() as i64),
458 Value::I128(x) => Value::I128(x.unsigned_abs() as i128),
459 _ => halt!(span, "Type error"),
460 },
461 UnaryOperation::Double => match value {
462 Value::Field(x) => Value::Field(x.double()),
463 Value::Group(x) => Value::Group(x.double()),
464 _ => halt!(span, "Type error"),
465 },
466 UnaryOperation::Inverse => match value {
467 Value::Field(x) => {
468 let Ok(y) = x.inverse() else {
469 halt!(span, "attempt to invert 0field");
470 };
471 Value::Field(y)
472 }
473 _ => halt!(span, "Can only invert fields"),
474 },
475 UnaryOperation::Negate => match value {
476 Value::I8(x) => match x.checked_neg() {
477 None => halt!(span, "negation overflow"),
478 Some(y) => Value::I8(y),
479 },
480 Value::I16(x) => match x.checked_neg() {
481 None => halt!(span, "negation overflow"),
482 Some(y) => Value::I16(y),
483 },
484 Value::I32(x) => match x.checked_neg() {
485 None => halt!(span, "negation overflow"),
486 Some(y) => Value::I32(y),
487 },
488 Value::I64(x) => match x.checked_neg() {
489 None => halt!(span, "negation overflow"),
490 Some(y) => Value::I64(y),
491 },
492 Value::I128(x) => match x.checked_neg() {
493 None => halt!(span, "negation overflow"),
494 Some(y) => Value::I128(y),
495 },
496 Value::Group(x) => Value::Group(-*x),
497 Value::Field(x) => Value::Field(-*x),
498 _ => halt!(span, "Type error"),
499 },
500 UnaryOperation::Not => match value {
501 Value::Bool(x) => Value::Bool(!x),
502 Value::U8(x) => Value::U8(!x),
503 Value::U16(x) => Value::U16(!x),
504 Value::U32(x) => Value::U32(!x),
505 Value::U64(x) => Value::U64(!x),
506 Value::U128(x) => Value::U128(!x),
507 Value::I8(x) => Value::I8(!x),
508 Value::I16(x) => Value::I16(!x),
509 Value::I32(x) => Value::I32(!x),
510 Value::I64(x) => Value::I64(!x),
511 Value::I128(x) => Value::I128(!x),
512 _ => halt!(span, "Type error"),
513 },
514 UnaryOperation::Square => match value {
515 Value::Field(x) => Value::Field(x.square()),
516 _ => halt!(span, "Can only square fields"),
517 },
518 UnaryOperation::SquareRoot => match value {
519 Value::Field(x) => {
520 let Ok(y) = x.square_root() else {
521 halt!(span, "square root failure");
522 };
523 Value::Field(y)
524 }
525 _ => halt!(span, "Can only apply square_root to fields"),
526 },
527 UnaryOperation::ToXCoordinate => match value {
528 Value::Group(x) => Value::Field(x.to_x_coordinate()),
529 _ => tc_fail!(),
530 },
531 UnaryOperation::ToYCoordinate => match value {
532 Value::Group(x) => Value::Field(x.to_y_coordinate()),
533 _ => tc_fail!(),
534 },
535 };
536
537 Ok(value_result)
538}
539
540pub fn evaluate_binary(span: Span, op: BinaryOperation, lhs: &Value, rhs: &Value) -> Result<Value> {
542 let value = match op {
543 BinaryOperation::Add => {
544 let Some(value) = (match (lhs, rhs) {
545 (Value::U8(x), Value::U8(y)) => x.checked_add(*y).map(Value::U8),
546 (Value::U16(x), Value::U16(y)) => x.checked_add(*y).map(Value::U16),
547 (Value::U32(x), Value::U32(y)) => x.checked_add(*y).map(Value::U32),
548 (Value::U64(x), Value::U64(y)) => x.checked_add(*y).map(Value::U64),
549 (Value::U128(x), Value::U128(y)) => x.checked_add(*y).map(Value::U128),
550 (Value::I8(x), Value::I8(y)) => x.checked_add(*y).map(Value::I8),
551 (Value::I16(x), Value::I16(y)) => x.checked_add(*y).map(Value::I16),
552 (Value::I32(x), Value::I32(y)) => x.checked_add(*y).map(Value::I32),
553 (Value::I64(x), Value::I64(y)) => x.checked_add(*y).map(Value::I64),
554 (Value::I128(x), Value::I128(y)) => x.checked_add(*y).map(Value::I128),
555 (Value::Group(x), Value::Group(y)) => Some(Value::Group(*x + *y)),
556 (Value::Field(x), Value::Field(y)) => Some(Value::Field(*x + *y)),
557 (Value::Scalar(x), Value::Scalar(y)) => Some(Value::Scalar(*x + *y)),
558 _ => halt!(span, "Type error"),
559 }) else {
560 halt!(span, "add overflow");
561 };
562 value
563 }
564 BinaryOperation::AddWrapped => match (lhs, rhs) {
565 (Value::U8(x), Value::U8(y)) => Value::U8(x.wrapping_add(*y)),
566 (Value::U16(x), Value::U16(y)) => Value::U16(x.wrapping_add(*y)),
567 (Value::U32(x), Value::U32(y)) => Value::U32(x.wrapping_add(*y)),
568 (Value::U64(x), Value::U64(y)) => Value::U64(x.wrapping_add(*y)),
569 (Value::U128(x), Value::U128(y)) => Value::U128(x.wrapping_add(*y)),
570 (Value::I8(x), Value::I8(y)) => Value::I8(x.wrapping_add(*y)),
571 (Value::I16(x), Value::I16(y)) => Value::I16(x.wrapping_add(*y)),
572 (Value::I32(x), Value::I32(y)) => Value::I32(x.wrapping_add(*y)),
573 (Value::I64(x), Value::I64(y)) => Value::I64(x.wrapping_add(*y)),
574 (Value::I128(x), Value::I128(y)) => Value::I128(x.wrapping_add(*y)),
575 _ => halt!(span, "Type error"),
576 },
577 BinaryOperation::And => match (lhs, rhs) {
578 (Value::Bool(x), Value::Bool(y)) => Value::Bool(*x && *y),
579 _ => halt!(span, "Type error"),
580 },
581 BinaryOperation::BitwiseAnd => match (lhs, rhs) {
582 (Value::Bool(x), Value::Bool(y)) => Value::Bool(x & y),
583 (Value::U8(x), Value::U8(y)) => Value::U8(x & y),
584 (Value::U16(x), Value::U16(y)) => Value::U16(x & y),
585 (Value::U32(x), Value::U32(y)) => Value::U32(x & y),
586 (Value::U64(x), Value::U64(y)) => Value::U64(x & y),
587 (Value::U128(x), Value::U128(y)) => Value::U128(x & y),
588 (Value::I8(x), Value::I8(y)) => Value::I8(x & y),
589 (Value::I16(x), Value::I16(y)) => Value::I16(x & y),
590 (Value::I32(x), Value::I32(y)) => Value::I32(x & y),
591 (Value::I64(x), Value::I64(y)) => Value::I64(x & y),
592 (Value::I128(x), Value::I128(y)) => Value::I128(x & y),
593 _ => halt!(span, "Type error"),
594 },
595 BinaryOperation::Div => {
596 let Some(value) = (match (lhs, rhs) {
597 (Value::U8(x), Value::U8(y)) => x.checked_div(*y).map(Value::U8),
598 (Value::U16(x), Value::U16(y)) => x.checked_div(*y).map(Value::U16),
599 (Value::U32(x), Value::U32(y)) => x.checked_div(*y).map(Value::U32),
600 (Value::U64(x), Value::U64(y)) => x.checked_div(*y).map(Value::U64),
601 (Value::U128(x), Value::U128(y)) => x.checked_div(*y).map(Value::U128),
602 (Value::I8(x), Value::I8(y)) => x.checked_div(*y).map(Value::I8),
603 (Value::I16(x), Value::I16(y)) => x.checked_div(*y).map(Value::I16),
604 (Value::I32(x), Value::I32(y)) => x.checked_div(*y).map(Value::I32),
605 (Value::I64(x), Value::I64(y)) => x.checked_div(*y).map(Value::I64),
606 (Value::I128(x), Value::I128(y)) => x.checked_div(*y).map(Value::I128),
607 (Value::Field(x), Value::Field(y)) => y.inverse().map(|y| Value::Field(*x * y)).ok(),
608 _ => halt!(span, "Type error"),
609 }) else {
610 halt!(span, "div overflow");
611 };
612 value
613 }
614 BinaryOperation::DivWrapped => match (lhs, rhs) {
615 (Value::U8(_), Value::U8(0))
616 | (Value::U16(_), Value::U16(0))
617 | (Value::U32(_), Value::U32(0))
618 | (Value::U64(_), Value::U64(0))
619 | (Value::U128(_), Value::U128(0))
620 | (Value::I8(_), Value::I8(0))
621 | (Value::I16(_), Value::I16(0))
622 | (Value::I32(_), Value::I32(0))
623 | (Value::I64(_), Value::I64(0))
624 | (Value::I128(_), Value::I128(0)) => halt!(span, "divide by 0"),
625 (Value::U8(x), Value::U8(y)) => Value::U8(x.wrapping_div(*y)),
626 (Value::U16(x), Value::U16(y)) => Value::U16(x.wrapping_div(*y)),
627 (Value::U32(x), Value::U32(y)) => Value::U32(x.wrapping_div(*y)),
628 (Value::U64(x), Value::U64(y)) => Value::U64(x.wrapping_div(*y)),
629 (Value::U128(x), Value::U128(y)) => Value::U128(x.wrapping_div(*y)),
630 (Value::I8(x), Value::I8(y)) => Value::I8(x.wrapping_div(*y)),
631 (Value::I16(x), Value::I16(y)) => Value::I16(x.wrapping_div(*y)),
632 (Value::I32(x), Value::I32(y)) => Value::I32(x.wrapping_div(*y)),
633 (Value::I64(x), Value::I64(y)) => Value::I64(x.wrapping_div(*y)),
634 (Value::I128(x), Value::I128(y)) => Value::I128(x.wrapping_div(*y)),
635 _ => halt!(span, "Type error"),
636 },
637 BinaryOperation::Eq => Value::Bool(lhs.eq(rhs)?),
638 BinaryOperation::Gte => Value::Bool(lhs.gte(rhs)?),
639 BinaryOperation::Gt => Value::Bool(lhs.gt(rhs)?),
640 BinaryOperation::Lte => Value::Bool(lhs.lte(rhs)?),
641 BinaryOperation::Lt => Value::Bool(lhs.lt(rhs)?),
642 BinaryOperation::Mod => {
643 let Some(value) = (match (lhs, rhs) {
644 (Value::U8(x), Value::U8(y)) => x.checked_rem(*y).map(Value::U8),
645 (Value::U16(x), Value::U16(y)) => x.checked_rem(*y).map(Value::U16),
646 (Value::U32(x), Value::U32(y)) => x.checked_rem(*y).map(Value::U32),
647 (Value::U64(x), Value::U64(y)) => x.checked_rem(*y).map(Value::U64),
648 (Value::U128(x), Value::U128(y)) => x.checked_rem(*y).map(Value::U128),
649 (Value::I8(x), Value::I8(y)) => x.checked_rem(*y).map(Value::I8),
650 (Value::I16(x), Value::I16(y)) => x.checked_rem(*y).map(Value::I16),
651 (Value::I32(x), Value::I32(y)) => x.checked_rem(*y).map(Value::I32),
652 (Value::I64(x), Value::I64(y)) => x.checked_rem(*y).map(Value::I64),
653 (Value::I128(x), Value::I128(y)) => x.checked_rem(*y).map(Value::I128),
654 _ => halt!(span, "Type error"),
655 }) else {
656 halt!(span, "mod overflow");
657 };
658 value
659 }
660 BinaryOperation::Mul => {
661 let Some(value) = (match (lhs, rhs) {
662 (Value::U8(x), Value::U8(y)) => x.checked_mul(*y).map(Value::U8),
663 (Value::U16(x), Value::U16(y)) => x.checked_mul(*y).map(Value::U16),
664 (Value::U32(x), Value::U32(y)) => x.checked_mul(*y).map(Value::U32),
665 (Value::U64(x), Value::U64(y)) => x.checked_mul(*y).map(Value::U64),
666 (Value::U128(x), Value::U128(y)) => x.checked_mul(*y).map(Value::U128),
667 (Value::I8(x), Value::I8(y)) => x.checked_mul(*y).map(Value::I8),
668 (Value::I16(x), Value::I16(y)) => x.checked_mul(*y).map(Value::I16),
669 (Value::I32(x), Value::I32(y)) => x.checked_mul(*y).map(Value::I32),
670 (Value::I64(x), Value::I64(y)) => x.checked_mul(*y).map(Value::I64),
671 (Value::I128(x), Value::I128(y)) => x.checked_mul(*y).map(Value::I128),
672 (Value::Field(x), Value::Field(y)) => Some(Value::Field(*x * *y)),
673 (Value::Group(x), Value::Scalar(y)) => Some(Value::Group(*x * *y)),
674 (Value::Scalar(x), Value::Group(y)) => Some(Value::Group(*x * *y)),
675 _ => halt!(span, "Type error"),
676 }) else {
677 halt!(span, "mul overflow");
678 };
679 value
680 }
681 BinaryOperation::MulWrapped => match (lhs, rhs) {
682 (Value::U8(x), Value::U8(y)) => Value::U8(x.wrapping_mul(*y)),
683 (Value::U16(x), Value::U16(y)) => Value::U16(x.wrapping_mul(*y)),
684 (Value::U32(x), Value::U32(y)) => Value::U32(x.wrapping_mul(*y)),
685 (Value::U64(x), Value::U64(y)) => Value::U64(x.wrapping_mul(*y)),
686 (Value::U128(x), Value::U128(y)) => Value::U128(x.wrapping_mul(*y)),
687 (Value::I8(x), Value::I8(y)) => Value::I8(x.wrapping_mul(*y)),
688 (Value::I16(x), Value::I16(y)) => Value::I16(x.wrapping_mul(*y)),
689 (Value::I32(x), Value::I32(y)) => Value::I32(x.wrapping_mul(*y)),
690 (Value::I64(x), Value::I64(y)) => Value::I64(x.wrapping_mul(*y)),
691 (Value::I128(x), Value::I128(y)) => Value::I128(x.wrapping_mul(*y)),
692 _ => halt!(span, "Type error"),
693 },
694
695 BinaryOperation::Nand => match (lhs, rhs) {
696 (Value::Bool(x), Value::Bool(y)) => Value::Bool(!(x & y)),
697 _ => halt!(span, "Type error"),
698 },
699 BinaryOperation::Neq => Value::Bool(lhs.neq(rhs)?),
700 BinaryOperation::Nor => match (lhs, rhs) {
701 (Value::Bool(x), Value::Bool(y)) => Value::Bool(!(x | y)),
702 _ => halt!(span, "Type error"),
703 },
704 BinaryOperation::Or => match (lhs, rhs) {
705 (Value::Bool(x), Value::Bool(y)) => Value::Bool(x | y),
706 _ => halt!(span, "Type error"),
707 },
708 BinaryOperation::BitwiseOr => match (lhs, rhs) {
709 (Value::Bool(x), Value::Bool(y)) => Value::Bool(x | y),
710 (Value::U8(x), Value::U8(y)) => Value::U8(x | y),
711 (Value::U16(x), Value::U16(y)) => Value::U16(x | y),
712 (Value::U32(x), Value::U32(y)) => Value::U32(x | y),
713 (Value::U64(x), Value::U64(y)) => Value::U64(x | y),
714 (Value::U128(x), Value::U128(y)) => Value::U128(x | y),
715 (Value::I8(x), Value::I8(y)) => Value::I8(x | y),
716 (Value::I16(x), Value::I16(y)) => Value::I16(x | y),
717 (Value::I32(x), Value::I32(y)) => Value::I32(x | y),
718 (Value::I64(x), Value::I64(y)) => Value::I64(x | y),
719 (Value::I128(x), Value::I128(y)) => Value::I128(x | y),
720 _ => halt!(span, "Type error"),
721 },
722 BinaryOperation::Pow => {
723 if let (Value::Field(x), Value::Field(y)) = (&lhs, &rhs) {
724 Value::Field(x.pow(y))
725 } else {
726 let rhs: u32 = match rhs {
727 Value::U8(y) => (*y).into(),
728 Value::U16(y) => (*y).into(),
729 Value::U32(y) => *y,
730 _ => tc_fail!(),
731 };
732
733 let Some(value) = (match lhs {
734 Value::U8(x) => x.checked_pow(rhs).map(Value::U8),
735 Value::U16(x) => x.checked_pow(rhs).map(Value::U16),
736 Value::U32(x) => x.checked_pow(rhs).map(Value::U32),
737 Value::U64(x) => x.checked_pow(rhs).map(Value::U64),
738 Value::U128(x) => x.checked_pow(rhs).map(Value::U128),
739 Value::I8(x) => x.checked_pow(rhs).map(Value::I8),
740 Value::I16(x) => x.checked_pow(rhs).map(Value::I16),
741 Value::I32(x) => x.checked_pow(rhs).map(Value::I32),
742 Value::I64(x) => x.checked_pow(rhs).map(Value::I64),
743 Value::I128(x) => x.checked_pow(rhs).map(Value::I128),
744 _ => halt!(span, "Type error"),
745 }) else {
746 halt!(span, "pow overflow");
747 };
748 value
749 }
750 }
751 BinaryOperation::PowWrapped => {
752 let rhs: u32 = match rhs {
753 Value::U8(y) => (*y).into(),
754 Value::U16(y) => (*y).into(),
755 Value::U32(y) => *y,
756 _ => halt!(span, "Type error"),
757 };
758
759 match lhs {
760 Value::U8(x) => Value::U8(x.wrapping_pow(rhs)),
761 Value::U16(x) => Value::U16(x.wrapping_pow(rhs)),
762 Value::U32(x) => Value::U32(x.wrapping_pow(rhs)),
763 Value::U64(x) => Value::U64(x.wrapping_pow(rhs)),
764 Value::U128(x) => Value::U128(x.wrapping_pow(rhs)),
765 Value::I8(x) => Value::I8(x.wrapping_pow(rhs)),
766 Value::I16(x) => Value::I16(x.wrapping_pow(rhs)),
767 Value::I32(x) => Value::I32(x.wrapping_pow(rhs)),
768 Value::I64(x) => Value::I64(x.wrapping_pow(rhs)),
769 Value::I128(x) => Value::I128(x.wrapping_pow(rhs)),
770 _ => halt!(span, "Type error"),
771 }
772 }
773 BinaryOperation::Rem => {
774 let Some(value) = (match (lhs, rhs) {
775 (Value::U8(x), Value::U8(y)) => x.checked_rem(*y).map(Value::U8),
776 (Value::U16(x), Value::U16(y)) => x.checked_rem(*y).map(Value::U16),
777 (Value::U32(x), Value::U32(y)) => x.checked_rem(*y).map(Value::U32),
778 (Value::U64(x), Value::U64(y)) => x.checked_rem(*y).map(Value::U64),
779 (Value::U128(x), Value::U128(y)) => x.checked_rem(*y).map(Value::U128),
780 (Value::I8(x), Value::I8(y)) => x.checked_rem(*y).map(Value::I8),
781 (Value::I16(x), Value::I16(y)) => x.checked_rem(*y).map(Value::I16),
782 (Value::I32(x), Value::I32(y)) => x.checked_rem(*y).map(Value::I32),
783 (Value::I64(x), Value::I64(y)) => x.checked_rem(*y).map(Value::I64),
784 (Value::I128(x), Value::I128(y)) => x.checked_rem(*y).map(Value::I128),
785 _ => halt!(span, "Type error"),
786 }) else {
787 halt!(span, "rem error");
788 };
789 value
790 }
791 BinaryOperation::RemWrapped => match (lhs, rhs) {
792 (Value::U8(_), Value::U8(0))
793 | (Value::U16(_), Value::U16(0))
794 | (Value::U32(_), Value::U32(0))
795 | (Value::U64(_), Value::U64(0))
796 | (Value::U128(_), Value::U128(0))
797 | (Value::I8(_), Value::I8(0))
798 | (Value::I16(_), Value::I16(0))
799 | (Value::I32(_), Value::I32(0))
800 | (Value::I64(_), Value::I64(0))
801 | (Value::I128(_), Value::I128(0)) => halt!(span, "rem by 0"),
802 (Value::U8(x), Value::U8(y)) => Value::U8(x.wrapping_rem(*y)),
803 (Value::U16(x), Value::U16(y)) => Value::U16(x.wrapping_rem(*y)),
804 (Value::U32(x), Value::U32(y)) => Value::U32(x.wrapping_rem(*y)),
805 (Value::U64(x), Value::U64(y)) => Value::U64(x.wrapping_rem(*y)),
806 (Value::U128(x), Value::U128(y)) => Value::U128(x.wrapping_rem(*y)),
807 (Value::I8(x), Value::I8(y)) => Value::I8(x.wrapping_rem(*y)),
808 (Value::I16(x), Value::I16(y)) => Value::I16(x.wrapping_rem(*y)),
809 (Value::I32(x), Value::I32(y)) => Value::I32(x.wrapping_rem(*y)),
810 (Value::I64(x), Value::I64(y)) => Value::I64(x.wrapping_rem(*y)),
811 (Value::I128(x), Value::I128(y)) => Value::I128(x.wrapping_rem(*y)),
812 _ => halt!(span, "Type error"),
813 },
814 BinaryOperation::Shl => {
815 let rhs: u32 = match rhs {
816 Value::U8(y) => (*y).into(),
817 Value::U16(y) => (*y).into(),
818 Value::U32(y) => *y,
819 _ => halt!(span, "Type error"),
820 };
821 match lhs {
822 Value::U8(_) | Value::I8(_) if rhs >= 8 => halt!(span, "shl overflow"),
823 Value::U16(_) | Value::I16(_) if rhs >= 16 => halt!(span, "shl overflow"),
824 Value::U32(_) | Value::I32(_) if rhs >= 32 => halt!(span, "shl overflow"),
825 Value::U64(_) | Value::I64(_) if rhs >= 64 => halt!(span, "shl overflow"),
826 Value::U128(_) | Value::I128(_) if rhs >= 128 => halt!(span, "shl overflow"),
827 _ => {}
828 }
829
830 let shifted = lhs.simple_shl(rhs);
832 let reshifted = shifted.simple_shr(rhs);
833 if lhs.eq(&reshifted)? {
834 shifted
835 } else {
836 halt!(span, "shl overflow");
837 }
838 }
839
840 BinaryOperation::ShlWrapped => {
841 let rhs: u32 = match rhs {
842 Value::U8(y) => (*y).into(),
843 Value::U16(y) => (*y).into(),
844 Value::U32(y) => *y,
845 _ => halt!(span, "Type error"),
846 };
847 match lhs {
848 Value::U8(x) => Value::U8(x.wrapping_shl(rhs)),
849 Value::U16(x) => Value::U16(x.wrapping_shl(rhs)),
850 Value::U32(x) => Value::U32(x.wrapping_shl(rhs)),
851 Value::U64(x) => Value::U64(x.wrapping_shl(rhs)),
852 Value::U128(x) => Value::U128(x.wrapping_shl(rhs)),
853 Value::I8(x) => Value::I8(x.wrapping_shl(rhs)),
854 Value::I16(x) => Value::I16(x.wrapping_shl(rhs)),
855 Value::I32(x) => Value::I32(x.wrapping_shl(rhs)),
856 Value::I64(x) => Value::I64(x.wrapping_shl(rhs)),
857 Value::I128(x) => Value::I128(x.wrapping_shl(rhs)),
858 _ => halt!(span, "Type error"),
859 }
860 }
861
862 BinaryOperation::Shr => {
863 let rhs: u32 = match rhs {
864 Value::U8(y) => (*y).into(),
865 Value::U16(y) => (*y).into(),
866 Value::U32(y) => *y,
867 _ => halt!(span, "Type error"),
868 };
869
870 match lhs {
871 Value::U8(_) | Value::I8(_) if rhs >= 8 => halt!(span, "shr overflow"),
872 Value::U16(_) | Value::I16(_) if rhs >= 16 => halt!(span, "shr overflow"),
873 Value::U32(_) | Value::I32(_) if rhs >= 32 => halt!(span, "shr overflow"),
874 Value::U64(_) | Value::I64(_) if rhs >= 64 => halt!(span, "shr overflow"),
875 Value::U128(_) | Value::I128(_) if rhs >= 128 => halt!(span, "shr overflow"),
876 _ => {}
877 }
878
879 lhs.simple_shr(rhs)
880 }
881
882 BinaryOperation::ShrWrapped => {
883 let rhs: u32 = match rhs {
884 Value::U8(y) => (*y).into(),
885 Value::U16(y) => (*y).into(),
886 Value::U32(y) => *y,
887 _ => halt!(span, "Type error"),
888 };
889
890 match lhs {
891 Value::U8(x) => Value::U8(x.wrapping_shr(rhs)),
892 Value::U16(x) => Value::U16(x.wrapping_shr(rhs)),
893 Value::U32(x) => Value::U32(x.wrapping_shr(rhs)),
894 Value::U64(x) => Value::U64(x.wrapping_shr(rhs)),
895 Value::U128(x) => Value::U128(x.wrapping_shr(rhs)),
896 Value::I8(x) => Value::I8(x.wrapping_shr(rhs)),
897 Value::I16(x) => Value::I16(x.wrapping_shr(rhs)),
898 Value::I32(x) => Value::I32(x.wrapping_shr(rhs)),
899 Value::I64(x) => Value::I64(x.wrapping_shr(rhs)),
900 Value::I128(x) => Value::I128(x.wrapping_shr(rhs)),
901 _ => halt!(span, "Type error"),
902 }
903 }
904
905 BinaryOperation::Sub => {
906 let Some(value) = (match (lhs, rhs) {
907 (Value::U8(x), Value::U8(y)) => x.checked_sub(*y).map(Value::U8),
908 (Value::U16(x), Value::U16(y)) => x.checked_sub(*y).map(Value::U16),
909 (Value::U32(x), Value::U32(y)) => x.checked_sub(*y).map(Value::U32),
910 (Value::U64(x), Value::U64(y)) => x.checked_sub(*y).map(Value::U64),
911 (Value::U128(x), Value::U128(y)) => x.checked_sub(*y).map(Value::U128),
912 (Value::I8(x), Value::I8(y)) => x.checked_sub(*y).map(Value::I8),
913 (Value::I16(x), Value::I16(y)) => x.checked_sub(*y).map(Value::I16),
914 (Value::I32(x), Value::I32(y)) => x.checked_sub(*y).map(Value::I32),
915 (Value::I64(x), Value::I64(y)) => x.checked_sub(*y).map(Value::I64),
916 (Value::I128(x), Value::I128(y)) => x.checked_sub(*y).map(Value::I128),
917 (Value::Group(x), Value::Group(y)) => Some(Value::Group(*x - *y)),
918 (Value::Field(x), Value::Field(y)) => Some(Value::Field(*x - *y)),
919 _ => halt!(span, "Type error"),
920 }) else {
921 halt!(span, "sub overflow");
922 };
923 value
924 }
925
926 BinaryOperation::SubWrapped => match (lhs, rhs) {
927 (Value::U8(x), Value::U8(y)) => Value::U8(x.wrapping_sub(*y)),
928 (Value::U16(x), Value::U16(y)) => Value::U16(x.wrapping_sub(*y)),
929 (Value::U32(x), Value::U32(y)) => Value::U32(x.wrapping_sub(*y)),
930 (Value::U64(x), Value::U64(y)) => Value::U64(x.wrapping_sub(*y)),
931 (Value::U128(x), Value::U128(y)) => Value::U128(x.wrapping_sub(*y)),
932 (Value::I8(x), Value::I8(y)) => Value::I8(x.wrapping_sub(*y)),
933 (Value::I16(x), Value::I16(y)) => Value::I16(x.wrapping_sub(*y)),
934 (Value::I32(x), Value::I32(y)) => Value::I32(x.wrapping_sub(*y)),
935 (Value::I64(x), Value::I64(y)) => Value::I64(x.wrapping_sub(*y)),
936 (Value::I128(x), Value::I128(y)) => Value::I128(x.wrapping_sub(*y)),
937 _ => halt!(span, "Type error"),
938 },
939
940 BinaryOperation::Xor => match (lhs, rhs) {
941 (Value::Bool(x), Value::Bool(y)) => Value::Bool(*x ^ *y),
942 (Value::U8(x), Value::U8(y)) => Value::U8(*x ^ *y),
943 (Value::U16(x), Value::U16(y)) => Value::U16(*x ^ *y),
944 (Value::U32(x), Value::U32(y)) => Value::U32(*x ^ *y),
945 (Value::U64(x), Value::U64(y)) => Value::U64(*x ^ *y),
946 (Value::U128(x), Value::U128(y)) => Value::U128(*x ^ *y),
947 (Value::I8(x), Value::I8(y)) => Value::I8(*x ^ *y),
948 (Value::I16(x), Value::I16(y)) => Value::I16(*x ^ *y),
949 (Value::I32(x), Value::I32(y)) => Value::I32(*x ^ *y),
950 (Value::I64(x), Value::I64(y)) => Value::I64(*x ^ *y),
951 (Value::I128(x), Value::I128(y)) => Value::I128(*x ^ *y),
952 _ => halt!(span, "Type error"),
953 },
954 };
955 Ok(value)
956}
957
958fn really_cast<C>(c: C, cast_type: &Type) -> Option<Value>
959where
960 C: Cast<SvmAddress>
961 + Cast<SvmField>
962 + Cast<SvmAddress>
963 + Cast<SvmGroup>
964 + Cast<SvmBoolean>
965 + Cast<SvmScalar>
966 + Cast<SvmInteger<u8>>
967 + Cast<SvmInteger<u16>>
968 + Cast<SvmInteger<u32>>
969 + Cast<SvmInteger<u64>>
970 + Cast<SvmInteger<u128>>
971 + Cast<SvmInteger<i8>>
972 + Cast<SvmInteger<i16>>
973 + Cast<SvmInteger<i32>>
974 + Cast<SvmInteger<i64>>
975 + Cast<SvmInteger<i128>>,
976{
977 use Type::*;
978
979 let value = match cast_type {
980 Address => Value::Address(c.cast().ok()?),
981 Boolean => Value::Bool({
982 let b: SvmBoolean = c.cast().ok()?;
983 *b
984 }),
985 Field => Value::Field(c.cast().ok()?),
986 Group => Value::Group(c.cast().ok()?),
987 Integer(IntegerType::U8) => Value::U8({
988 let i: SvmInteger<u8> = c.cast().ok()?;
989 *i
990 }),
991 Integer(IntegerType::U16) => Value::U16({
992 let i: SvmInteger<u16> = c.cast().ok()?;
993 *i
994 }),
995 Integer(IntegerType::U32) => Value::U32({
996 let i: SvmInteger<u32> = c.cast().ok()?;
997 *i
998 }),
999 Integer(IntegerType::U64) => Value::U64({
1000 let i: SvmInteger<u64> = c.cast().ok()?;
1001 *i
1002 }),
1003 Integer(IntegerType::U128) => Value::U128({
1004 let i: SvmInteger<u128> = c.cast().ok()?;
1005 *i
1006 }),
1007 Integer(IntegerType::I8) => Value::I8({
1008 let i: SvmInteger<i8> = c.cast().ok()?;
1009 *i
1010 }),
1011 Integer(IntegerType::I16) => Value::I16({
1012 let i: SvmInteger<i16> = c.cast().ok()?;
1013 *i
1014 }),
1015 Integer(IntegerType::I32) => Value::I32({
1016 let i: SvmInteger<i32> = c.cast().ok()?;
1017 *i
1018 }),
1019 Integer(IntegerType::I64) => Value::I64({
1020 let i: SvmInteger<i64> = c.cast().ok()?;
1021 *i
1022 }),
1023 Integer(IntegerType::I128) => Value::I128({
1024 let i: SvmInteger<i128> = c.cast().ok()?;
1025 *i
1026 }),
1027 Scalar => Value::Scalar(c.cast().ok()?),
1028
1029 _ => tc_fail!(),
1030 };
1031 Some(value)
1032}