Skip to content

Commit d96ca58

Browse files
committed
update
1 parent 4d4a0b0 commit d96ca58

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

src/conversions/std/num.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,16 @@ mod fast_128bit_int_conversion {
358358
use super::*;
359359

360360
#[cfg(Py_3_14)]
361-
const PY_LONG_DIGIT_BITS: usize = 30;
361+
const PYLONG_BITS_IN_DIGIT: usize = 30;
362362

363363
#[cfg(Py_3_14)]
364-
fn get_bits_per_digit() -> usize {
365-
unsafe { (*ffi::PyLong_GetNativeLayout()).bits_per_digit as usize }
364+
fn is_30bit_layout() -> bool {
365+
static DIGITS: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
366+
367+
*DIGITS.get_or_init(|| {
368+
let layout = unsafe { &*ffi::PyLong_GetNativeLayout() };
369+
layout.bits_per_digit == PYLONG_BITS_IN_DIGIT
370+
})
366371
}
367372

368373
// for 128bit Integers
@@ -379,8 +384,8 @@ mod fast_128bit_int_conversion {
379384
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
380385
#[cfg(Py_3_14)]
381386
{
382-
if get_bits_per_digit() == PY_LONG_DIGIT_BITS {
383-
const DIGIT_MASK: u32 = (1 << PY_LONG_DIGIT_BITS) - 1;
387+
if !is_30bit_layout() {
388+
const DIGIT_MASK: u32 = (1 << PYLONG_BITS_IN_DIGIT) - 1;
384389

385390
let value = self as u128;
386391
let negative = $is_signed && (self as i128) < 0;
@@ -393,7 +398,7 @@ mod fast_128bit_int_conversion {
393398
let n_digits = if bits == 0 {
394399
1
395400
} else {
396-
bits.div_ceil(PY_LONG_DIGIT_BITS)
401+
bits.div_ceil(PYLONG_BITS_IN_DIGIT)
397402
};
398403
let mut ptr = std::ptr::null_mut();
399404
let long_writer = unsafe {
@@ -410,7 +415,7 @@ mod fast_128bit_int_conversion {
410415
let mut rest = abs;
411416
for i in 0..n_digits {
412417
unsafe { digits.add(i).write(rest as u32 & DIGIT_MASK) };
413-
rest >>= PY_LONG_DIGIT_BITS;
418+
rest >>= PYLONG_BITS_IN_DIGIT;
414419
}
415420
return unsafe {
416421
ffi::PyLongWriter_Finish(long_writer)
@@ -456,7 +461,7 @@ mod fast_128bit_int_conversion {
456461
let num = nb_index(&ob)?;
457462
#[cfg(Py_3_14)]
458463
{
459-
if get_bits_per_digit() == PY_LONG_DIGIT_BITS {
464+
if !is_30bit_layout() {
460465
let mut long_export = MaybeUninit::<ffi::PyLongExport>::uninit();
461466
unsafe {
462467
crate::err::error_on_minusone(
@@ -492,7 +497,7 @@ mod fast_128bit_int_conversion {
492497
if i == 4 && digit >> 8 != 0 {
493498
overflowed = true;
494499
}
495-
abs |= digit << (i * PY_LONG_DIGIT_BITS);
500+
abs |= digit << (i * PYLONG_BITS_IN_DIGIT);
496501
}
497502
unsafe { ffi::PyLong_FreeExport(long_export.as_mut_ptr()) };
498503
if overflowed {

0 commit comments

Comments
 (0)