Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationInplaceRshift.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* WARNING, this code is GENERATED. Modify the template HelperOperationInplace.c.j2 instead! */
4
5/* This file is included from another C file, help IDEs to still parse it on its own. */
6#ifdef __IDE_ONLY__
7#include "nuitka/prelude.h"
8#endif
9
10/* C helpers for type in-place ">>" (RSHIFT) operations */
11
12/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "LONG" to Python2 'long', Python3 'int'. */
13static inline bool _INPLACE_OPERATION_RSHIFT_LONG_LONG(PyObject **operand1, PyObject *operand2) {
14 assert(operand1); // Pointer must be non-null.
15
16 CHECK_OBJECT(*operand1);
17 assert(PyLong_CheckExact(*operand1));
18 CHECK_OBJECT(operand2);
19 assert(PyLong_CheckExact(operand2));
20
21 // Not every code path will make use of all possible results.
22#if defined(_MSC_VER)
23#pragma warning(push)
24#pragma warning(disable : 4101)
25#endif
26 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
27 NUITKA_MAY_BE_UNUSED long clong_result;
28#if defined(_MSC_VER)
29#pragma warning(pop)
30#endif
31
32 PyObject *x = PyLong_Type.tp_as_number->nb_rshift(*operand1, operand2);
33 assert(x != Py_NotImplemented);
34
35 obj_result = x;
36 goto exit_result_object;
37
38exit_result_object:
39 if (unlikely(obj_result == NULL)) {
40 goto exit_result_exception;
41 }
42 // We got an object handed, that we have to release.
43 Py_DECREF(*operand1);
44 *operand1 = obj_result;
45 goto exit_result_ok;
46
47exit_result_ok:
48 return true;
49
50exit_result_exception:
51 return false;
52}
53
54bool INPLACE_OPERATION_RSHIFT_LONG_LONG(PyObject **operand1, PyObject *operand2) {
55 return _INPLACE_OPERATION_RSHIFT_LONG_LONG(operand1, operand2);
56}
57
58/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
59static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_RSHIFT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
60 PyTypeObject *type1 = Py_TYPE(*operand1);
61
62#if defined(_MSC_VER)
63#pragma warning(push)
64#pragma warning(disable : 4101)
65#endif
66 NUITKA_MAY_BE_UNUSED bool cbool_result;
67 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
68#if defined(_MSC_VER)
69#pragma warning(pop)
70#endif
71
72 binaryfunc islot =
73 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_rshift : NULL;
74
75 if (islot != NULL) {
76 PyObject *x = islot(*operand1, operand2);
77
78 if (x != Py_NotImplemented) {
79 obj_result = x;
80 goto exit_inplace_result_object;
81 }
82
83 Py_DECREF_IMMORTAL(x);
84 }
85
86 {
87 binaryfunc slot1 =
88 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_rshift : NULL;
89 binaryfunc slot2 = NULL;
90
91 if (!(type1 == &PyLong_Type)) {
92 // Different types, need to consider second value slot.
93
94 slot2 = PyLong_Type.tp_as_number->nb_rshift;
95
96 if (slot1 == slot2) {
97 slot2 = NULL;
98 }
99 }
100
101 if (slot1 != NULL) {
102 PyObject *x = slot1(*operand1, operand2);
103
104 if (x != Py_NotImplemented) {
105 obj_result = x;
106 goto exit_inplace_result_object;
107 }
108
109 Py_DECREF_IMMORTAL(x);
110 }
111
112 if (slot2 != NULL) {
113 PyObject *x = slot2(*operand1, operand2);
114
115 if (x != Py_NotImplemented) {
116 obj_result = x;
117 goto exit_inplace_result_object;
118 }
119
120 Py_DECREF_IMMORTAL(x);
121 }
122
123#if PYTHON_VERSION < 0x300
124 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
125 coercion c1 =
126 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
127
128 if (c1 != NULL) {
129 PyObject *coerced1 = *operand1;
130 PyObject *coerced2 = operand2;
131
132 int err = c1(&coerced1, &coerced2);
133
134 if (unlikely(err < 0)) {
135 goto exit_inplace_exception;
136 }
137
138 if (err == 0) {
139 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
140
141 if (likely(mv == NULL)) {
142 binaryfunc slot = mv->nb_rshift;
143
144 if (likely(slot != NULL)) {
145 PyObject *x = slot(coerced1, coerced2);
146
147 Py_DECREF(coerced1);
148 Py_DECREF(coerced2);
149
150 obj_result = x;
151 goto exit_inplace_result_object;
152 }
153 }
154
155 // nb_coerce took a reference.
156 Py_DECREF(coerced1);
157 Py_DECREF(coerced2);
158 }
159 }
160 coercion c2 = PyLong_Type.tp_as_number->nb_coerce;
161
162 if (c2 != NULL) {
163 PyObject *coerced1 = *operand1;
164 PyObject *coerced2 = operand2;
165
166 int err = c2(&coerced2, &coerced1);
167
168 if (unlikely(err < 0)) {
169 goto exit_inplace_exception;
170 }
171
172 if (err == 0) {
173 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
174
175 if (likely(mv == NULL)) {
176 binaryfunc slot = mv->nb_rshift;
177
178 if (likely(slot != NULL)) {
179 PyObject *x = slot(coerced1, coerced2);
180
181 Py_DECREF(coerced1);
182 Py_DECREF(coerced2);
183
184 obj_result = x;
185 goto exit_inplace_result_object;
186 }
187 }
188
189 // nb_coerce took a reference.
190 Py_DECREF(coerced1);
191 Py_DECREF(coerced2);
192 }
193 }
194 }
195#endif
196
197#if PYTHON_VERSION < 0x300
198 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: '%s' and 'long'", type1->tp_name);
199#else
200 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: '%s' and 'int'", type1->tp_name);
201#endif
202 goto exit_inplace_exception;
203 }
204
205exit_inplace_result_object:
206 if (unlikely(obj_result == NULL)) {
207 return false;
208 }
209
210 // We got an object handed, that we have to release.
211 Py_DECREF(*operand1);
212
213 // That's our return value then. As we use a dedicated variable, it's
214 // OK that way.
215 *operand1 = obj_result;
216
217 return true;
218
219exit_inplace_exception:
220 return false;
221}
222static inline bool _INPLACE_OPERATION_RSHIFT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
223 assert(operand1); // Pointer must be non-null.
224
225 CHECK_OBJECT(*operand1);
226 CHECK_OBJECT(operand2);
227 assert(PyLong_CheckExact(operand2));
228
229 PyTypeObject *type1 = Py_TYPE(*operand1);
230
231 if (type1 == &PyLong_Type) {
232 // return _BINARY_OPERATION_RSHIFT_LONG_LONG_INPLACE(operand1, operand2);
233
234 // Not every code path will make use of all possible results.
235#if defined(_MSC_VER)
236#pragma warning(push)
237#pragma warning(disable : 4101)
238#endif
239 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
240 NUITKA_MAY_BE_UNUSED long clong_result;
241#if defined(_MSC_VER)
242#pragma warning(pop)
243#endif
244
245 PyObject *x = PyLong_Type.tp_as_number->nb_rshift(*operand1, operand2);
246 assert(x != Py_NotImplemented);
247
248 obj_result = x;
249 goto exit_result_object;
250
251 exit_result_object:
252 if (unlikely(obj_result == NULL)) {
253 goto exit_result_exception;
254 }
255 // We got an object handed, that we have to release.
256 Py_DECREF(*operand1);
257 *operand1 = obj_result;
258 goto exit_result_ok;
259
260 exit_result_ok:
261 return true;
262
263 exit_result_exception:
264 return false;
265 }
266
267 return __INPLACE_OPERATION_RSHIFT_OBJECT_LONG(operand1, operand2);
268}
269
270bool INPLACE_OPERATION_RSHIFT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
271 return _INPLACE_OPERATION_RSHIFT_OBJECT_LONG(operand1, operand2);
272}
273
274/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
275static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_RSHIFT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
276 PyTypeObject *type2 = Py_TYPE(operand2);
277
278#if defined(_MSC_VER)
279#pragma warning(push)
280#pragma warning(disable : 4101)
281#endif
282 NUITKA_MAY_BE_UNUSED bool cbool_result;
283 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
284#if defined(_MSC_VER)
285#pragma warning(pop)
286#endif
287
288 // No inplace number slot nb_inplace_rshift available for this type.
289
290 {
291 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_rshift;
292 binaryfunc slot2 = NULL;
293
294 if (!(&PyLong_Type == type2)) {
295 // Different types, need to consider second value slot.
296
297 slot2 =
298 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_rshift : NULL;
299
300 if (slot1 == slot2) {
301 slot2 = NULL;
302 }
303 }
304
305 if (slot1 != NULL) {
306 if (slot2 != NULL) {
307 if (Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
308 PyObject *x = slot2(*operand1, operand2);
309
310 if (x != Py_NotImplemented) {
311 obj_result = x;
312 goto exit_inplace_result_object;
313 }
314
315 Py_DECREF_IMMORTAL(x);
316 slot2 = NULL;
317 }
318 }
319
320 PyObject *x = slot1(*operand1, operand2);
321
322 if (x != Py_NotImplemented) {
323 obj_result = x;
324 goto exit_inplace_result_object;
325 }
326
327 Py_DECREF_IMMORTAL(x);
328 }
329
330 if (slot2 != NULL) {
331 PyObject *x = slot2(*operand1, operand2);
332
333 if (x != Py_NotImplemented) {
334 obj_result = x;
335 goto exit_inplace_result_object;
336 }
337
338 Py_DECREF_IMMORTAL(x);
339 }
340
341#if PYTHON_VERSION < 0x300
342 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
343 coercion c1 = PyLong_Type.tp_as_number->nb_coerce;
344
345 if (c1 != NULL) {
346 PyObject *coerced1 = *operand1;
347 PyObject *coerced2 = operand2;
348
349 int err = c1(&coerced1, &coerced2);
350
351 if (unlikely(err < 0)) {
352 goto exit_inplace_exception;
353 }
354
355 if (err == 0) {
356 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
357
358 if (likely(mv == NULL)) {
359 binaryfunc slot = mv->nb_rshift;
360
361 if (likely(slot != NULL)) {
362 PyObject *x = slot(coerced1, coerced2);
363
364 Py_DECREF(coerced1);
365 Py_DECREF(coerced2);
366
367 obj_result = x;
368 goto exit_inplace_result_object;
369 }
370 }
371
372 // nb_coerce took a reference.
373 Py_DECREF(coerced1);
374 Py_DECREF(coerced2);
375 }
376 }
377 coercion c2 =
378 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
379
380 if (c2 != NULL) {
381 PyObject *coerced1 = *operand1;
382 PyObject *coerced2 = operand2;
383
384 int err = c2(&coerced2, &coerced1);
385
386 if (unlikely(err < 0)) {
387 goto exit_inplace_exception;
388 }
389
390 if (err == 0) {
391 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
392
393 if (likely(mv == NULL)) {
394 binaryfunc slot = mv->nb_rshift;
395
396 if (likely(slot != NULL)) {
397 PyObject *x = slot(coerced1, coerced2);
398
399 Py_DECREF(coerced1);
400 Py_DECREF(coerced2);
401
402 obj_result = x;
403 goto exit_inplace_result_object;
404 }
405 }
406
407 // nb_coerce took a reference.
408 Py_DECREF(coerced1);
409 Py_DECREF(coerced2);
410 }
411 }
412 }
413#endif
414
415#if PYTHON_VERSION < 0x300
416 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: 'long' and '%s'", type2->tp_name);
417#else
418 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: 'int' and '%s'", type2->tp_name);
419#endif
420 goto exit_inplace_exception;
421 }
422
423exit_inplace_result_object:
424 if (unlikely(obj_result == NULL)) {
425 return false;
426 }
427
428 // We got an object handed, that we have to release.
429 Py_DECREF(*operand1);
430
431 // That's our return value then. As we use a dedicated variable, it's
432 // OK that way.
433 *operand1 = obj_result;
434
435 return true;
436
437exit_inplace_exception:
438 return false;
439}
440static inline bool _INPLACE_OPERATION_RSHIFT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
441 assert(operand1); // Pointer must be non-null.
442
443 CHECK_OBJECT(*operand1);
444 assert(PyLong_CheckExact(*operand1));
445 CHECK_OBJECT(operand2);
446
447 PyTypeObject *type2 = Py_TYPE(operand2);
448
449 if (&PyLong_Type == type2) {
450 // return _BINARY_OPERATION_RSHIFT_LONG_LONG_INPLACE(operand1, operand2);
451
452 // Not every code path will make use of all possible results.
453#if defined(_MSC_VER)
454#pragma warning(push)
455#pragma warning(disable : 4101)
456#endif
457 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
458 NUITKA_MAY_BE_UNUSED long clong_result;
459#if defined(_MSC_VER)
460#pragma warning(pop)
461#endif
462
463 PyObject *x = PyLong_Type.tp_as_number->nb_rshift(*operand1, operand2);
464 assert(x != Py_NotImplemented);
465
466 obj_result = x;
467 goto exit_result_object;
468
469 exit_result_object:
470 if (unlikely(obj_result == NULL)) {
471 goto exit_result_exception;
472 }
473 // We got an object handed, that we have to release.
474 Py_DECREF(*operand1);
475 *operand1 = obj_result;
476 goto exit_result_ok;
477
478 exit_result_ok:
479 return true;
480
481 exit_result_exception:
482 return false;
483 }
484
485 return __INPLACE_OPERATION_RSHIFT_LONG_OBJECT(operand1, operand2);
486}
487
488bool INPLACE_OPERATION_RSHIFT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
489 return _INPLACE_OPERATION_RSHIFT_LONG_OBJECT(operand1, operand2);
490}
491
492#if PYTHON_VERSION < 0x300
493/* Code referring to "INT" corresponds to Python2 'int' and "INT" to Python2 'int'. */
494static inline bool _INPLACE_OPERATION_RSHIFT_INT_INT(PyObject **operand1, PyObject *operand2) {
495 assert(operand1); // Pointer must be non-null.
496
497 CHECK_OBJECT(*operand1);
498 assert(PyInt_CheckExact(*operand1));
499 CHECK_OBJECT(operand2);
500 assert(PyInt_CheckExact(operand2));
501
502 // Not every code path will make use of all possible results.
503#if defined(_MSC_VER)
504#pragma warning(push)
505#pragma warning(disable : 4101)
506#endif
507 NUITKA_MAY_BE_UNUSED bool cbool_result;
508 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
509 NUITKA_MAY_BE_UNUSED long clong_result;
510 NUITKA_MAY_BE_UNUSED double cfloat_result;
511#if defined(_MSC_VER)
512#pragma warning(pop)
513#endif
514
515 CHECK_OBJECT(*operand1);
516 assert(PyInt_CheckExact(*operand1));
517 CHECK_OBJECT(operand2);
518 assert(PyInt_CheckExact(operand2));
519
520 const long a = PyInt_AS_LONG(*operand1);
521 const long b = PyInt_AS_LONG(operand2);
522
523 if (unlikely(b < 0)) {
524 PyThreadState *tstate = PyThreadState_GET();
525
526 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
527 goto exit_result_exception;
528 }
529
530 /* Short cut for zero shift or shifting zero. */
531 if (a == 0 || b == 0) {
532 goto exit_result_ok_left;
533 } else if (b >= LONG_BIT) {
534 if (a < 0) {
535 goto exit_result_ok_const_int_neg_1;
536 } else {
537 goto exit_result_ok_const_int_0;
538 }
539 } else {
540 long r = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
541
542 clong_result = r;
543 goto exit_result_ok_clong;
544 }
545
546exit_result_ok_clong:
547
548 // We got an object handed, that we have to release.
549 Py_DECREF(*operand1);
550
551 // That's our return value then. As we use a dedicated variable, it's
552 // OK that way.
553 *operand1 = Nuitka_PyInt_FromLong(clong_result);
554 goto exit_result_ok;
555
556exit_result_ok_left:
557 goto exit_result_ok;
558
559exit_result_ok_const_int_0:
560 // We got an object handed, that we have to release.
561 Py_DECREF(*operand1);
562 Py_INCREF(const_int_0);
563 *operand1 = const_int_0;
564 goto exit_result_ok;
565
566exit_result_ok_const_int_neg_1:
567 // We got an object handed, that we have to release.
568 Py_DECREF(*operand1);
569 Py_INCREF(const_int_neg_1);
570 *operand1 = const_int_neg_1;
571 goto exit_result_ok;
572
573exit_result_ok:
574 return true;
575
576exit_result_exception:
577 return false;
578}
579
580bool INPLACE_OPERATION_RSHIFT_INT_INT(PyObject **operand1, PyObject *operand2) {
581 return _INPLACE_OPERATION_RSHIFT_INT_INT(operand1, operand2);
582}
583#endif
584
585#if PYTHON_VERSION < 0x300
586/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
587static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_RSHIFT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
588 PyTypeObject *type1 = Py_TYPE(*operand1);
589
590#if defined(_MSC_VER)
591#pragma warning(push)
592#pragma warning(disable : 4101)
593#endif
594 NUITKA_MAY_BE_UNUSED bool cbool_result;
595 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
596#if defined(_MSC_VER)
597#pragma warning(pop)
598#endif
599
600 binaryfunc islot =
601 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_rshift : NULL;
602
603 if (islot != NULL) {
604 PyObject *x = islot(*operand1, operand2);
605
606 if (x != Py_NotImplemented) {
607 obj_result = x;
608 goto exit_inplace_result_object;
609 }
610
611 Py_DECREF_IMMORTAL(x);
612 }
613
614 {
615 binaryfunc slot1 =
616 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_rshift : NULL;
617 binaryfunc slot2 = NULL;
618
619 if (!(type1 == &PyInt_Type)) {
620 // Different types, need to consider second value slot.
621
622 slot2 = PyInt_Type.tp_as_number->nb_rshift;
623
624 if (slot1 == slot2) {
625 slot2 = NULL;
626 }
627 }
628
629 if (slot1 != NULL) {
630 PyObject *x = slot1(*operand1, operand2);
631
632 if (x != Py_NotImplemented) {
633 obj_result = x;
634 goto exit_inplace_result_object;
635 }
636
637 Py_DECREF_IMMORTAL(x);
638 }
639
640 if (slot2 != NULL) {
641 PyObject *x = slot2(*operand1, operand2);
642
643 if (x != Py_NotImplemented) {
644 obj_result = x;
645 goto exit_inplace_result_object;
646 }
647
648 Py_DECREF_IMMORTAL(x);
649 }
650
651#if PYTHON_VERSION < 0x300
652 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
653 coercion c1 =
654 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
655
656 if (c1 != NULL) {
657 PyObject *coerced1 = *operand1;
658 PyObject *coerced2 = operand2;
659
660 int err = c1(&coerced1, &coerced2);
661
662 if (unlikely(err < 0)) {
663 goto exit_inplace_exception;
664 }
665
666 if (err == 0) {
667 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
668
669 if (likely(mv == NULL)) {
670 binaryfunc slot = mv->nb_rshift;
671
672 if (likely(slot != NULL)) {
673 PyObject *x = slot(coerced1, coerced2);
674
675 Py_DECREF(coerced1);
676 Py_DECREF(coerced2);
677
678 obj_result = x;
679 goto exit_inplace_result_object;
680 }
681 }
682
683 // nb_coerce took a reference.
684 Py_DECREF(coerced1);
685 Py_DECREF(coerced2);
686 }
687 }
688 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
689
690 if (c2 != NULL) {
691 PyObject *coerced1 = *operand1;
692 PyObject *coerced2 = operand2;
693
694 int err = c2(&coerced2, &coerced1);
695
696 if (unlikely(err < 0)) {
697 goto exit_inplace_exception;
698 }
699
700 if (err == 0) {
701 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
702
703 if (likely(mv == NULL)) {
704 binaryfunc slot = mv->nb_rshift;
705
706 if (likely(slot != NULL)) {
707 PyObject *x = slot(coerced1, coerced2);
708
709 Py_DECREF(coerced1);
710 Py_DECREF(coerced2);
711
712 obj_result = x;
713 goto exit_inplace_result_object;
714 }
715 }
716
717 // nb_coerce took a reference.
718 Py_DECREF(coerced1);
719 Py_DECREF(coerced2);
720 }
721 }
722 }
723#endif
724
725 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: '%s' and 'int'", type1->tp_name);
726 goto exit_inplace_exception;
727 }
728
729exit_inplace_result_object:
730 if (unlikely(obj_result == NULL)) {
731 return false;
732 }
733
734 // We got an object handed, that we have to release.
735 Py_DECREF(*operand1);
736
737 // That's our return value then. As we use a dedicated variable, it's
738 // OK that way.
739 *operand1 = obj_result;
740
741 return true;
742
743exit_inplace_exception:
744 return false;
745}
746static inline bool _INPLACE_OPERATION_RSHIFT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
747 assert(operand1); // Pointer must be non-null.
748
749 CHECK_OBJECT(*operand1);
750 CHECK_OBJECT(operand2);
751 assert(PyInt_CheckExact(operand2));
752
753 PyTypeObject *type1 = Py_TYPE(*operand1);
754
755 if (type1 == &PyInt_Type) {
756 // return _BINARY_OPERATION_RSHIFT_INT_INT_INPLACE(operand1, operand2);
757
758 // Not every code path will make use of all possible results.
759#if defined(_MSC_VER)
760#pragma warning(push)
761#pragma warning(disable : 4101)
762#endif
763 NUITKA_MAY_BE_UNUSED bool cbool_result;
764 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
765 NUITKA_MAY_BE_UNUSED long clong_result;
766 NUITKA_MAY_BE_UNUSED double cfloat_result;
767#if defined(_MSC_VER)
768#pragma warning(pop)
769#endif
770
771 CHECK_OBJECT(*operand1);
772 assert(PyInt_CheckExact(*operand1));
773 CHECK_OBJECT(operand2);
774 assert(PyInt_CheckExact(operand2));
775
776 const long a = PyInt_AS_LONG(*operand1);
777 const long b = PyInt_AS_LONG(operand2);
778
779 if (unlikely(b < 0)) {
780 PyThreadState *tstate = PyThreadState_GET();
781
782 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
783 goto exit_result_exception;
784 }
785
786 /* Short cut for zero shift or shifting zero. */
787 if (a == 0 || b == 0) {
788 goto exit_result_ok_left;
789 } else if (b >= LONG_BIT) {
790 if (a < 0) {
791 goto exit_result_ok_const_int_neg_1;
792 } else {
793 goto exit_result_ok_const_int_0;
794 }
795 } else {
796 long r = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
797
798 clong_result = r;
799 goto exit_result_ok_clong;
800 }
801
802 exit_result_ok_clong:
803
804 // We got an object handed, that we have to release.
805 Py_DECREF(*operand1);
806
807 // That's our return value then. As we use a dedicated variable, it's
808 // OK that way.
809 *operand1 = Nuitka_PyInt_FromLong(clong_result);
810 goto exit_result_ok;
811
812 exit_result_ok_left:
813 goto exit_result_ok;
814
815 exit_result_ok_const_int_0:
816 // We got an object handed, that we have to release.
817 Py_DECREF(*operand1);
818 Py_INCREF(const_int_0);
819 *operand1 = const_int_0;
820 goto exit_result_ok;
821
822 exit_result_ok_const_int_neg_1:
823 // We got an object handed, that we have to release.
824 Py_DECREF(*operand1);
825 Py_INCREF(const_int_neg_1);
826 *operand1 = const_int_neg_1;
827 goto exit_result_ok;
828
829 exit_result_ok:
830 return true;
831
832 exit_result_exception:
833 return false;
834 }
835
836 return __INPLACE_OPERATION_RSHIFT_OBJECT_INT(operand1, operand2);
837}
838
839bool INPLACE_OPERATION_RSHIFT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
840 return _INPLACE_OPERATION_RSHIFT_OBJECT_INT(operand1, operand2);
841}
842#endif
843
844#if PYTHON_VERSION < 0x300
845/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
846static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_RSHIFT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
847 PyTypeObject *type2 = Py_TYPE(operand2);
848
849#if defined(_MSC_VER)
850#pragma warning(push)
851#pragma warning(disable : 4101)
852#endif
853 NUITKA_MAY_BE_UNUSED bool cbool_result;
854 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
855#if defined(_MSC_VER)
856#pragma warning(pop)
857#endif
858
859 // No inplace number slot nb_inplace_rshift available for this type.
860
861 {
862 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_rshift;
863 binaryfunc slot2 = NULL;
864
865 if (!(&PyInt_Type == type2)) {
866 // Different types, need to consider second value slot.
867
868 slot2 =
869 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_rshift : NULL;
870
871 if (slot1 == slot2) {
872 slot2 = NULL;
873 }
874 }
875
876 if (slot1 != NULL) {
877 if (slot2 != NULL) {
878 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
879 PyObject *x = slot2(*operand1, operand2);
880
881 if (x != Py_NotImplemented) {
882 obj_result = x;
883 goto exit_inplace_result_object;
884 }
885
886 Py_DECREF_IMMORTAL(x);
887 slot2 = NULL;
888 }
889 }
890
891 PyObject *x = slot1(*operand1, operand2);
892
893 if (x != Py_NotImplemented) {
894 obj_result = x;
895 goto exit_inplace_result_object;
896 }
897
898 Py_DECREF_IMMORTAL(x);
899 }
900
901 if (slot2 != NULL) {
902 PyObject *x = slot2(*operand1, operand2);
903
904 if (x != Py_NotImplemented) {
905 obj_result = x;
906 goto exit_inplace_result_object;
907 }
908
909 Py_DECREF_IMMORTAL(x);
910 }
911
912#if PYTHON_VERSION < 0x300
913 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
914 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
915
916 if (c1 != NULL) {
917 PyObject *coerced1 = *operand1;
918 PyObject *coerced2 = operand2;
919
920 int err = c1(&coerced1, &coerced2);
921
922 if (unlikely(err < 0)) {
923 goto exit_inplace_exception;
924 }
925
926 if (err == 0) {
927 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
928
929 if (likely(mv == NULL)) {
930 binaryfunc slot = mv->nb_rshift;
931
932 if (likely(slot != NULL)) {
933 PyObject *x = slot(coerced1, coerced2);
934
935 Py_DECREF(coerced1);
936 Py_DECREF(coerced2);
937
938 obj_result = x;
939 goto exit_inplace_result_object;
940 }
941 }
942
943 // nb_coerce took a reference.
944 Py_DECREF(coerced1);
945 Py_DECREF(coerced2);
946 }
947 }
948 coercion c2 =
949 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
950
951 if (c2 != NULL) {
952 PyObject *coerced1 = *operand1;
953 PyObject *coerced2 = operand2;
954
955 int err = c2(&coerced2, &coerced1);
956
957 if (unlikely(err < 0)) {
958 goto exit_inplace_exception;
959 }
960
961 if (err == 0) {
962 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
963
964 if (likely(mv == NULL)) {
965 binaryfunc slot = mv->nb_rshift;
966
967 if (likely(slot != NULL)) {
968 PyObject *x = slot(coerced1, coerced2);
969
970 Py_DECREF(coerced1);
971 Py_DECREF(coerced2);
972
973 obj_result = x;
974 goto exit_inplace_result_object;
975 }
976 }
977
978 // nb_coerce took a reference.
979 Py_DECREF(coerced1);
980 Py_DECREF(coerced2);
981 }
982 }
983 }
984#endif
985
986 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: 'int' and '%s'", type2->tp_name);
987 goto exit_inplace_exception;
988 }
989
990exit_inplace_result_object:
991 if (unlikely(obj_result == NULL)) {
992 return false;
993 }
994
995 // We got an object handed, that we have to release.
996 Py_DECREF(*operand1);
997
998 // That's our return value then. As we use a dedicated variable, it's
999 // OK that way.
1000 *operand1 = obj_result;
1001
1002 return true;
1003
1004exit_inplace_exception:
1005 return false;
1006}
1007static inline bool _INPLACE_OPERATION_RSHIFT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
1008 assert(operand1); // Pointer must be non-null.
1009
1010 CHECK_OBJECT(*operand1);
1011 assert(PyInt_CheckExact(*operand1));
1012 CHECK_OBJECT(operand2);
1013
1014 PyTypeObject *type2 = Py_TYPE(operand2);
1015
1016 if (&PyInt_Type == type2) {
1017 // return _BINARY_OPERATION_RSHIFT_INT_INT_INPLACE(operand1, operand2);
1018
1019 // Not every code path will make use of all possible results.
1020#if defined(_MSC_VER)
1021#pragma warning(push)
1022#pragma warning(disable : 4101)
1023#endif
1024 NUITKA_MAY_BE_UNUSED bool cbool_result;
1025 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1026 NUITKA_MAY_BE_UNUSED long clong_result;
1027 NUITKA_MAY_BE_UNUSED double cfloat_result;
1028#if defined(_MSC_VER)
1029#pragma warning(pop)
1030#endif
1031
1032 CHECK_OBJECT(*operand1);
1033 assert(PyInt_CheckExact(*operand1));
1034 CHECK_OBJECT(operand2);
1035 assert(PyInt_CheckExact(operand2));
1036
1037 const long a = PyInt_AS_LONG(*operand1);
1038 const long b = PyInt_AS_LONG(operand2);
1039
1040 if (unlikely(b < 0)) {
1041 PyThreadState *tstate = PyThreadState_GET();
1042
1043 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
1044 goto exit_result_exception;
1045 }
1046
1047 /* Short cut for zero shift or shifting zero. */
1048 if (a == 0 || b == 0) {
1049 goto exit_result_ok_left;
1050 } else if (b >= LONG_BIT) {
1051 if (a < 0) {
1052 goto exit_result_ok_const_int_neg_1;
1053 } else {
1054 goto exit_result_ok_const_int_0;
1055 }
1056 } else {
1057 long r = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
1058
1059 clong_result = r;
1060 goto exit_result_ok_clong;
1061 }
1062
1063 exit_result_ok_clong:
1064
1065 // We got an object handed, that we have to release.
1066 Py_DECREF(*operand1);
1067
1068 // That's our return value then. As we use a dedicated variable, it's
1069 // OK that way.
1070 *operand1 = Nuitka_PyInt_FromLong(clong_result);
1071 goto exit_result_ok;
1072
1073 exit_result_ok_left:
1074 goto exit_result_ok;
1075
1076 exit_result_ok_const_int_0:
1077 // We got an object handed, that we have to release.
1078 Py_DECREF(*operand1);
1079 Py_INCREF(const_int_0);
1080 *operand1 = const_int_0;
1081 goto exit_result_ok;
1082
1083 exit_result_ok_const_int_neg_1:
1084 // We got an object handed, that we have to release.
1085 Py_DECREF(*operand1);
1086 Py_INCREF(const_int_neg_1);
1087 *operand1 = const_int_neg_1;
1088 goto exit_result_ok;
1089
1090 exit_result_ok:
1091 return true;
1092
1093 exit_result_exception:
1094 return false;
1095 }
1096
1097 return __INPLACE_OPERATION_RSHIFT_INT_OBJECT(operand1, operand2);
1098}
1099
1100bool INPLACE_OPERATION_RSHIFT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
1101 return _INPLACE_OPERATION_RSHIFT_INT_OBJECT(operand1, operand2);
1102}
1103#endif
1104
1105#if PYTHON_VERSION < 0x300
1106/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
1107static inline bool _INPLACE_OPERATION_RSHIFT_LONG_INT(PyObject **operand1, PyObject *operand2) {
1108 assert(operand1); // Pointer must be non-null.
1109
1110 CHECK_OBJECT(*operand1);
1111 assert(PyLong_CheckExact(*operand1));
1112 CHECK_OBJECT(operand2);
1113 assert(PyInt_CheckExact(operand2));
1114
1115#if defined(_MSC_VER)
1116#pragma warning(push)
1117#pragma warning(disable : 4101)
1118#endif
1119 NUITKA_MAY_BE_UNUSED bool cbool_result;
1120 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1121#if defined(_MSC_VER)
1122#pragma warning(pop)
1123#endif
1124
1125 // No inplace number slot nb_inplace_rshift available for this type.
1126
1127 {
1128 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_rshift;
1129 // Slot2 ignored on purpose, type1 takes precedence.
1130
1131 if (slot1 != NULL) {
1132 PyObject *x = slot1(*operand1, operand2);
1133
1134 if (x != Py_NotImplemented) {
1135 obj_result = x;
1136 goto exit_inplace_result_object;
1137 }
1138
1139 Py_DECREF_IMMORTAL(x);
1140 }
1141
1142 // Statically recognized that coercion is not possible with these types
1143
1144 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: 'long' and 'int'");
1145 goto exit_inplace_exception;
1146 }
1147
1148exit_inplace_result_object:
1149 if (unlikely(obj_result == NULL)) {
1150 return false;
1151 }
1152
1153 // We got an object handed, that we have to release.
1154 Py_DECREF(*operand1);
1155
1156 // That's our return value then. As we use a dedicated variable, it's
1157 // OK that way.
1158 *operand1 = obj_result;
1159
1160 return true;
1161
1162exit_inplace_exception:
1163 return false;
1164}
1165
1166bool INPLACE_OPERATION_RSHIFT_LONG_INT(PyObject **operand1, PyObject *operand2) {
1167 return _INPLACE_OPERATION_RSHIFT_LONG_INT(operand1, operand2);
1168}
1169#endif
1170
1171#if PYTHON_VERSION < 0x300
1172/* Code referring to "INT" corresponds to Python2 'int' and "LONG" to Python2 'long', Python3 'int'. */
1173static inline bool _INPLACE_OPERATION_RSHIFT_INT_LONG(PyObject **operand1, PyObject *operand2) {
1174 assert(operand1); // Pointer must be non-null.
1175
1176 CHECK_OBJECT(*operand1);
1177 assert(PyInt_CheckExact(*operand1));
1178 CHECK_OBJECT(operand2);
1179 assert(PyLong_CheckExact(operand2));
1180
1181#if defined(_MSC_VER)
1182#pragma warning(push)
1183#pragma warning(disable : 4101)
1184#endif
1185 NUITKA_MAY_BE_UNUSED bool cbool_result;
1186 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1187#if defined(_MSC_VER)
1188#pragma warning(pop)
1189#endif
1190
1191 // No inplace number slot nb_inplace_rshift available for this type.
1192
1193 {
1194 // Slot1 ignored on purpose, type2 takes precedence.
1195 binaryfunc slot2 = NULL;
1196
1197 if (!(0)) {
1198 // Different types, need to consider second value slot.
1199
1200 slot2 = PyLong_Type.tp_as_number->nb_rshift;
1201 }
1202
1203 if (slot2 != NULL) {
1204 PyObject *x = slot2(*operand1, operand2);
1205
1206 if (x != Py_NotImplemented) {
1207 obj_result = x;
1208 goto exit_inplace_result_object;
1209 }
1210
1211 Py_DECREF_IMMORTAL(x);
1212 }
1213
1214 // Statically recognized that coercion is not possible with these types
1215
1216 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: 'int' and 'long'");
1217 goto exit_inplace_exception;
1218 }
1219
1220exit_inplace_result_object:
1221 if (unlikely(obj_result == NULL)) {
1222 return false;
1223 }
1224
1225 // We got an object handed, that we have to release.
1226 Py_DECREF(*operand1);
1227
1228 // That's our return value then. As we use a dedicated variable, it's
1229 // OK that way.
1230 *operand1 = obj_result;
1231
1232 return true;
1233
1234exit_inplace_exception:
1235 return false;
1236}
1237
1238bool INPLACE_OPERATION_RSHIFT_INT_LONG(PyObject **operand1, PyObject *operand2) {
1239 return _INPLACE_OPERATION_RSHIFT_INT_LONG(operand1, operand2);
1240}
1241#endif
1242
1243/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
1244static inline bool _INPLACE_OPERATION_RSHIFT_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
1245 assert(operand1); // Pointer must be non-null.
1246
1247 CHECK_OBJECT(*operand1);
1248 CHECK_OBJECT(operand2);
1249
1250#if PYTHON_VERSION < 0x300
1251 if (PyInt_CheckExact(*operand1) && PyInt_CheckExact(operand2)) {
1252
1253 // Not every code path will make use of all possible results.
1254#if defined(_MSC_VER)
1255#pragma warning(push)
1256#pragma warning(disable : 4101)
1257#endif
1258 NUITKA_MAY_BE_UNUSED bool cbool_result;
1259 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1260 NUITKA_MAY_BE_UNUSED long clong_result;
1261 NUITKA_MAY_BE_UNUSED double cfloat_result;
1262#if defined(_MSC_VER)
1263#pragma warning(pop)
1264#endif
1265
1266 CHECK_OBJECT(*operand1);
1267 assert(PyInt_CheckExact(*operand1));
1268 CHECK_OBJECT(operand2);
1269 assert(PyInt_CheckExact(operand2));
1270
1271 const long a = PyInt_AS_LONG(*operand1);
1272 const long b = PyInt_AS_LONG(operand2);
1273
1274 if (unlikely(b < 0)) {
1275 PyThreadState *tstate = PyThreadState_GET();
1276
1277 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
1278 goto exit_result_exception;
1279 }
1280
1281 /* Short cut for zero shift or shifting zero. */
1282 if (a == 0 || b == 0) {
1283 goto exit_result_ok_left;
1284 } else if (b >= LONG_BIT) {
1285 if (a < 0) {
1286 goto exit_result_ok_const_int_neg_1;
1287 } else {
1288 goto exit_result_ok_const_int_0;
1289 }
1290 } else {
1291 long r = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
1292
1293 clong_result = r;
1294 goto exit_result_ok_clong;
1295 }
1296
1297 exit_result_ok_clong:
1298
1299 // We got an object handed, that we have to release.
1300 Py_DECREF(*operand1);
1301
1302 // That's our return value then. As we use a dedicated variable, it's
1303 // OK that way.
1304 *operand1 = Nuitka_PyInt_FromLong(clong_result);
1305 goto exit_result_ok;
1306
1307 exit_result_ok_left:
1308 goto exit_result_ok;
1309
1310 exit_result_ok_const_int_0:
1311 // We got an object handed, that we have to release.
1312 Py_DECREF(*operand1);
1313 Py_INCREF(const_int_0);
1314 *operand1 = const_int_0;
1315 goto exit_result_ok;
1316
1317 exit_result_ok_const_int_neg_1:
1318 // We got an object handed, that we have to release.
1319 Py_DECREF(*operand1);
1320 Py_INCREF(const_int_neg_1);
1321 *operand1 = const_int_neg_1;
1322 goto exit_result_ok;
1323
1324 exit_result_ok:
1325 return true;
1326
1327 exit_result_exception:
1328 return false;
1329 }
1330#endif
1331
1332 if (Py_TYPE(*operand1) == Py_TYPE(operand2)) {
1333#if PYTHON_VERSION >= 0x300
1334 if (PyLong_CheckExact(operand2)) {
1335 return _INPLACE_OPERATION_RSHIFT_LONG_LONG(operand1, operand2);
1336 }
1337#endif
1338 }
1339
1340 PyTypeObject *type1 = Py_TYPE(*operand1);
1341 PyTypeObject *type2 = Py_TYPE(operand2);
1342
1343#if defined(_MSC_VER)
1344#pragma warning(push)
1345#pragma warning(disable : 4101)
1346#endif
1347 NUITKA_MAY_BE_UNUSED bool cbool_result;
1348 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1349#if defined(_MSC_VER)
1350#pragma warning(pop)
1351#endif
1352
1353 binaryfunc islot =
1354 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_rshift : NULL;
1355
1356 if (islot != NULL) {
1357 PyObject *x = islot(*operand1, operand2);
1358
1359 if (x != Py_NotImplemented) {
1360 obj_result = x;
1361 goto exit_inplace_result_object;
1362 }
1363
1364 Py_DECREF_IMMORTAL(x);
1365 }
1366
1367 {
1368 binaryfunc slot1 =
1369 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_rshift : NULL;
1370 binaryfunc slot2 = NULL;
1371
1372 if (!(type1 == type2)) {
1373 // Different types, need to consider second value slot.
1374
1375 slot2 =
1376 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_rshift : NULL;
1377
1378 if (slot1 == slot2) {
1379 slot2 = NULL;
1380 }
1381 }
1382
1383 if (slot1 != NULL) {
1384 if (slot2 != NULL) {
1385 if (Nuitka_Type_IsSubtype(type2, type1)) {
1386 PyObject *x = slot2(*operand1, operand2);
1387
1388 if (x != Py_NotImplemented) {
1389 obj_result = x;
1390 goto exit_inplace_result_object;
1391 }
1392
1393 Py_DECREF_IMMORTAL(x);
1394 slot2 = NULL;
1395 }
1396 }
1397
1398 PyObject *x = slot1(*operand1, operand2);
1399
1400 if (x != Py_NotImplemented) {
1401 obj_result = x;
1402 goto exit_inplace_result_object;
1403 }
1404
1405 Py_DECREF_IMMORTAL(x);
1406 }
1407
1408 if (slot2 != NULL) {
1409 PyObject *x = slot2(*operand1, operand2);
1410
1411 if (x != Py_NotImplemented) {
1412 obj_result = x;
1413 goto exit_inplace_result_object;
1414 }
1415
1416 Py_DECREF_IMMORTAL(x);
1417 }
1418
1419#if PYTHON_VERSION < 0x300
1420 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
1421 coercion c1 =
1422 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1423
1424 if (c1 != NULL) {
1425 PyObject *coerced1 = *operand1;
1426 PyObject *coerced2 = operand2;
1427
1428 int err = c1(&coerced1, &coerced2);
1429
1430 if (unlikely(err < 0)) {
1431 goto exit_inplace_exception;
1432 }
1433
1434 if (err == 0) {
1435 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1436
1437 if (likely(mv == NULL)) {
1438 binaryfunc slot = mv->nb_rshift;
1439
1440 if (likely(slot != NULL)) {
1441 PyObject *x = slot(coerced1, coerced2);
1442
1443 Py_DECREF(coerced1);
1444 Py_DECREF(coerced2);
1445
1446 obj_result = x;
1447 goto exit_inplace_result_object;
1448 }
1449 }
1450
1451 // nb_coerce took a reference.
1452 Py_DECREF(coerced1);
1453 Py_DECREF(coerced2);
1454 }
1455 }
1456 coercion c2 =
1457 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1458
1459 if (c2 != NULL) {
1460 PyObject *coerced1 = *operand1;
1461 PyObject *coerced2 = operand2;
1462
1463 int err = c2(&coerced2, &coerced1);
1464
1465 if (unlikely(err < 0)) {
1466 goto exit_inplace_exception;
1467 }
1468
1469 if (err == 0) {
1470 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1471
1472 if (likely(mv == NULL)) {
1473 binaryfunc slot = mv->nb_rshift;
1474
1475 if (likely(slot != NULL)) {
1476 PyObject *x = slot(coerced1, coerced2);
1477
1478 Py_DECREF(coerced1);
1479 Py_DECREF(coerced2);
1480
1481 obj_result = x;
1482 goto exit_inplace_result_object;
1483 }
1484 }
1485
1486 // nb_coerce took a reference.
1487 Py_DECREF(coerced1);
1488 Py_DECREF(coerced2);
1489 }
1490 }
1491 }
1492#endif
1493
1494 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for >>=: '%s' and '%s'", type1->tp_name,
1495 type2->tp_name);
1496 goto exit_inplace_exception;
1497 }
1498
1499exit_inplace_result_object:
1500 if (unlikely(obj_result == NULL)) {
1501 return false;
1502 }
1503
1504 // We got an object handed, that we have to release.
1505 Py_DECREF(*operand1);
1506
1507 // That's our return value then. As we use a dedicated variable, it's
1508 // OK that way.
1509 *operand1 = obj_result;
1510
1511 return true;
1512
1513exit_inplace_exception:
1514 return false;
1515}
1516
1517bool INPLACE_OPERATION_RSHIFT_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
1518 return _INPLACE_OPERATION_RSHIFT_OBJECT_OBJECT(operand1, operand2);
1519}
1520
1521// Part of "Nuitka", an optimizing Python compiler that is compatible and
1522// integrates with CPython, but also works on its own.
1523//
1524// Licensed under the Apache License, Version 2.0 (the "License");
1525// you may not use this file except in compliance with the License.
1526// You may obtain a copy of the License at
1527//
1528// http://www.apache.org/licenses/LICENSE-2.0
1529//
1530// Unless required by applicable law or agreed to in writing, software
1531// distributed under the License is distributed on an "AS IS" BASIS,
1532// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1533// See the License for the specific language governing permissions and
1534// limitations under the License.