Skip to main content

soroban_env_host/host/
num.rs

1#[macro_export]
2macro_rules! impl_wrapping_obj_from_num {
3    ($host_fn: ident, $hot: ty, $obj: ty, $num: ty) => {
4        fn $host_fn(&self, _vmcaller: &mut VmCaller<Host>, u: $num) -> Result<$obj, HostError> {
5            self.add_host_object(<$hot>::from(u))
6        }
7    };
8}
9
10#[macro_export]
11macro_rules! impl_wrapping_obj_to_num {
12    ($host_fn: ident, $data: ty, $obj: ty, $num: ty) => {
13        fn $host_fn(&self, _vmcaller: &mut VmCaller<Host>, obj: $obj) -> Result<$num, HostError> {
14            self.visit_obj(obj, |t: &$data| Ok(t.metered_clone(self)?.into()))
15        }
16    };
17}
18
19#[macro_export]
20macro_rules! impl_bignum_host_fns {
21    (@core $host: ident, $lhs_val: ident, $rhs_val: ident, $maybe_res: ident,
22           $method: ident, $num: ty, $cost: ident) => {
23        $host.charge_budget(ContractCostType::$cost, None)?;
24        let lhs: $num = $lhs_val.to_val().try_into_val($host)?;
25        let rhs = $rhs_val.to_val().try_into_val($host)?;
26        $maybe_res = lhs.$method(rhs);
27    };
28    ($host_fn: ident, $method: ident, $num: ty, $valty: ty, $operand_valty: ty, $cost: ident) => {
29        fn $host_fn(
30            &self,
31            _vmcaller: &mut VmCaller<Self::VmUserState>,
32            lhs_val: $valty,
33            rhs_val: $operand_valty,
34        ) -> Result<$valty, Self::Error> {
35            let host = self;
36            let maybe_res: Option<$num>;
37            impl_bignum_host_fns!(@core host, lhs_val, rhs_val, maybe_res,
38                                         $method, $num, $cost);
39            let res = maybe_res.ok_or_else(|| {
40                host.err(
41                    ScErrorType::Object,
42                    ScErrorCode::ArithDomain,
43                    "overflow has occurred",
44                    &[lhs_val.to_val(), rhs_val.to_val()],
45                )
46            })?;
47            Ok(res.try_into_val(host)?)
48        }
49    };
50    ($host_fn: ident, $method: ident, $num: ty, $valty: ty, $operand_valty: ty, $cost: ident, checked) => {
51        fn $host_fn(
52            &self,
53            _vmcaller: &mut VmCaller<Self::VmUserState>,
54            lhs_val: $valty,
55            rhs_val: $operand_valty,
56        ) -> Result<Val, Self::Error> {
57            let host = self;
58            let maybe_res: Option<$num>;
59            impl_bignum_host_fns!(@core host, lhs_val, rhs_val, maybe_res,
60                                         $method, $num, $cost);
61            match maybe_res {
62                Some(res) => {
63                    let v: $valty = res.try_into_val(host)?;
64                    Ok(v.to_val())
65                }
66                None => Ok(Val::VOID.to_val()),
67            }
68        }
69    };
70}
71
72#[macro_export]
73macro_rules! impl_bls12_381_fr_arith_host_fns {
74    ($host_fn: ident, $method: ident) => {
75        fn $host_fn(
76            &self,
77            _vmcaller: &mut VmCaller<Self::VmUserState>,
78            lhs: U256Val,
79            rhs: U256Val,
80        ) -> Result<U256Val, Self::Error> {
81            let mut lhs = self.fr_from_u256val(lhs)?;
82            let rhs = self.fr_from_u256val(rhs)?;
83            self.$method(&mut lhs, &rhs)?;
84            self.fr_to_u256val(lhs)
85        }
86    };
87}
88
89#[macro_export]
90macro_rules! impl_bn254_fr_arith_host_fns {
91    ($host_fn: ident, $method: ident) => {
92        fn $host_fn(
93            &self,
94            _vmcaller: &mut VmCaller<Self::VmUserState>,
95            lhs: U256Val,
96            rhs: U256Val,
97        ) -> Result<U256Val, Self::Error> {
98            let mut lhs = self.bn254_fr_from_u256val(lhs)?;
99            let rhs = self.bn254_fr_from_u256val(rhs)?;
100            self.$method(&mut lhs, &rhs)?;
101            self.bn254_fr_to_u256val(lhs)
102        }
103    };
104}