quickjs_runtime/quickjs_utils/
bigints.rs1use crate::jsutils::JsError;
2use crate::quickjs_utils;
3use crate::quickjs_utils::{functions, primitives};
4use crate::quickjsrealmadapter::QuickJsRealmAdapter;
5use crate::quickjsvalueadapter::QuickJsValueAdapter;
6#[cfg(feature = "bellard")]
7use crate::quickjsvalueadapter::TAG_BIG_INT;
8use libquickjs_sys as q;
9
10pub fn new_bigint_i64_q(
11 context: &QuickJsRealmAdapter,
12 int: i64,
13) -> Result<QuickJsValueAdapter, JsError> {
14 unsafe { new_bigint_i64(context.context, int) }
15}
16
17pub fn new_bigint_u64_q(
18 context: &QuickJsRealmAdapter,
19 int: u64,
20) -> Result<QuickJsValueAdapter, JsError> {
21 unsafe { new_bigint_u64(context.context, int) }
22}
23
24#[allow(dead_code)]
25pub unsafe fn new_bigint_i64(
28 context: *mut q::JSContext,
29 int: i64,
30) -> Result<QuickJsValueAdapter, JsError> {
31 let res_val = q::JS_NewBigInt64(context, int);
32 let ret = QuickJsValueAdapter::new(context, res_val, false, true, "new_bigint_i64");
33
34 #[cfg(feature = "bellard")]
35 {
36 #[cfg(debug_assertions)]
37 if ret.get_tag() == TAG_BIG_INT {
38 assert_eq!(ret.get_ref_count(), 1);
39 }
40 }
41 Ok(ret)
42}
43
44#[allow(dead_code)]
45pub unsafe fn new_bigint_u64(
48 context: *mut q::JSContext,
49 int: u64,
50) -> Result<QuickJsValueAdapter, JsError> {
51 let res_val = q::JS_NewBigUint64(context, int);
52 let ret = QuickJsValueAdapter::new(context, res_val, false, true, "new_bigint_u64");
53
54 #[cfg(feature = "bellard")]
55 {
56 #[cfg(debug_assertions)]
57 if ret.get_tag() == TAG_BIG_INT {
58 assert_eq!(ret.get_ref_count(), 1);
59 }
60 }
61 Ok(ret)
62}
63
64pub fn new_bigint_str_q(
65 context: &QuickJsRealmAdapter,
66 input_str: &str,
67) -> Result<QuickJsValueAdapter, JsError> {
68 unsafe { new_bigint_str(context.context, input_str) }
69}
70
71#[allow(dead_code)]
72pub unsafe fn new_bigint_str(
75 context: *mut q::JSContext,
76 input_str: &str,
77) -> Result<QuickJsValueAdapter, JsError> {
78 let global_ref = quickjs_utils::get_global(context);
79 let str_ref = primitives::from_string(context, input_str)?;
80 let bigint_ref = functions::invoke_member_function(context, &global_ref, "BigInt", &[str_ref])?;
81 let ret = bigint_ref;
82
83 #[cfg(feature = "bellard")]
84 assert_eq!(ret.get_ref_count(), 1);
85 Ok(ret)
86}
87
88pub fn to_string_q(
89 context: &QuickJsRealmAdapter,
90 big_int_ref: &QuickJsValueAdapter,
91) -> Result<String, JsError> {
92 unsafe { to_string(context.context, big_int_ref) }
93}
94
95#[allow(dead_code)]
96pub unsafe fn to_string(
99 context: *mut q::JSContext,
100 big_int_ref: &QuickJsValueAdapter,
101) -> Result<String, JsError> {
102 if !big_int_ref.is_big_int() {
103 return Err(JsError::new_str("big_int_ref was not a big_int"));
104 }
105 functions::call_to_string(context, big_int_ref)
106}
107
108#[cfg(test)]
109pub mod tests {
110 use crate::facades::tests::init_test_rt;
111 use crate::jsutils::Script;
112 use crate::quickjs_utils::bigints;
113 use crate::quickjs_utils::bigints::new_bigint_str_q;
114
115 #[test]
116 fn test_bigint() {
117 let rt = init_test_rt();
118 rt.exe_rt_task_in_event_loop(|q_js_rt| {
119 let q_ctx = q_js_rt.get_main_realm();
120
121 let res = q_ctx
122 .eval(Script::new("createABigInt.js", "BigInt(1234567890)"))
123 .expect("script failed");
124 log::info!(
125 "script bi was {} {}",
126 res.get_tag(),
127 res.to_string().expect("could not toString")
128 );
129
130 let bi_ref = bigints::new_bigint_u64_q(q_ctx, 659863456456)
131 .expect("could not create bigint from u64");
132
133 unsafe {
134 if let Some(e) = crate::quickjs_utils::errors::get_exception(q_ctx.context) {
135 log::error!("ex: {}", e);
136 }
137 }
138
139 let to_str = bigints::to_string_q(q_ctx, &bi_ref).expect("could not tostring bigint");
140 assert_eq!(to_str, "659863456456");
141 let bi_ref = bigints::new_bigint_i64_q(q_ctx, 659863456457)
142 .expect("could not create bigint from u64");
143 let to_str = bigints::to_string_q(q_ctx, &bi_ref).expect("could not tostring bigint");
144 assert_eq!(to_str, "659863456457");
145
146 let bi_ref =
147 new_bigint_str_q(q_ctx, "345346345645234564536345345345345456534783448567")
148 .expect("could not create bigint from str");
149
150 log::debug!("bi_ref.get_js_type is {}", bi_ref.get_js_type());
151
152 let to_str = bigints::to_string_q(q_ctx, &bi_ref).expect("could not tostring bigint");
153 assert_eq!(to_str, "345346345645234564536345345345345456534783448567");
154 });
155 }
156}