Skip to main content

multiversx_sc_wasm_adapter/api/managed_types/
big_int_api_node.rs

1use core::cmp::Ordering;
2
3use multiversx_sc::api::{BigIntApiImpl, Sign};
4
5unsafe extern "C" {
6    fn bigIntNew(value: i64) -> i32;
7
8    fn bigIntSetInt64(destination: i32, value: i64);
9    fn bigIntIsInt64(reference: i32) -> i32;
10    fn bigIntGetInt64(reference: i32) -> i64;
11
12    fn bigIntAdd(dest: i32, x: i32, y: i32);
13    fn bigIntSub(dest: i32, x: i32, y: i32);
14    fn bigIntMul(dest: i32, x: i32, y: i32);
15    fn bigIntTDiv(dest: i32, x: i32, y: i32);
16    fn bigIntTMod(dest: i32, x: i32, y: i32);
17
18    fn bigIntAbs(dest: i32, x: i32);
19    fn bigIntNeg(dest: i32, x: i32);
20    fn bigIntSign(x: i32) -> i32;
21    fn bigIntCmp(x: i32, y: i32) -> i32;
22
23    fn bigIntSqrt(dest: i32, x: i32);
24    fn bigIntPow(dest: i32, x: i32, y: i32);
25    fn bigIntLog2(x: i32) -> i32;
26
27    fn bigIntAnd(dest: i32, x: i32, y: i32);
28    fn bigIntOr(dest: i32, x: i32, y: i32);
29    fn bigIntXor(dest: i32, x: i32, y: i32);
30    fn bigIntShr(dest: i32, x: i32, bits: i32);
31    fn bigIntShl(dest: i32, x: i32, bits: i32);
32
33    fn bigIntToString(bigIntHandle: i32, destHandle: i32);
34}
35
36macro_rules! binary_op_wrapper {
37    ($method_name:ident, $hook_name:ident) => {
38        fn $method_name(
39            &self,
40            dest: Self::BigIntHandle,
41            x: Self::BigIntHandle,
42            y: Self::BigIntHandle,
43        ) {
44            unsafe {
45                $hook_name(dest, x, y);
46            }
47        }
48    };
49}
50
51macro_rules! unary_op_wrapper {
52    ($method_name:ident, $hook_name:ident) => {
53        fn $method_name(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle) {
54            unsafe {
55                $hook_name(dest, x);
56            }
57        }
58    };
59}
60
61impl BigIntApiImpl for crate::api::VmApiImpl {
62    #[inline]
63    fn bi_new(&self, value: i64) -> Self::BigIntHandle {
64        unsafe { bigIntNew(value) }
65    }
66
67    #[inline]
68    fn bi_set_int64(&self, destination: Self::BigIntHandle, value: i64) {
69        unsafe {
70            bigIntSetInt64(destination, value);
71        }
72    }
73
74    fn bi_to_i64(&self, reference: Self::BigIntHandle) -> Option<i64> {
75        unsafe {
76            let is_i64_result = bigIntIsInt64(reference);
77            if is_i64_result > 0 {
78                Some(bigIntGetInt64(reference))
79            } else {
80                None
81            }
82        }
83    }
84
85    binary_op_wrapper! {bi_add, bigIntAdd}
86    binary_op_wrapper! {bi_sub, bigIntSub}
87    binary_op_wrapper! {bi_mul, bigIntMul}
88    binary_op_wrapper! {bi_t_div, bigIntTDiv}
89    binary_op_wrapper! {bi_t_mod, bigIntTMod}
90
91    unary_op_wrapper! {bi_abs, bigIntAbs}
92    unary_op_wrapper! {bi_neg, bigIntNeg}
93
94    fn bi_sign(&self, x: Self::BigIntHandle) -> Sign {
95        unsafe {
96            match bigIntSign(x).cmp(&0) {
97                Ordering::Greater => Sign::Plus,
98                Ordering::Equal => Sign::NoSign,
99                Ordering::Less => Sign::Minus,
100            }
101        }
102    }
103
104    #[inline]
105    fn bi_cmp(&self, x: Self::BigIntHandle, y: Self::BigIntHandle) -> Ordering {
106        unsafe { bigIntCmp(x, y).cmp(&0) }
107    }
108
109    unary_op_wrapper! {bi_sqrt, bigIntSqrt}
110    binary_op_wrapper! {bi_pow, bigIntPow}
111
112    fn bi_log2(&self, x: Self::BigIntHandle) -> i32 {
113        unsafe { bigIntLog2(x) }
114    }
115
116    binary_op_wrapper! {bi_and, bigIntAnd}
117    binary_op_wrapper! {bi_or, bigIntOr}
118    binary_op_wrapper! {bi_xor, bigIntXor}
119
120    fn bi_shr(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle, bits: usize) {
121        unsafe {
122            bigIntShr(dest, x, bits as i32);
123        }
124    }
125
126    fn bi_shl(&self, dest: Self::BigIntHandle, x: Self::BigIntHandle, bits: usize) {
127        unsafe {
128            bigIntShl(dest, x, bits as i32);
129        }
130    }
131
132    fn bi_to_string(
133        &self,
134        bi_handle: Self::BigIntHandle,
135        result_handle: Self::ManagedBufferHandle,
136    ) {
137        unsafe {
138            bigIntToString(bi_handle, result_handle);
139        }
140    }
141}