Skip to content

Commit 55eb87f

Browse files
committed
feat: optimize BigInt conversion by adding support for short BigInt
1 parent 8f7d601 commit 55eb87f

File tree

4 files changed

+20
-8
lines changed

4 files changed

+20
-8
lines changed

libquickjs-sys/embed/extensions.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ int JS_Ext_GetInt(JSValue v)
7777
return JS_VALUE_GET_INT(v);
7878
}
7979

80+
int JS_Ext_GetShortBigInt(JSValue v)
81+
{
82+
return JS_VALUE_GET_SHORT_BIG_INT(v);
83+
}
84+
8085
int JS_Ext_GetBool(JSValue v)
8186
{
8287
return JS_VALUE_GET_BOOL(v);

libquickjs-sys/embed/extensions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern "C"
1919
bool JS_Ext_IsNan(JSValue v);
2020
double JS_Ext_GetFloat64(JSValue v);
2121
int JS_Ext_GetInt(JSValue v);
22+
int JS_Ext_GetShortBigInt(JSValue v);
2223
int JS_Ext_GetBool(JSValue v);
2324
void *JS_Ext_GetPtr(JSValue v);
2425
int JS_Ext_GetNormTag(JSValue v);

src/value/value.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,13 @@ impl OwnedJsValue {
320320
});
321321
}
322322

323-
// let mut int: i64 = 0;
324-
// let ret = unsafe { q::JS_ToBigInt64(self.context, &mut int, self.value) };
325-
// if ret == 0 {
326-
// Ok(BigInt {
327-
// inner: BigIntOrI64::Int(int),
328-
// })
329-
// } else {
323+
if self.is_short_bigint() {
324+
let int = unsafe { q::JS_Ext_GetShortBigInt(self.value) };
325+
return Ok(BigInt {
326+
inner: BigIntOrI64::Int(int as i64),
327+
});
328+
}
329+
330330
let ret = unsafe { q::JS_Ext_BigIntToString1(self.context, self.value, 16) };
331331
let ret = OwnedJsValue::new(self.context, ret);
332332

tests/runtime.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,16 @@ fn chrono_roundtrip() {
664664
#[cfg(feature = "bigint")]
665665
#[test]
666666
fn test_bigint_deserialize_i64() {
667-
for i in [0, std::i64::MAX, std::i64::MIN] {
667+
for i in [0, std::i32::MAX as i64 / 2, std::i64::MAX, std::i64::MIN] {
668668
let c = Context::builder().build().unwrap();
669669
let value = c.eval(&format!("{}n", i), false).unwrap();
670670
assert_eq!(value.to_bigint(), Ok(i.into()));
671+
if i.unsigned_abs() <= std::i32::MAX as u64 {
672+
assert!(value.is_short_bigint());
673+
} else {
674+
assert!(!value.is_short_bigint());
675+
assert!(value.is_bigint());
676+
}
671677
}
672678
}
673679

0 commit comments

Comments
 (0)