X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
XXX try PyLong_Export without value
  • Loading branch information
skirpichev committed Dec 26, 2024
commit bf687e5e3d278294be4425b7cde7e54a3406e533
10 changes: 9 additions & 1 deletion Modules/_decimal/_decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2335,9 +2335,17 @@ dec_from_long(decimal_state *state, PyTypeObject *type, PyObject *v,
return NULL;
}
if (export_long.digits) {
const uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;

if (PyUnstable_Long_IsCompact((PyLongObject *)v)) {
_dec_settriple(dec, sign, ((uint32_t *)export_long.digits)[0], 0);
mpd_qfinalize(MPD(dec), ctx, status);
PyLong_FreeExport(&export_long);
return dec;
}

const PyLongLayout *layout = PyLong_GetNativeLayout();
const uint32_t base = (uint32_t)1 << layout->bits_per_digit;
const uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
const Py_ssize_t len = export_long.ndigits;

if (base > UINT16_MAX) {
Expand Down
39 changes: 9 additions & 30 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -6842,36 +6842,15 @@ PyLong_Export(PyObject *obj, PyLongExport *export_long)
return -1;
}

// Fast-path: try to convert to a int64_t
int overflow;
#if SIZEOF_LONG == 8
long value = PyLong_AsLongAndOverflow(obj, &overflow);
#else
// Windows has 32-bit long, so use 64-bit long long instead
long long value = PyLong_AsLongLongAndOverflow(obj, &overflow);
#endif
Py_BUILD_ASSERT(sizeof(value) == sizeof(int64_t));
// the function cannot fail since obj is a PyLongObject
assert(!(value == -1 && PyErr_Occurred()));

if (!overflow) {
export_long->value = value;
export_long->negative = 0;
export_long->ndigits = 0;
export_long->digits = NULL;
export_long->_reserved = 0;
}
else {
PyLongObject *self = (PyLongObject*)obj;
export_long->value = 0;
export_long->negative = _PyLong_IsNegative(self);
export_long->ndigits = _PyLong_DigitCount(self);
if (export_long->ndigits == 0) {
export_long->ndigits = 1;
}
export_long->digits = self->long_value.ob_digit;
export_long->_reserved = (Py_uintptr_t)Py_NewRef(obj);
}
PyLongObject *self = (PyLongObject*)obj;
export_long->value = 0;
export_long->negative = _PyLong_IsNegative(self);
export_long->ndigits = _PyLong_DigitCount(self);
if (export_long->ndigits == 0) {
export_long->ndigits = 1;
}
export_long->digits = self->long_value.ob_digit;
export_long->_reserved = (Py_uintptr_t)Py_NewRef(obj);
return 0;
}

Expand Down
X Tutup