Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationInplaceLshift.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 "<<" (LSHIFT) 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_LSHIFT_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_lshift(*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_LSHIFT_LONG_LONG(PyObject **operand1, PyObject *operand2) {
55 return _INPLACE_OPERATION_LSHIFT_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_LSHIFT_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_lshift : 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_lshift : 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_lshift;
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_lshift;
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_lshift;
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_LSHIFT_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_LSHIFT_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_lshift(*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_LSHIFT_OBJECT_LONG(operand1, operand2);
268}
269
270bool INPLACE_OPERATION_LSHIFT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
271 return _INPLACE_OPERATION_LSHIFT_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_LSHIFT_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_lshift available for this type.
289
290 {
291 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_lshift;
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_lshift : 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_lshift;
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_lshift;
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_LSHIFT_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_LSHIFT_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_lshift(*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_LSHIFT_LONG_OBJECT(operand1, operand2);
486}
487
488bool INPLACE_OPERATION_LSHIFT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
489 return _INPLACE_OPERATION_LSHIFT_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_LSHIFT_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 /* Short cut for zero shift or shifting zero. */
530 if (a == 0 || b == 0) {
531 goto exit_result_ok_left;
532 } else if (b >= LONG_BIT) {
533 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
534 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
535
536 // TODO: Change this to using CLONG once we specialize that too.
537 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
538
539 Py_DECREF(operand1_long);
540 Py_DECREF(operand2_long);
541
542 obj_result = r;
543 goto exit_result_object;
544 } else {
545 long c = a << b;
546
547 if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
548 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
549 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
550
551 // TODO: Change this to using CLONG once we specialize that too.
552 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
553
554 Py_DECREF(operand1_long);
555 Py_DECREF(operand2_long);
556
557 obj_result = r;
558 goto exit_result_object;
559 } else {
560 clong_result = c;
561 goto exit_result_ok_clong;
562 }
563 }
564
565exit_result_ok_clong:
566
567 // We got an object handed, that we have to release.
568 Py_DECREF(*operand1);
569
570 // That's our return value then. As we use a dedicated variable, it's
571 // OK that way.
572 *operand1 = Nuitka_PyInt_FromLong(clong_result);
573 goto exit_result_ok;
574
575exit_result_ok_left:
576 goto exit_result_ok;
577
578exit_result_object:
579 if (unlikely(obj_result == NULL)) {
580 goto exit_result_exception;
581 }
582 // We got an object handed, that we have to release.
583 Py_DECREF(*operand1);
584
585 *operand1 = obj_result;
586 goto exit_result_ok;
587
588exit_result_ok:
589 return true;
590
591exit_result_exception:
592 return false;
593}
594
595bool INPLACE_OPERATION_LSHIFT_INT_INT(PyObject **operand1, PyObject *operand2) {
596 return _INPLACE_OPERATION_LSHIFT_INT_INT(operand1, operand2);
597}
598#endif
599
600#if PYTHON_VERSION < 0x300
601/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
602static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_LSHIFT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
603 PyTypeObject *type1 = Py_TYPE(*operand1);
604
605#if defined(_MSC_VER)
606#pragma warning(push)
607#pragma warning(disable : 4101)
608#endif
609 NUITKA_MAY_BE_UNUSED bool cbool_result;
610 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
611#if defined(_MSC_VER)
612#pragma warning(pop)
613#endif
614
615 binaryfunc islot =
616 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_lshift : NULL;
617
618 if (islot != NULL) {
619 PyObject *x = islot(*operand1, operand2);
620
621 if (x != Py_NotImplemented) {
622 obj_result = x;
623 goto exit_inplace_result_object;
624 }
625
626 Py_DECREF_IMMORTAL(x);
627 }
628
629 {
630 binaryfunc slot1 =
631 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_lshift : NULL;
632 binaryfunc slot2 = NULL;
633
634 if (!(type1 == &PyInt_Type)) {
635 // Different types, need to consider second value slot.
636
637 slot2 = PyInt_Type.tp_as_number->nb_lshift;
638
639 if (slot1 == slot2) {
640 slot2 = NULL;
641 }
642 }
643
644 if (slot1 != NULL) {
645 PyObject *x = slot1(*operand1, operand2);
646
647 if (x != Py_NotImplemented) {
648 obj_result = x;
649 goto exit_inplace_result_object;
650 }
651
652 Py_DECREF_IMMORTAL(x);
653 }
654
655 if (slot2 != NULL) {
656 PyObject *x = slot2(*operand1, operand2);
657
658 if (x != Py_NotImplemented) {
659 obj_result = x;
660 goto exit_inplace_result_object;
661 }
662
663 Py_DECREF_IMMORTAL(x);
664 }
665
666#if PYTHON_VERSION < 0x300
667 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
668 coercion c1 =
669 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
670
671 if (c1 != NULL) {
672 PyObject *coerced1 = *operand1;
673 PyObject *coerced2 = operand2;
674
675 int err = c1(&coerced1, &coerced2);
676
677 if (unlikely(err < 0)) {
678 goto exit_inplace_exception;
679 }
680
681 if (err == 0) {
682 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
683
684 if (likely(mv == NULL)) {
685 binaryfunc slot = mv->nb_lshift;
686
687 if (likely(slot != NULL)) {
688 PyObject *x = slot(coerced1, coerced2);
689
690 Py_DECREF(coerced1);
691 Py_DECREF(coerced2);
692
693 obj_result = x;
694 goto exit_inplace_result_object;
695 }
696 }
697
698 // nb_coerce took a reference.
699 Py_DECREF(coerced1);
700 Py_DECREF(coerced2);
701 }
702 }
703 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
704
705 if (c2 != NULL) {
706 PyObject *coerced1 = *operand1;
707 PyObject *coerced2 = operand2;
708
709 int err = c2(&coerced2, &coerced1);
710
711 if (unlikely(err < 0)) {
712 goto exit_inplace_exception;
713 }
714
715 if (err == 0) {
716 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
717
718 if (likely(mv == NULL)) {
719 binaryfunc slot = mv->nb_lshift;
720
721 if (likely(slot != NULL)) {
722 PyObject *x = slot(coerced1, coerced2);
723
724 Py_DECREF(coerced1);
725 Py_DECREF(coerced2);
726
727 obj_result = x;
728 goto exit_inplace_result_object;
729 }
730 }
731
732 // nb_coerce took a reference.
733 Py_DECREF(coerced1);
734 Py_DECREF(coerced2);
735 }
736 }
737 }
738#endif
739
740 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for <<=: '%s' and 'int'", type1->tp_name);
741 goto exit_inplace_exception;
742 }
743
744exit_inplace_result_object:
745 if (unlikely(obj_result == NULL)) {
746 return false;
747 }
748
749 // We got an object handed, that we have to release.
750 Py_DECREF(*operand1);
751
752 // That's our return value then. As we use a dedicated variable, it's
753 // OK that way.
754 *operand1 = obj_result;
755
756 return true;
757
758exit_inplace_exception:
759 return false;
760}
761static inline bool _INPLACE_OPERATION_LSHIFT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
762 assert(operand1); // Pointer must be non-null.
763
764 CHECK_OBJECT(*operand1);
765 CHECK_OBJECT(operand2);
766 assert(PyInt_CheckExact(operand2));
767
768 PyTypeObject *type1 = Py_TYPE(*operand1);
769
770 if (type1 == &PyInt_Type) {
771 // return _BINARY_OPERATION_LSHIFT_INT_INT_INPLACE(operand1, operand2);
772
773 // Not every code path will make use of all possible results.
774#if defined(_MSC_VER)
775#pragma warning(push)
776#pragma warning(disable : 4101)
777#endif
778 NUITKA_MAY_BE_UNUSED bool cbool_result;
779 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
780 NUITKA_MAY_BE_UNUSED long clong_result;
781 NUITKA_MAY_BE_UNUSED double cfloat_result;
782#if defined(_MSC_VER)
783#pragma warning(pop)
784#endif
785
786 CHECK_OBJECT(*operand1);
787 assert(PyInt_CheckExact(*operand1));
788 CHECK_OBJECT(operand2);
789 assert(PyInt_CheckExact(operand2));
790
791 const long a = PyInt_AS_LONG(*operand1);
792 const long b = PyInt_AS_LONG(operand2);
793
794 if (unlikely(b < 0)) {
795 PyThreadState *tstate = PyThreadState_GET();
796
797 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
798 goto exit_result_exception;
799 }
800 /* Short cut for zero shift or shifting zero. */
801 if (a == 0 || b == 0) {
802 goto exit_result_ok_left;
803 } else if (b >= LONG_BIT) {
804 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
805 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
806
807 // TODO: Change this to using CLONG once we specialize that too.
808 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
809
810 Py_DECREF(operand1_long);
811 Py_DECREF(operand2_long);
812
813 obj_result = r;
814 goto exit_result_object;
815 } else {
816 long c = a << b;
817
818 if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
819 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
820 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
821
822 // TODO: Change this to using CLONG once we specialize that too.
823 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
824
825 Py_DECREF(operand1_long);
826 Py_DECREF(operand2_long);
827
828 obj_result = r;
829 goto exit_result_object;
830 } else {
831 clong_result = c;
832 goto exit_result_ok_clong;
833 }
834 }
835
836 exit_result_ok_clong:
837
838 // We got an object handed, that we have to release.
839 Py_DECREF(*operand1);
840
841 // That's our return value then. As we use a dedicated variable, it's
842 // OK that way.
843 *operand1 = Nuitka_PyInt_FromLong(clong_result);
844 goto exit_result_ok;
845
846 exit_result_ok_left:
847 goto exit_result_ok;
848
849 exit_result_object:
850 if (unlikely(obj_result == NULL)) {
851 goto exit_result_exception;
852 }
853 // We got an object handed, that we have to release.
854 Py_DECREF(*operand1);
855
856 *operand1 = obj_result;
857 goto exit_result_ok;
858
859 exit_result_ok:
860 return true;
861
862 exit_result_exception:
863 return false;
864 }
865
866 return __INPLACE_OPERATION_LSHIFT_OBJECT_INT(operand1, operand2);
867}
868
869bool INPLACE_OPERATION_LSHIFT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
870 return _INPLACE_OPERATION_LSHIFT_OBJECT_INT(operand1, operand2);
871}
872#endif
873
874#if PYTHON_VERSION < 0x300
875/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
876static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_LSHIFT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
877 PyTypeObject *type2 = Py_TYPE(operand2);
878
879#if defined(_MSC_VER)
880#pragma warning(push)
881#pragma warning(disable : 4101)
882#endif
883 NUITKA_MAY_BE_UNUSED bool cbool_result;
884 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
885#if defined(_MSC_VER)
886#pragma warning(pop)
887#endif
888
889 // No inplace number slot nb_inplace_lshift available for this type.
890
891 {
892 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_lshift;
893 binaryfunc slot2 = NULL;
894
895 if (!(&PyInt_Type == type2)) {
896 // Different types, need to consider second value slot.
897
898 slot2 =
899 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_lshift : NULL;
900
901 if (slot1 == slot2) {
902 slot2 = NULL;
903 }
904 }
905
906 if (slot1 != NULL) {
907 if (slot2 != NULL) {
908 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
909 PyObject *x = slot2(*operand1, operand2);
910
911 if (x != Py_NotImplemented) {
912 obj_result = x;
913 goto exit_inplace_result_object;
914 }
915
916 Py_DECREF_IMMORTAL(x);
917 slot2 = NULL;
918 }
919 }
920
921 PyObject *x = slot1(*operand1, operand2);
922
923 if (x != Py_NotImplemented) {
924 obj_result = x;
925 goto exit_inplace_result_object;
926 }
927
928 Py_DECREF_IMMORTAL(x);
929 }
930
931 if (slot2 != NULL) {
932 PyObject *x = slot2(*operand1, operand2);
933
934 if (x != Py_NotImplemented) {
935 obj_result = x;
936 goto exit_inplace_result_object;
937 }
938
939 Py_DECREF_IMMORTAL(x);
940 }
941
942#if PYTHON_VERSION < 0x300
943 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
944 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
945
946 if (c1 != NULL) {
947 PyObject *coerced1 = *operand1;
948 PyObject *coerced2 = operand2;
949
950 int err = c1(&coerced1, &coerced2);
951
952 if (unlikely(err < 0)) {
953 goto exit_inplace_exception;
954 }
955
956 if (err == 0) {
957 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
958
959 if (likely(mv == NULL)) {
960 binaryfunc slot = mv->nb_lshift;
961
962 if (likely(slot != NULL)) {
963 PyObject *x = slot(coerced1, coerced2);
964
965 Py_DECREF(coerced1);
966 Py_DECREF(coerced2);
967
968 obj_result = x;
969 goto exit_inplace_result_object;
970 }
971 }
972
973 // nb_coerce took a reference.
974 Py_DECREF(coerced1);
975 Py_DECREF(coerced2);
976 }
977 }
978 coercion c2 =
979 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
980
981 if (c2 != NULL) {
982 PyObject *coerced1 = *operand1;
983 PyObject *coerced2 = operand2;
984
985 int err = c2(&coerced2, &coerced1);
986
987 if (unlikely(err < 0)) {
988 goto exit_inplace_exception;
989 }
990
991 if (err == 0) {
992 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
993
994 if (likely(mv == NULL)) {
995 binaryfunc slot = mv->nb_lshift;
996
997 if (likely(slot != NULL)) {
998 PyObject *x = slot(coerced1, coerced2);
999
1000 Py_DECREF(coerced1);
1001 Py_DECREF(coerced2);
1002
1003 obj_result = x;
1004 goto exit_inplace_result_object;
1005 }
1006 }
1007
1008 // nb_coerce took a reference.
1009 Py_DECREF(coerced1);
1010 Py_DECREF(coerced2);
1011 }
1012 }
1013 }
1014#endif
1015
1016 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for <<=: 'int' and '%s'", type2->tp_name);
1017 goto exit_inplace_exception;
1018 }
1019
1020exit_inplace_result_object:
1021 if (unlikely(obj_result == NULL)) {
1022 return false;
1023 }
1024
1025 // We got an object handed, that we have to release.
1026 Py_DECREF(*operand1);
1027
1028 // That's our return value then. As we use a dedicated variable, it's
1029 // OK that way.
1030 *operand1 = obj_result;
1031
1032 return true;
1033
1034exit_inplace_exception:
1035 return false;
1036}
1037static inline bool _INPLACE_OPERATION_LSHIFT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
1038 assert(operand1); // Pointer must be non-null.
1039
1040 CHECK_OBJECT(*operand1);
1041 assert(PyInt_CheckExact(*operand1));
1042 CHECK_OBJECT(operand2);
1043
1044 PyTypeObject *type2 = Py_TYPE(operand2);
1045
1046 if (&PyInt_Type == type2) {
1047 // return _BINARY_OPERATION_LSHIFT_INT_INT_INPLACE(operand1, operand2);
1048
1049 // Not every code path will make use of all possible results.
1050#if defined(_MSC_VER)
1051#pragma warning(push)
1052#pragma warning(disable : 4101)
1053#endif
1054 NUITKA_MAY_BE_UNUSED bool cbool_result;
1055 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1056 NUITKA_MAY_BE_UNUSED long clong_result;
1057 NUITKA_MAY_BE_UNUSED double cfloat_result;
1058#if defined(_MSC_VER)
1059#pragma warning(pop)
1060#endif
1061
1062 CHECK_OBJECT(*operand1);
1063 assert(PyInt_CheckExact(*operand1));
1064 CHECK_OBJECT(operand2);
1065 assert(PyInt_CheckExact(operand2));
1066
1067 const long a = PyInt_AS_LONG(*operand1);
1068 const long b = PyInt_AS_LONG(operand2);
1069
1070 if (unlikely(b < 0)) {
1071 PyThreadState *tstate = PyThreadState_GET();
1072
1073 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
1074 goto exit_result_exception;
1075 }
1076 /* Short cut for zero shift or shifting zero. */
1077 if (a == 0 || b == 0) {
1078 goto exit_result_ok_left;
1079 } else if (b >= LONG_BIT) {
1080 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
1081 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
1082
1083 // TODO: Change this to using CLONG once we specialize that too.
1084 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
1085
1086 Py_DECREF(operand1_long);
1087 Py_DECREF(operand2_long);
1088
1089 obj_result = r;
1090 goto exit_result_object;
1091 } else {
1092 long c = a << b;
1093
1094 if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
1095 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
1096 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
1097
1098 // TODO: Change this to using CLONG once we specialize that too.
1099 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
1100
1101 Py_DECREF(operand1_long);
1102 Py_DECREF(operand2_long);
1103
1104 obj_result = r;
1105 goto exit_result_object;
1106 } else {
1107 clong_result = c;
1108 goto exit_result_ok_clong;
1109 }
1110 }
1111
1112 exit_result_ok_clong:
1113
1114 // We got an object handed, that we have to release.
1115 Py_DECREF(*operand1);
1116
1117 // That's our return value then. As we use a dedicated variable, it's
1118 // OK that way.
1119 *operand1 = Nuitka_PyInt_FromLong(clong_result);
1120 goto exit_result_ok;
1121
1122 exit_result_ok_left:
1123 goto exit_result_ok;
1124
1125 exit_result_object:
1126 if (unlikely(obj_result == NULL)) {
1127 goto exit_result_exception;
1128 }
1129 // We got an object handed, that we have to release.
1130 Py_DECREF(*operand1);
1131
1132 *operand1 = obj_result;
1133 goto exit_result_ok;
1134
1135 exit_result_ok:
1136 return true;
1137
1138 exit_result_exception:
1139 return false;
1140 }
1141
1142 return __INPLACE_OPERATION_LSHIFT_INT_OBJECT(operand1, operand2);
1143}
1144
1145bool INPLACE_OPERATION_LSHIFT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
1146 return _INPLACE_OPERATION_LSHIFT_INT_OBJECT(operand1, operand2);
1147}
1148#endif
1149
1150#if PYTHON_VERSION < 0x300
1151/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
1152static inline bool _INPLACE_OPERATION_LSHIFT_LONG_INT(PyObject **operand1, PyObject *operand2) {
1153 assert(operand1); // Pointer must be non-null.
1154
1155 CHECK_OBJECT(*operand1);
1156 assert(PyLong_CheckExact(*operand1));
1157 CHECK_OBJECT(operand2);
1158 assert(PyInt_CheckExact(operand2));
1159
1160#if defined(_MSC_VER)
1161#pragma warning(push)
1162#pragma warning(disable : 4101)
1163#endif
1164 NUITKA_MAY_BE_UNUSED bool cbool_result;
1165 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1166#if defined(_MSC_VER)
1167#pragma warning(pop)
1168#endif
1169
1170 // No inplace number slot nb_inplace_lshift available for this type.
1171
1172 {
1173 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_lshift;
1174 // Slot2 ignored on purpose, type1 takes precedence.
1175
1176 if (slot1 != NULL) {
1177 PyObject *x = slot1(*operand1, operand2);
1178
1179 if (x != Py_NotImplemented) {
1180 obj_result = x;
1181 goto exit_inplace_result_object;
1182 }
1183
1184 Py_DECREF_IMMORTAL(x);
1185 }
1186
1187 // Statically recognized that coercion is not possible with these types
1188
1189 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for <<=: 'long' and 'int'");
1190 goto exit_inplace_exception;
1191 }
1192
1193exit_inplace_result_object:
1194 if (unlikely(obj_result == NULL)) {
1195 return false;
1196 }
1197
1198 // We got an object handed, that we have to release.
1199 Py_DECREF(*operand1);
1200
1201 // That's our return value then. As we use a dedicated variable, it's
1202 // OK that way.
1203 *operand1 = obj_result;
1204
1205 return true;
1206
1207exit_inplace_exception:
1208 return false;
1209}
1210
1211bool INPLACE_OPERATION_LSHIFT_LONG_INT(PyObject **operand1, PyObject *operand2) {
1212 return _INPLACE_OPERATION_LSHIFT_LONG_INT(operand1, operand2);
1213}
1214#endif
1215
1216#if PYTHON_VERSION < 0x300
1217/* Code referring to "INT" corresponds to Python2 'int' and "LONG" to Python2 'long', Python3 'int'. */
1218static inline bool _INPLACE_OPERATION_LSHIFT_INT_LONG(PyObject **operand1, PyObject *operand2) {
1219 assert(operand1); // Pointer must be non-null.
1220
1221 CHECK_OBJECT(*operand1);
1222 assert(PyInt_CheckExact(*operand1));
1223 CHECK_OBJECT(operand2);
1224 assert(PyLong_CheckExact(operand2));
1225
1226#if defined(_MSC_VER)
1227#pragma warning(push)
1228#pragma warning(disable : 4101)
1229#endif
1230 NUITKA_MAY_BE_UNUSED bool cbool_result;
1231 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1232#if defined(_MSC_VER)
1233#pragma warning(pop)
1234#endif
1235
1236 // No inplace number slot nb_inplace_lshift available for this type.
1237
1238 {
1239 // Slot1 ignored on purpose, type2 takes precedence.
1240 binaryfunc slot2 = NULL;
1241
1242 if (!(0)) {
1243 // Different types, need to consider second value slot.
1244
1245 slot2 = PyLong_Type.tp_as_number->nb_lshift;
1246 }
1247
1248 if (slot2 != NULL) {
1249 PyObject *x = slot2(*operand1, operand2);
1250
1251 if (x != Py_NotImplemented) {
1252 obj_result = x;
1253 goto exit_inplace_result_object;
1254 }
1255
1256 Py_DECREF_IMMORTAL(x);
1257 }
1258
1259 // Statically recognized that coercion is not possible with these types
1260
1261 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for <<=: 'int' and 'long'");
1262 goto exit_inplace_exception;
1263 }
1264
1265exit_inplace_result_object:
1266 if (unlikely(obj_result == NULL)) {
1267 return false;
1268 }
1269
1270 // We got an object handed, that we have to release.
1271 Py_DECREF(*operand1);
1272
1273 // That's our return value then. As we use a dedicated variable, it's
1274 // OK that way.
1275 *operand1 = obj_result;
1276
1277 return true;
1278
1279exit_inplace_exception:
1280 return false;
1281}
1282
1283bool INPLACE_OPERATION_LSHIFT_INT_LONG(PyObject **operand1, PyObject *operand2) {
1284 return _INPLACE_OPERATION_LSHIFT_INT_LONG(operand1, operand2);
1285}
1286#endif
1287
1288/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
1289static inline bool _INPLACE_OPERATION_LSHIFT_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
1290 assert(operand1); // Pointer must be non-null.
1291
1292 CHECK_OBJECT(*operand1);
1293 CHECK_OBJECT(operand2);
1294
1295#if PYTHON_VERSION < 0x300
1296 if (PyInt_CheckExact(*operand1) && PyInt_CheckExact(operand2)) {
1297
1298 // Not every code path will make use of all possible results.
1299#if defined(_MSC_VER)
1300#pragma warning(push)
1301#pragma warning(disable : 4101)
1302#endif
1303 NUITKA_MAY_BE_UNUSED bool cbool_result;
1304 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1305 NUITKA_MAY_BE_UNUSED long clong_result;
1306 NUITKA_MAY_BE_UNUSED double cfloat_result;
1307#if defined(_MSC_VER)
1308#pragma warning(pop)
1309#endif
1310
1311 CHECK_OBJECT(*operand1);
1312 assert(PyInt_CheckExact(*operand1));
1313 CHECK_OBJECT(operand2);
1314 assert(PyInt_CheckExact(operand2));
1315
1316 const long a = PyInt_AS_LONG(*operand1);
1317 const long b = PyInt_AS_LONG(operand2);
1318
1319 if (unlikely(b < 0)) {
1320 PyThreadState *tstate = PyThreadState_GET();
1321
1322 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "negative shift count");
1323 goto exit_result_exception;
1324 }
1325 /* Short cut for zero shift or shifting zero. */
1326 if (a == 0 || b == 0) {
1327 goto exit_result_ok_left;
1328 } else if (b >= LONG_BIT) {
1329 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
1330 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
1331
1332 // TODO: Change this to using CLONG once we specialize that too.
1333 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
1334
1335 Py_DECREF(operand1_long);
1336 Py_DECREF(operand2_long);
1337
1338 obj_result = r;
1339 goto exit_result_object;
1340 } else {
1341 long c = a << b;
1342
1343 if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
1344 PyObject *operand1_long = Nuitka_PyLong_FromLong(a);
1345 PyObject *operand2_long = Nuitka_PyLong_FromLong(b);
1346
1347 // TODO: Change this to using CLONG once we specialize that too.
1348 PyObject *r = _BINARY_OPERATION_LSHIFT_OBJECT_LONG_LONG(operand1_long, operand2_long);
1349
1350 Py_DECREF(operand1_long);
1351 Py_DECREF(operand2_long);
1352
1353 obj_result = r;
1354 goto exit_result_object;
1355 } else {
1356 clong_result = c;
1357 goto exit_result_ok_clong;
1358 }
1359 }
1360
1361 exit_result_ok_clong:
1362
1363 // We got an object handed, that we have to release.
1364 Py_DECREF(*operand1);
1365
1366 // That's our return value then. As we use a dedicated variable, it's
1367 // OK that way.
1368 *operand1 = Nuitka_PyInt_FromLong(clong_result);
1369 goto exit_result_ok;
1370
1371 exit_result_ok_left:
1372 goto exit_result_ok;
1373
1374 exit_result_object:
1375 if (unlikely(obj_result == NULL)) {
1376 goto exit_result_exception;
1377 }
1378 // We got an object handed, that we have to release.
1379 Py_DECREF(*operand1);
1380
1381 *operand1 = obj_result;
1382 goto exit_result_ok;
1383
1384 exit_result_ok:
1385 return true;
1386
1387 exit_result_exception:
1388 return false;
1389 }
1390#endif
1391
1392 if (Py_TYPE(*operand1) == Py_TYPE(operand2)) {
1393#if PYTHON_VERSION >= 0x300
1394 if (PyLong_CheckExact(operand2)) {
1395 return _INPLACE_OPERATION_LSHIFT_LONG_LONG(operand1, operand2);
1396 }
1397#endif
1398 }
1399
1400 PyTypeObject *type1 = Py_TYPE(*operand1);
1401 PyTypeObject *type2 = Py_TYPE(operand2);
1402
1403#if defined(_MSC_VER)
1404#pragma warning(push)
1405#pragma warning(disable : 4101)
1406#endif
1407 NUITKA_MAY_BE_UNUSED bool cbool_result;
1408 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1409#if defined(_MSC_VER)
1410#pragma warning(pop)
1411#endif
1412
1413 binaryfunc islot =
1414 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_lshift : NULL;
1415
1416 if (islot != NULL) {
1417 PyObject *x = islot(*operand1, operand2);
1418
1419 if (x != Py_NotImplemented) {
1420 obj_result = x;
1421 goto exit_inplace_result_object;
1422 }
1423
1424 Py_DECREF_IMMORTAL(x);
1425 }
1426
1427 {
1428 binaryfunc slot1 =
1429 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_lshift : NULL;
1430 binaryfunc slot2 = NULL;
1431
1432 if (!(type1 == type2)) {
1433 // Different types, need to consider second value slot.
1434
1435 slot2 =
1436 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_lshift : NULL;
1437
1438 if (slot1 == slot2) {
1439 slot2 = NULL;
1440 }
1441 }
1442
1443 if (slot1 != NULL) {
1444 if (slot2 != NULL) {
1445 if (Nuitka_Type_IsSubtype(type2, type1)) {
1446 PyObject *x = slot2(*operand1, operand2);
1447
1448 if (x != Py_NotImplemented) {
1449 obj_result = x;
1450 goto exit_inplace_result_object;
1451 }
1452
1453 Py_DECREF_IMMORTAL(x);
1454 slot2 = NULL;
1455 }
1456 }
1457
1458 PyObject *x = slot1(*operand1, operand2);
1459
1460 if (x != Py_NotImplemented) {
1461 obj_result = x;
1462 goto exit_inplace_result_object;
1463 }
1464
1465 Py_DECREF_IMMORTAL(x);
1466 }
1467
1468 if (slot2 != NULL) {
1469 PyObject *x = slot2(*operand1, operand2);
1470
1471 if (x != Py_NotImplemented) {
1472 obj_result = x;
1473 goto exit_inplace_result_object;
1474 }
1475
1476 Py_DECREF_IMMORTAL(x);
1477 }
1478
1479#if PYTHON_VERSION < 0x300
1480 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
1481 coercion c1 =
1482 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1483
1484 if (c1 != NULL) {
1485 PyObject *coerced1 = *operand1;
1486 PyObject *coerced2 = operand2;
1487
1488 int err = c1(&coerced1, &coerced2);
1489
1490 if (unlikely(err < 0)) {
1491 goto exit_inplace_exception;
1492 }
1493
1494 if (err == 0) {
1495 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1496
1497 if (likely(mv == NULL)) {
1498 binaryfunc slot = mv->nb_lshift;
1499
1500 if (likely(slot != NULL)) {
1501 PyObject *x = slot(coerced1, coerced2);
1502
1503 Py_DECREF(coerced1);
1504 Py_DECREF(coerced2);
1505
1506 obj_result = x;
1507 goto exit_inplace_result_object;
1508 }
1509 }
1510
1511 // nb_coerce took a reference.
1512 Py_DECREF(coerced1);
1513 Py_DECREF(coerced2);
1514 }
1515 }
1516 coercion c2 =
1517 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1518
1519 if (c2 != NULL) {
1520 PyObject *coerced1 = *operand1;
1521 PyObject *coerced2 = operand2;
1522
1523 int err = c2(&coerced2, &coerced1);
1524
1525 if (unlikely(err < 0)) {
1526 goto exit_inplace_exception;
1527 }
1528
1529 if (err == 0) {
1530 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1531
1532 if (likely(mv == NULL)) {
1533 binaryfunc slot = mv->nb_lshift;
1534
1535 if (likely(slot != NULL)) {
1536 PyObject *x = slot(coerced1, coerced2);
1537
1538 Py_DECREF(coerced1);
1539 Py_DECREF(coerced2);
1540
1541 obj_result = x;
1542 goto exit_inplace_result_object;
1543 }
1544 }
1545
1546 // nb_coerce took a reference.
1547 Py_DECREF(coerced1);
1548 Py_DECREF(coerced2);
1549 }
1550 }
1551 }
1552#endif
1553
1554 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for <<=: '%s' and '%s'", type1->tp_name,
1555 type2->tp_name);
1556 goto exit_inplace_exception;
1557 }
1558
1559exit_inplace_result_object:
1560 if (unlikely(obj_result == NULL)) {
1561 return false;
1562 }
1563
1564 // We got an object handed, that we have to release.
1565 Py_DECREF(*operand1);
1566
1567 // That's our return value then. As we use a dedicated variable, it's
1568 // OK that way.
1569 *operand1 = obj_result;
1570
1571 return true;
1572
1573exit_inplace_exception:
1574 return false;
1575}
1576
1577bool INPLACE_OPERATION_LSHIFT_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
1578 return _INPLACE_OPERATION_LSHIFT_OBJECT_OBJECT(operand1, operand2);
1579}
1580
1581// Part of "Nuitka", an optimizing Python compiler that is compatible and
1582// integrates with CPython, but also works on its own.
1583//
1584// Licensed under the Apache License, Version 2.0 (the "License");
1585// you may not use this file except in compliance with the License.
1586// You may obtain a copy of the License at
1587//
1588// http://www.apache.org/licenses/LICENSE-2.0
1589//
1590// Unless required by applicable law or agreed to in writing, software
1591// distributed under the License is distributed on an "AS IS" BASIS,
1592// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1593// See the License for the specific language governing permissions and
1594// limitations under the License.