@@ -120,9 +120,6 @@ static inline size_t CPy_FindAttrOffset(PyTypeObject *trait, CPyVTableItem *vtab
120
120
CPyTagged CPyTagged_FromSsize_t (Py_ssize_t value );
121
121
CPyTagged CPyTagged_FromVoidPtr (void * ptr );
122
122
CPyTagged CPyTagged_FromInt64 (int64_t value );
123
- CPyTagged CPyTagged_FromObject (PyObject * object );
124
- CPyTagged CPyTagged_StealFromObject (PyObject * object );
125
- CPyTagged CPyTagged_BorrowFromObject (PyObject * object );
126
123
PyObject * CPyTagged_AsObject (CPyTagged x );
127
124
PyObject * CPyTagged_StealAsObject (CPyTagged x );
128
125
Py_ssize_t CPyTagged_AsSsize_t (CPyTagged x );
@@ -148,18 +145,18 @@ CPyTagged CPyTagged_FromFloat(double f);
148
145
PyObject * CPyLong_FromStrWithBase (PyObject * o , CPyTagged base );
149
146
PyObject * CPyLong_FromStr (PyObject * o );
150
147
PyObject * CPyBool_Str (bool b );
151
- int64_t CPyLong_AsInt64 (PyObject * o );
148
+ int64_t CPyLong_AsInt64_ (PyObject * o );
152
149
int64_t CPyInt64_Divide (int64_t x , int64_t y );
153
150
int64_t CPyInt64_Remainder (int64_t x , int64_t y );
154
- int32_t CPyLong_AsInt32 (PyObject * o );
151
+ int32_t CPyLong_AsInt32_ (PyObject * o );
155
152
int32_t CPyInt32_Divide (int32_t x , int32_t y );
156
153
int32_t CPyInt32_Remainder (int32_t x , int32_t y );
157
154
void CPyInt32_Overflow (void );
158
- int16_t CPyLong_AsInt16 (PyObject * o );
155
+ int16_t CPyLong_AsInt16_ (PyObject * o );
159
156
int16_t CPyInt16_Divide (int16_t x , int16_t y );
160
157
int16_t CPyInt16_Remainder (int16_t x , int16_t y );
161
158
void CPyInt16_Overflow (void );
162
- uint8_t CPyLong_AsUInt8 (PyObject * o );
159
+ uint8_t CPyLong_AsUInt8_ (PyObject * o );
163
160
void CPyUInt8_Overflow (void );
164
161
double CPyTagged_TrueDivide (CPyTagged x , CPyTagged y );
165
162
@@ -199,6 +196,41 @@ static inline PyObject *CPyTagged_LongAsObject(CPyTagged x) {
199
196
return (PyObject * )(x & ~CPY_INT_TAG );
200
197
}
201
198
199
+ static inline CPyTagged CPyTagged_FromObject (PyObject * object ) {
200
+ int overflow ;
201
+ // The overflow check knows about CPyTagged's width
202
+ Py_ssize_t value = CPyLong_AsSsize_tAndOverflow (object , & overflow );
203
+ if (unlikely (overflow != 0 )) {
204
+ Py_INCREF (object );
205
+ return ((CPyTagged )object ) | CPY_INT_TAG ;
206
+ } else {
207
+ return value << 1 ;
208
+ }
209
+ }
210
+
211
+ static inline CPyTagged CPyTagged_StealFromObject (PyObject * object ) {
212
+ int overflow ;
213
+ // The overflow check knows about CPyTagged's width
214
+ Py_ssize_t value = CPyLong_AsSsize_tAndOverflow (object , & overflow );
215
+ if (unlikely (overflow != 0 )) {
216
+ return ((CPyTagged )object ) | CPY_INT_TAG ;
217
+ } else {
218
+ Py_DECREF (object );
219
+ return value << 1 ;
220
+ }
221
+ }
222
+
223
+ static inline CPyTagged CPyTagged_BorrowFromObject (PyObject * object ) {
224
+ int overflow ;
225
+ // The overflow check knows about CPyTagged's width
226
+ Py_ssize_t value = CPyLong_AsSsize_tAndOverflow (object , & overflow );
227
+ if (unlikely (overflow != 0 )) {
228
+ return ((CPyTagged )object ) | CPY_INT_TAG ;
229
+ } else {
230
+ return value << 1 ;
231
+ }
232
+ }
233
+
202
234
static inline bool CPyTagged_TooBig (Py_ssize_t value ) {
203
235
// Micro-optimized for the common case where it fits.
204
236
return (size_t )value > CPY_TAGGED_MAX
@@ -286,6 +318,107 @@ static inline bool CPyTagged_IsLe(CPyTagged left, CPyTagged right) {
286
318
}
287
319
}
288
320
321
+ static inline int64_t CPyLong_AsInt64 (PyObject * o ) {
322
+ if (likely (PyLong_Check (o ))) {
323
+ PyLongObject * lobj = (PyLongObject * )o ;
324
+ Py_ssize_t size = Py_SIZE (lobj );
325
+ if (likely (size == 1 )) {
326
+ // Fast path
327
+ return CPY_LONG_DIGIT (lobj , 0 );
328
+ } else if (likely (size == 0 )) {
329
+ return 0 ;
330
+ }
331
+ }
332
+ // Slow path
333
+ return CPyLong_AsInt64_ (o );
334
+ }
335
+
336
+ static inline int32_t CPyLong_AsInt32 (PyObject * o ) {
337
+ if (likely (PyLong_Check (o ))) {
338
+ #if CPY_3_12_FEATURES
339
+ PyLongObject * lobj = (PyLongObject * )o ;
340
+ size_t tag = CPY_LONG_TAG (lobj );
341
+ if (likely (tag == (1 << CPY_NON_SIZE_BITS ))) {
342
+ // Fast path
343
+ return CPY_LONG_DIGIT (lobj , 0 );
344
+ } else if (likely (tag == CPY_SIGN_ZERO )) {
345
+ return 0 ;
346
+ }
347
+ #else
348
+ PyLongObject * lobj = (PyLongObject * )o ;
349
+ Py_ssize_t size = lobj -> ob_base .ob_size ;
350
+ if (likely (size == 1 )) {
351
+ // Fast path
352
+ return CPY_LONG_DIGIT (lobj , 0 );
353
+ } else if (likely (size == 0 )) {
354
+ return 0 ;
355
+ }
356
+ #endif
357
+ }
358
+ // Slow path
359
+ return CPyLong_AsInt32_ (o );
360
+ }
361
+
362
+ static inline int16_t CPyLong_AsInt16 (PyObject * o ) {
363
+ if (likely (PyLong_Check (o ))) {
364
+ #if CPY_3_12_FEATURES
365
+ PyLongObject * lobj = (PyLongObject * )o ;
366
+ size_t tag = CPY_LONG_TAG (lobj );
367
+ if (likely (tag == (1 << CPY_NON_SIZE_BITS ))) {
368
+ // Fast path
369
+ digit x = CPY_LONG_DIGIT (lobj , 0 );
370
+ if (x < 0x8000 )
371
+ return x ;
372
+ } else if (likely (tag == CPY_SIGN_ZERO )) {
373
+ return 0 ;
374
+ }
375
+ #else
376
+ PyLongObject * lobj = (PyLongObject * )o ;
377
+ Py_ssize_t size = lobj -> ob_base .ob_size ;
378
+ if (likely (size == 1 )) {
379
+ // Fast path
380
+ digit x = lobj -> ob_digit [0 ];
381
+ if (x < 0x8000 )
382
+ return x ;
383
+ } else if (likely (size == 0 )) {
384
+ return 0 ;
385
+ }
386
+ #endif
387
+ }
388
+ // Slow path
389
+ return CPyLong_AsInt16_ (o );
390
+ }
391
+
392
+ static inline uint8_t CPyLong_AsUInt8 (PyObject * o ) {
393
+ if (likely (PyLong_Check (o ))) {
394
+ #if CPY_3_12_FEATURES
395
+ PyLongObject * lobj = (PyLongObject * )o ;
396
+ size_t tag = CPY_LONG_TAG (lobj );
397
+ if (likely (tag == (1 << CPY_NON_SIZE_BITS ))) {
398
+ // Fast path
399
+ digit x = CPY_LONG_DIGIT (lobj , 0 );
400
+ if (x < 256 )
401
+ return x ;
402
+ } else if (likely (tag == CPY_SIGN_ZERO )) {
403
+ return 0 ;
404
+ }
405
+ #else
406
+ PyLongObject * lobj = (PyLongObject * )o ;
407
+ Py_ssize_t size = lobj -> ob_base .ob_size ;
408
+ if (likely (size == 1 )) {
409
+ // Fast path
410
+ digit x = lobj -> ob_digit [0 ];
411
+ if (x < 256 )
412
+ return x ;
413
+ } else if (likely (size == 0 )) {
414
+ return 0 ;
415
+ }
416
+ #endif
417
+ }
418
+ // Slow path
419
+ return CPyLong_AsUInt8_ (o );
420
+ }
421
+
289
422
static inline CPyTagged CPyTagged_Negate (CPyTagged num ) {
290
423
if (likely (CPyTagged_CheckShort (num )
291
424
&& num != (CPyTagged ) ((Py_ssize_t )1 << (CPY_INT_BITS - 1 )))) {
0 commit comments