1use crate::BigInt;
2use crate::Context;
3use crate::Local;
4use crate::isolate::RealIsolate;
5use crate::scope::PinScope;
6use crate::support::int;
7
8use std::mem::MaybeUninit;
9
10unsafe extern "C" {
11 fn v8__BigInt__New(isolate: *mut RealIsolate, value: i64) -> *const BigInt;
12 fn v8__BigInt__NewFromUnsigned(
13 isolate: *mut RealIsolate,
14 value: u64,
15 ) -> *const BigInt;
16 fn v8__BigInt__NewFromWords(
17 context: *const Context,
18 sign_bit: int,
19 word_count: int,
20 words: *const u64,
21 ) -> *const BigInt;
22 fn v8__BigInt__Uint64Value(this: *const BigInt, lossless: *mut bool) -> u64;
23 fn v8__BigInt__Int64Value(this: *const BigInt, lossless: *mut bool) -> i64;
24 fn v8__BigInt__WordCount(this: *const BigInt) -> int;
25 fn v8__BigInt__ToWordsArray(
26 this: *const BigInt,
27 sign_bit: *mut int,
28 word_count: *mut int,
29 words: *mut u64,
30 );
31}
32
33impl BigInt {
34 #[inline(always)]
35 pub fn new_from_i64<'s>(
36 scope: &PinScope<'s, '_, ()>,
37 value: i64,
38 ) -> Local<'s, BigInt> {
39 unsafe {
40 scope.cast_local(|sd| v8__BigInt__New(sd.get_isolate_ptr(), value))
41 }
42 .unwrap()
43 }
44
45 #[inline(always)]
46 pub fn new_from_u64<'s>(
47 scope: &PinScope<'s, '_, ()>,
48 value: u64,
49 ) -> Local<'s, BigInt> {
50 unsafe {
51 scope.cast_local(|sd| {
52 v8__BigInt__NewFromUnsigned(sd.get_isolate_ptr(), value)
53 })
54 }
55 .unwrap()
56 }
57
58 #[inline(always)]
64 pub fn new_from_words<'s>(
65 scope: &PinScope<'s, '_, ()>,
66 sign_bit: bool,
67 words: &[u64],
68 ) -> Option<Local<'s, BigInt>> {
69 unsafe {
70 scope.cast_local(|sd| {
71 v8__BigInt__NewFromWords(
72 sd.get_current_context(),
73 sign_bit as int,
74 words.len() as int,
75 words.as_ptr(),
76 )
77 })
78 }
79 }
80
81 #[inline(always)]
86 pub fn u64_value(&self) -> (u64, bool) {
87 let mut lossless = MaybeUninit::uninit();
88 let v = unsafe { v8__BigInt__Uint64Value(self, lossless.as_mut_ptr()) };
89 let lossless = unsafe { lossless.assume_init() };
90 (v, lossless)
91 }
92
93 #[inline(always)]
97 pub fn i64_value(&self) -> (i64, bool) {
98 let mut lossless = MaybeUninit::uninit();
99 let v = unsafe { v8__BigInt__Int64Value(self, lossless.as_mut_ptr()) };
100 let lossless = unsafe { lossless.assume_init() };
101 (v, lossless)
102 }
103
104 #[inline(always)]
107 pub fn word_count(&self) -> usize {
108 unsafe { v8__BigInt__WordCount(self) as usize }
109 }
110
111 #[inline]
115 pub fn to_words_array<'a>(
116 &self,
117 words: &'a mut [u64],
118 ) -> (bool, &'a mut [u64]) {
119 let mut sign_bit = MaybeUninit::uninit();
120 let mut word_count = words.len() as int;
121 unsafe {
122 v8__BigInt__ToWordsArray(
123 self,
124 sign_bit.as_mut_ptr(),
125 &mut word_count,
126 words.as_mut_ptr(),
127 );
128 }
129
130 let sign_bit = unsafe { sign_bit.assume_init() };
131 debug_assert!(sign_bit == 0 || sign_bit == 1);
132 let word_count = word_count as usize;
133
134 (
135 sign_bit == 1,
136 if word_count < words.len() {
137 &mut words[..word_count]
138 } else {
139 words
140 },
141 )
142 }
143}