Skip to content

Commit 021ab8e

Browse files
committed
Revert "XXX try PyLong_Export without value"
This reverts commit bf687e5.
1 parent bf687e5 commit 021ab8e

File tree

2 files changed

+31
-18
lines changed

2 files changed

+31
-18
lines changed

Modules/_decimal/_decimal.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,17 +2335,9 @@ dec_from_long(decimal_state *state, PyTypeObject *type, PyObject *v,
23352335
return NULL;
23362336
}
23372337
if (export_long.digits) {
2338-
const uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
2339-
2340-
if (PyUnstable_Long_IsCompact((PyLongObject *)v)) {
2341-
_dec_settriple(dec, sign, ((uint32_t *)export_long.digits)[0], 0);
2342-
mpd_qfinalize(MPD(dec), ctx, status);
2343-
PyLong_FreeExport(&export_long);
2344-
return dec;
2345-
}
2346-
23472338
const PyLongLayout *layout = PyLong_GetNativeLayout();
23482339
const uint32_t base = (uint32_t)1 << layout->bits_per_digit;
2340+
const uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
23492341
const Py_ssize_t len = export_long.ndigits;
23502342

23512343
if (base > UINT16_MAX) {

Objects/longobject.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6842,15 +6842,36 @@ PyLong_Export(PyObject *obj, PyLongExport *export_long)
68426842
return -1;
68436843
}
68446844

6845-
PyLongObject *self = (PyLongObject*)obj;
6846-
export_long->value = 0;
6847-
export_long->negative = _PyLong_IsNegative(self);
6848-
export_long->ndigits = _PyLong_DigitCount(self);
6849-
if (export_long->ndigits == 0) {
6850-
export_long->ndigits = 1;
6851-
}
6852-
export_long->digits = self->long_value.ob_digit;
6853-
export_long->_reserved = (Py_uintptr_t)Py_NewRef(obj);
6845+
// Fast-path: try to convert to a int64_t
6846+
int overflow;
6847+
#if SIZEOF_LONG == 8
6848+
long value = PyLong_AsLongAndOverflow(obj, &overflow);
6849+
#else
6850+
// Windows has 32-bit long, so use 64-bit long long instead
6851+
long long value = PyLong_AsLongLongAndOverflow(obj, &overflow);
6852+
#endif
6853+
Py_BUILD_ASSERT(sizeof(value) == sizeof(int64_t));
6854+
// the function cannot fail since obj is a PyLongObject
6855+
assert(!(value == -1 && PyErr_Occurred()));
6856+
6857+
if (!overflow) {
6858+
export_long->value = value;
6859+
export_long->negative = 0;
6860+
export_long->ndigits = 0;
6861+
export_long->digits = NULL;
6862+
export_long->_reserved = 0;
6863+
}
6864+
else {
6865+
PyLongObject *self = (PyLongObject*)obj;
6866+
export_long->value = 0;
6867+
export_long->negative = _PyLong_IsNegative(self);
6868+
export_long->ndigits = _PyLong_DigitCount(self);
6869+
if (export_long->ndigits == 0) {
6870+
export_long->ndigits = 1;
6871+
}
6872+
export_long->digits = self->long_value.ob_digit;
6873+
export_long->_reserved = (Py_uintptr_t)Py_NewRef(obj);
6874+
}
68546875
return 0;
68556876
}
68566877

0 commit comments

Comments
 (0)