Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationInplaceBitand.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 "&" (BITAND) 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_BITAND_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_and(*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_BITAND_LONG_LONG(PyObject **operand1, PyObject *operand2) {
55 return _INPLACE_OPERATION_BITAND_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_BITAND_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_and : 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_and : 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_and;
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_and;
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_and;
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_BITAND_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_BITAND_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_and(*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_BITAND_OBJECT_LONG(operand1, operand2);
268}
269
270bool INPLACE_OPERATION_BITAND_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
271 return _INPLACE_OPERATION_BITAND_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_BITAND_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_and available for this type.
289
290 {
291 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_and;
292 binaryfunc slot2 = NULL;
293
294 if (!(&PyLong_Type == type2)) {
295 // Different types, need to consider second value slot.
296
297 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_and : NULL;
298
299 if (slot1 == slot2) {
300 slot2 = NULL;
301 }
302 }
303
304 if (slot1 != NULL) {
305 if (slot2 != NULL) {
306 if (Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
307 PyObject *x = slot2(*operand1, operand2);
308
309 if (x != Py_NotImplemented) {
310 obj_result = x;
311 goto exit_inplace_result_object;
312 }
313
314 Py_DECREF_IMMORTAL(x);
315 slot2 = NULL;
316 }
317 }
318
319 PyObject *x = slot1(*operand1, operand2);
320
321 if (x != Py_NotImplemented) {
322 obj_result = x;
323 goto exit_inplace_result_object;
324 }
325
326 Py_DECREF_IMMORTAL(x);
327 }
328
329 if (slot2 != NULL) {
330 PyObject *x = slot2(*operand1, operand2);
331
332 if (x != Py_NotImplemented) {
333 obj_result = x;
334 goto exit_inplace_result_object;
335 }
336
337 Py_DECREF_IMMORTAL(x);
338 }
339
340#if PYTHON_VERSION < 0x300
341 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
342 coercion c1 = PyLong_Type.tp_as_number->nb_coerce;
343
344 if (c1 != NULL) {
345 PyObject *coerced1 = *operand1;
346 PyObject *coerced2 = operand2;
347
348 int err = c1(&coerced1, &coerced2);
349
350 if (unlikely(err < 0)) {
351 goto exit_inplace_exception;
352 }
353
354 if (err == 0) {
355 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
356
357 if (likely(mv == NULL)) {
358 binaryfunc slot = mv->nb_and;
359
360 if (likely(slot != NULL)) {
361 PyObject *x = slot(coerced1, coerced2);
362
363 Py_DECREF(coerced1);
364 Py_DECREF(coerced2);
365
366 obj_result = x;
367 goto exit_inplace_result_object;
368 }
369 }
370
371 // nb_coerce took a reference.
372 Py_DECREF(coerced1);
373 Py_DECREF(coerced2);
374 }
375 }
376 coercion c2 =
377 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
378
379 if (c2 != NULL) {
380 PyObject *coerced1 = *operand1;
381 PyObject *coerced2 = operand2;
382
383 int err = c2(&coerced2, &coerced1);
384
385 if (unlikely(err < 0)) {
386 goto exit_inplace_exception;
387 }
388
389 if (err == 0) {
390 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
391
392 if (likely(mv == NULL)) {
393 binaryfunc slot = mv->nb_and;
394
395 if (likely(slot != NULL)) {
396 PyObject *x = slot(coerced1, coerced2);
397
398 Py_DECREF(coerced1);
399 Py_DECREF(coerced2);
400
401 obj_result = x;
402 goto exit_inplace_result_object;
403 }
404 }
405
406 // nb_coerce took a reference.
407 Py_DECREF(coerced1);
408 Py_DECREF(coerced2);
409 }
410 }
411 }
412#endif
413
414#if PYTHON_VERSION < 0x300
415 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: 'long' and '%s'", type2->tp_name);
416#else
417 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: 'int' and '%s'", type2->tp_name);
418#endif
419 goto exit_inplace_exception;
420 }
421
422exit_inplace_result_object:
423 if (unlikely(obj_result == NULL)) {
424 return false;
425 }
426
427 // We got an object handed, that we have to release.
428 Py_DECREF(*operand1);
429
430 // That's our return value then. As we use a dedicated variable, it's
431 // OK that way.
432 *operand1 = obj_result;
433
434 return true;
435
436exit_inplace_exception:
437 return false;
438}
439static inline bool _INPLACE_OPERATION_BITAND_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
440 assert(operand1); // Pointer must be non-null.
441
442 CHECK_OBJECT(*operand1);
443 assert(PyLong_CheckExact(*operand1));
444 CHECK_OBJECT(operand2);
445
446 PyTypeObject *type2 = Py_TYPE(operand2);
447
448 if (&PyLong_Type == type2) {
449 // return _BINARY_OPERATION_BITAND_LONG_LONG_INPLACE(operand1, operand2);
450
451 // Not every code path will make use of all possible results.
452#if defined(_MSC_VER)
453#pragma warning(push)
454#pragma warning(disable : 4101)
455#endif
456 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
457 NUITKA_MAY_BE_UNUSED long clong_result;
458#if defined(_MSC_VER)
459#pragma warning(pop)
460#endif
461
462 PyObject *x = PyLong_Type.tp_as_number->nb_and(*operand1, operand2);
463 assert(x != Py_NotImplemented);
464
465 obj_result = x;
466 goto exit_result_object;
467
468 exit_result_object:
469 if (unlikely(obj_result == NULL)) {
470 goto exit_result_exception;
471 }
472 // We got an object handed, that we have to release.
473 Py_DECREF(*operand1);
474 *operand1 = obj_result;
475 goto exit_result_ok;
476
477 exit_result_ok:
478 return true;
479
480 exit_result_exception:
481 return false;
482 }
483
484 return __INPLACE_OPERATION_BITAND_LONG_OBJECT(operand1, operand2);
485}
486
487bool INPLACE_OPERATION_BITAND_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
488 return _INPLACE_OPERATION_BITAND_LONG_OBJECT(operand1, operand2);
489}
490
491#if PYTHON_VERSION < 0x300
492/* Code referring to "INT" corresponds to Python2 'int' and "INT" to Python2 'int'. */
493static inline bool _INPLACE_OPERATION_BITAND_INT_INT(PyObject **operand1, PyObject *operand2) {
494 assert(operand1); // Pointer must be non-null.
495
496 CHECK_OBJECT(*operand1);
497 assert(PyInt_CheckExact(*operand1));
498 CHECK_OBJECT(operand2);
499 assert(PyInt_CheckExact(operand2));
500
501 // Not every code path will make use of all possible results.
502#if defined(_MSC_VER)
503#pragma warning(push)
504#pragma warning(disable : 4101)
505#endif
506 NUITKA_MAY_BE_UNUSED bool cbool_result;
507 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
508 NUITKA_MAY_BE_UNUSED long clong_result;
509 NUITKA_MAY_BE_UNUSED double cfloat_result;
510#if defined(_MSC_VER)
511#pragma warning(pop)
512#endif
513
514 CHECK_OBJECT(*operand1);
515 assert(PyInt_CheckExact(*operand1));
516 CHECK_OBJECT(operand2);
517 assert(PyInt_CheckExact(operand2));
518
519 const long a = PyInt_AS_LONG(*operand1);
520 const long b = PyInt_AS_LONG(operand2);
521
522 const long r = a & b;
523
524 clong_result = r;
525 goto exit_result_ok_clong;
526
527exit_result_ok_clong:
528
529 // We got an object handed, that we have to release.
530 Py_DECREF(*operand1);
531
532 // That's our return value then. As we use a dedicated variable, it's
533 // OK that way.
534 *operand1 = Nuitka_PyInt_FromLong(clong_result);
535 goto exit_result_ok;
536
537exit_result_ok:
538 return true;
539}
540
541bool INPLACE_OPERATION_BITAND_INT_INT(PyObject **operand1, PyObject *operand2) {
542 return _INPLACE_OPERATION_BITAND_INT_INT(operand1, operand2);
543}
544#endif
545
546#if PYTHON_VERSION < 0x300
547/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
548static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_BITAND_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
549 PyTypeObject *type1 = Py_TYPE(*operand1);
550
551#if defined(_MSC_VER)
552#pragma warning(push)
553#pragma warning(disable : 4101)
554#endif
555 NUITKA_MAY_BE_UNUSED bool cbool_result;
556 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
557#if defined(_MSC_VER)
558#pragma warning(pop)
559#endif
560
561 binaryfunc islot =
562 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_and : NULL;
563
564 if (islot != NULL) {
565 PyObject *x = islot(*operand1, operand2);
566
567 if (x != Py_NotImplemented) {
568 obj_result = x;
569 goto exit_inplace_result_object;
570 }
571
572 Py_DECREF_IMMORTAL(x);
573 }
574
575 {
576 binaryfunc slot1 =
577 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_and : NULL;
578 binaryfunc slot2 = NULL;
579
580 if (!(type1 == &PyInt_Type)) {
581 // Different types, need to consider second value slot.
582
583 slot2 = PyInt_Type.tp_as_number->nb_and;
584
585 if (slot1 == slot2) {
586 slot2 = NULL;
587 }
588 }
589
590 if (slot1 != NULL) {
591 PyObject *x = slot1(*operand1, operand2);
592
593 if (x != Py_NotImplemented) {
594 obj_result = x;
595 goto exit_inplace_result_object;
596 }
597
598 Py_DECREF_IMMORTAL(x);
599 }
600
601 if (slot2 != NULL) {
602 PyObject *x = slot2(*operand1, operand2);
603
604 if (x != Py_NotImplemented) {
605 obj_result = x;
606 goto exit_inplace_result_object;
607 }
608
609 Py_DECREF_IMMORTAL(x);
610 }
611
612#if PYTHON_VERSION < 0x300
613 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
614 coercion c1 =
615 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
616
617 if (c1 != NULL) {
618 PyObject *coerced1 = *operand1;
619 PyObject *coerced2 = operand2;
620
621 int err = c1(&coerced1, &coerced2);
622
623 if (unlikely(err < 0)) {
624 goto exit_inplace_exception;
625 }
626
627 if (err == 0) {
628 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
629
630 if (likely(mv == NULL)) {
631 binaryfunc slot = mv->nb_and;
632
633 if (likely(slot != NULL)) {
634 PyObject *x = slot(coerced1, coerced2);
635
636 Py_DECREF(coerced1);
637 Py_DECREF(coerced2);
638
639 obj_result = x;
640 goto exit_inplace_result_object;
641 }
642 }
643
644 // nb_coerce took a reference.
645 Py_DECREF(coerced1);
646 Py_DECREF(coerced2);
647 }
648 }
649 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
650
651 if (c2 != NULL) {
652 PyObject *coerced1 = *operand1;
653 PyObject *coerced2 = operand2;
654
655 int err = c2(&coerced2, &coerced1);
656
657 if (unlikely(err < 0)) {
658 goto exit_inplace_exception;
659 }
660
661 if (err == 0) {
662 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
663
664 if (likely(mv == NULL)) {
665 binaryfunc slot = mv->nb_and;
666
667 if (likely(slot != NULL)) {
668 PyObject *x = slot(coerced1, coerced2);
669
670 Py_DECREF(coerced1);
671 Py_DECREF(coerced2);
672
673 obj_result = x;
674 goto exit_inplace_result_object;
675 }
676 }
677
678 // nb_coerce took a reference.
679 Py_DECREF(coerced1);
680 Py_DECREF(coerced2);
681 }
682 }
683 }
684#endif
685
686 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: '%s' and 'int'", type1->tp_name);
687 goto exit_inplace_exception;
688 }
689
690exit_inplace_result_object:
691 if (unlikely(obj_result == NULL)) {
692 return false;
693 }
694
695 // We got an object handed, that we have to release.
696 Py_DECREF(*operand1);
697
698 // That's our return value then. As we use a dedicated variable, it's
699 // OK that way.
700 *operand1 = obj_result;
701
702 return true;
703
704exit_inplace_exception:
705 return false;
706}
707static inline bool _INPLACE_OPERATION_BITAND_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
708 assert(operand1); // Pointer must be non-null.
709
710 CHECK_OBJECT(*operand1);
711 CHECK_OBJECT(operand2);
712 assert(PyInt_CheckExact(operand2));
713
714 PyTypeObject *type1 = Py_TYPE(*operand1);
715
716 if (type1 == &PyInt_Type) {
717 // return _BINARY_OPERATION_BITAND_INT_INT_INPLACE(operand1, operand2);
718
719 // Not every code path will make use of all possible results.
720#if defined(_MSC_VER)
721#pragma warning(push)
722#pragma warning(disable : 4101)
723#endif
724 NUITKA_MAY_BE_UNUSED bool cbool_result;
725 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
726 NUITKA_MAY_BE_UNUSED long clong_result;
727 NUITKA_MAY_BE_UNUSED double cfloat_result;
728#if defined(_MSC_VER)
729#pragma warning(pop)
730#endif
731
732 CHECK_OBJECT(*operand1);
733 assert(PyInt_CheckExact(*operand1));
734 CHECK_OBJECT(operand2);
735 assert(PyInt_CheckExact(operand2));
736
737 const long a = PyInt_AS_LONG(*operand1);
738 const long b = PyInt_AS_LONG(operand2);
739
740 const long r = a & b;
741
742 clong_result = r;
743 goto exit_result_ok_clong;
744
745 exit_result_ok_clong:
746
747 // We got an object handed, that we have to release.
748 Py_DECREF(*operand1);
749
750 // That's our return value then. As we use a dedicated variable, it's
751 // OK that way.
752 *operand1 = Nuitka_PyInt_FromLong(clong_result);
753 goto exit_result_ok;
754
755 exit_result_ok:
756 return true;
757 }
758
759 return __INPLACE_OPERATION_BITAND_OBJECT_INT(operand1, operand2);
760}
761
762bool INPLACE_OPERATION_BITAND_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
763 return _INPLACE_OPERATION_BITAND_OBJECT_INT(operand1, operand2);
764}
765#endif
766
767#if PYTHON_VERSION < 0x300
768/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
769static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_BITAND_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
770 PyTypeObject *type2 = Py_TYPE(operand2);
771
772#if defined(_MSC_VER)
773#pragma warning(push)
774#pragma warning(disable : 4101)
775#endif
776 NUITKA_MAY_BE_UNUSED bool cbool_result;
777 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
778#if defined(_MSC_VER)
779#pragma warning(pop)
780#endif
781
782 // No inplace number slot nb_inplace_and available for this type.
783
784 {
785 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_and;
786 binaryfunc slot2 = NULL;
787
788 if (!(&PyInt_Type == type2)) {
789 // Different types, need to consider second value slot.
790
791 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_and : NULL;
792
793 if (slot1 == slot2) {
794 slot2 = NULL;
795 }
796 }
797
798 if (slot1 != NULL) {
799 if (slot2 != NULL) {
800 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
801 PyObject *x = slot2(*operand1, operand2);
802
803 if (x != Py_NotImplemented) {
804 obj_result = x;
805 goto exit_inplace_result_object;
806 }
807
808 Py_DECREF_IMMORTAL(x);
809 slot2 = NULL;
810 }
811 }
812
813 PyObject *x = slot1(*operand1, operand2);
814
815 if (x != Py_NotImplemented) {
816 obj_result = x;
817 goto exit_inplace_result_object;
818 }
819
820 Py_DECREF_IMMORTAL(x);
821 }
822
823 if (slot2 != NULL) {
824 PyObject *x = slot2(*operand1, operand2);
825
826 if (x != Py_NotImplemented) {
827 obj_result = x;
828 goto exit_inplace_result_object;
829 }
830
831 Py_DECREF_IMMORTAL(x);
832 }
833
834#if PYTHON_VERSION < 0x300
835 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
836 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
837
838 if (c1 != NULL) {
839 PyObject *coerced1 = *operand1;
840 PyObject *coerced2 = operand2;
841
842 int err = c1(&coerced1, &coerced2);
843
844 if (unlikely(err < 0)) {
845 goto exit_inplace_exception;
846 }
847
848 if (err == 0) {
849 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
850
851 if (likely(mv == NULL)) {
852 binaryfunc slot = mv->nb_and;
853
854 if (likely(slot != NULL)) {
855 PyObject *x = slot(coerced1, coerced2);
856
857 Py_DECREF(coerced1);
858 Py_DECREF(coerced2);
859
860 obj_result = x;
861 goto exit_inplace_result_object;
862 }
863 }
864
865 // nb_coerce took a reference.
866 Py_DECREF(coerced1);
867 Py_DECREF(coerced2);
868 }
869 }
870 coercion c2 =
871 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
872
873 if (c2 != NULL) {
874 PyObject *coerced1 = *operand1;
875 PyObject *coerced2 = operand2;
876
877 int err = c2(&coerced2, &coerced1);
878
879 if (unlikely(err < 0)) {
880 goto exit_inplace_exception;
881 }
882
883 if (err == 0) {
884 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
885
886 if (likely(mv == NULL)) {
887 binaryfunc slot = mv->nb_and;
888
889 if (likely(slot != NULL)) {
890 PyObject *x = slot(coerced1, coerced2);
891
892 Py_DECREF(coerced1);
893 Py_DECREF(coerced2);
894
895 obj_result = x;
896 goto exit_inplace_result_object;
897 }
898 }
899
900 // nb_coerce took a reference.
901 Py_DECREF(coerced1);
902 Py_DECREF(coerced2);
903 }
904 }
905 }
906#endif
907
908 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: 'int' and '%s'", type2->tp_name);
909 goto exit_inplace_exception;
910 }
911
912exit_inplace_result_object:
913 if (unlikely(obj_result == NULL)) {
914 return false;
915 }
916
917 // We got an object handed, that we have to release.
918 Py_DECREF(*operand1);
919
920 // That's our return value then. As we use a dedicated variable, it's
921 // OK that way.
922 *operand1 = obj_result;
923
924 return true;
925
926exit_inplace_exception:
927 return false;
928}
929static inline bool _INPLACE_OPERATION_BITAND_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
930 assert(operand1); // Pointer must be non-null.
931
932 CHECK_OBJECT(*operand1);
933 assert(PyInt_CheckExact(*operand1));
934 CHECK_OBJECT(operand2);
935
936 PyTypeObject *type2 = Py_TYPE(operand2);
937
938 if (&PyInt_Type == type2) {
939 // return _BINARY_OPERATION_BITAND_INT_INT_INPLACE(operand1, operand2);
940
941 // Not every code path will make use of all possible results.
942#if defined(_MSC_VER)
943#pragma warning(push)
944#pragma warning(disable : 4101)
945#endif
946 NUITKA_MAY_BE_UNUSED bool cbool_result;
947 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
948 NUITKA_MAY_BE_UNUSED long clong_result;
949 NUITKA_MAY_BE_UNUSED double cfloat_result;
950#if defined(_MSC_VER)
951#pragma warning(pop)
952#endif
953
954 CHECK_OBJECT(*operand1);
955 assert(PyInt_CheckExact(*operand1));
956 CHECK_OBJECT(operand2);
957 assert(PyInt_CheckExact(operand2));
958
959 const long a = PyInt_AS_LONG(*operand1);
960 const long b = PyInt_AS_LONG(operand2);
961
962 const long r = a & b;
963
964 clong_result = r;
965 goto exit_result_ok_clong;
966
967 exit_result_ok_clong:
968
969 // We got an object handed, that we have to release.
970 Py_DECREF(*operand1);
971
972 // That's our return value then. As we use a dedicated variable, it's
973 // OK that way.
974 *operand1 = Nuitka_PyInt_FromLong(clong_result);
975 goto exit_result_ok;
976
977 exit_result_ok:
978 return true;
979 }
980
981 return __INPLACE_OPERATION_BITAND_INT_OBJECT(operand1, operand2);
982}
983
984bool INPLACE_OPERATION_BITAND_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
985 return _INPLACE_OPERATION_BITAND_INT_OBJECT(operand1, operand2);
986}
987#endif
988
989#if PYTHON_VERSION < 0x300
990/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
991static inline bool _INPLACE_OPERATION_BITAND_INT_CLONG(PyObject **operand1, long operand2) {
992 assert(operand1); // Pointer must be non-null.
993
994 CHECK_OBJECT(*operand1);
995 assert(PyInt_CheckExact(*operand1));
996
997 // Not every code path will make use of all possible results.
998#if defined(_MSC_VER)
999#pragma warning(push)
1000#pragma warning(disable : 4101)
1001#endif
1002 NUITKA_MAY_BE_UNUSED bool cbool_result;
1003 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1004 NUITKA_MAY_BE_UNUSED long clong_result;
1005 NUITKA_MAY_BE_UNUSED double cfloat_result;
1006#if defined(_MSC_VER)
1007#pragma warning(pop)
1008#endif
1009
1010 CHECK_OBJECT(*operand1);
1011 assert(PyInt_CheckExact(*operand1));
1012
1013 const long a = PyInt_AS_LONG(*operand1);
1014 const long b = operand2;
1015
1016 const long r = a & b;
1017
1018 clong_result = r;
1019 goto exit_result_ok_clong;
1020
1021exit_result_ok_clong:
1022
1023 // We got an object handed, that we have to release.
1024 Py_DECREF(*operand1);
1025
1026 // That's our return value then. As we use a dedicated variable, it's
1027 // OK that way.
1028 *operand1 = Nuitka_PyInt_FromLong(clong_result);
1029 goto exit_result_ok;
1030
1031exit_result_ok:
1032 return true;
1033}
1034
1035bool INPLACE_OPERATION_BITAND_INT_CLONG(PyObject **operand1, long operand2) {
1036 return _INPLACE_OPERATION_BITAND_INT_CLONG(operand1, operand2);
1037}
1038#endif
1039
1040#if PYTHON_VERSION < 0x300
1041/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
1042static inline bool _INPLACE_OPERATION_BITAND_LONG_INT(PyObject **operand1, PyObject *operand2) {
1043 assert(operand1); // Pointer must be non-null.
1044
1045 CHECK_OBJECT(*operand1);
1046 assert(PyLong_CheckExact(*operand1));
1047 CHECK_OBJECT(operand2);
1048 assert(PyInt_CheckExact(operand2));
1049
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#if defined(_MSC_VER)
1057#pragma warning(pop)
1058#endif
1059
1060 // No inplace number slot nb_inplace_and available for this type.
1061
1062 {
1063 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_and;
1064 // Slot2 ignored on purpose, type1 takes precedence.
1065
1066 if (slot1 != NULL) {
1067 PyObject *x = slot1(*operand1, operand2);
1068
1069 if (x != Py_NotImplemented) {
1070 obj_result = x;
1071 goto exit_inplace_result_object;
1072 }
1073
1074 Py_DECREF_IMMORTAL(x);
1075 }
1076
1077 // Statically recognized that coercion is not possible with these types
1078
1079 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: 'long' and 'int'");
1080 goto exit_inplace_exception;
1081 }
1082
1083exit_inplace_result_object:
1084 if (unlikely(obj_result == NULL)) {
1085 return false;
1086 }
1087
1088 // We got an object handed, that we have to release.
1089 Py_DECREF(*operand1);
1090
1091 // That's our return value then. As we use a dedicated variable, it's
1092 // OK that way.
1093 *operand1 = obj_result;
1094
1095 return true;
1096
1097exit_inplace_exception:
1098 return false;
1099}
1100
1101bool INPLACE_OPERATION_BITAND_LONG_INT(PyObject **operand1, PyObject *operand2) {
1102 return _INPLACE_OPERATION_BITAND_LONG_INT(operand1, operand2);
1103}
1104#endif
1105
1106#if PYTHON_VERSION < 0x300
1107/* Code referring to "INT" corresponds to Python2 'int' and "LONG" to Python2 'long', Python3 'int'. */
1108static inline bool _INPLACE_OPERATION_BITAND_INT_LONG(PyObject **operand1, PyObject *operand2) {
1109 assert(operand1); // Pointer must be non-null.
1110
1111 CHECK_OBJECT(*operand1);
1112 assert(PyInt_CheckExact(*operand1));
1113 CHECK_OBJECT(operand2);
1114 assert(PyLong_CheckExact(operand2));
1115
1116#if defined(_MSC_VER)
1117#pragma warning(push)
1118#pragma warning(disable : 4101)
1119#endif
1120 NUITKA_MAY_BE_UNUSED bool cbool_result;
1121 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1122#if defined(_MSC_VER)
1123#pragma warning(pop)
1124#endif
1125
1126 // No inplace number slot nb_inplace_and available for this type.
1127
1128 {
1129 // Slot1 ignored on purpose, type2 takes precedence.
1130 binaryfunc slot2 = NULL;
1131
1132 if (!(0)) {
1133 // Different types, need to consider second value slot.
1134
1135 slot2 = PyLong_Type.tp_as_number->nb_and;
1136 }
1137
1138 if (slot2 != NULL) {
1139 PyObject *x = slot2(*operand1, operand2);
1140
1141 if (x != Py_NotImplemented) {
1142 obj_result = x;
1143 goto exit_inplace_result_object;
1144 }
1145
1146 Py_DECREF_IMMORTAL(x);
1147 }
1148
1149 // Statically recognized that coercion is not possible with these types
1150
1151 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: 'int' and 'long'");
1152 goto exit_inplace_exception;
1153 }
1154
1155exit_inplace_result_object:
1156 if (unlikely(obj_result == NULL)) {
1157 return false;
1158 }
1159
1160 // We got an object handed, that we have to release.
1161 Py_DECREF(*operand1);
1162
1163 // That's our return value then. As we use a dedicated variable, it's
1164 // OK that way.
1165 *operand1 = obj_result;
1166
1167 return true;
1168
1169exit_inplace_exception:
1170 return false;
1171}
1172
1173bool INPLACE_OPERATION_BITAND_INT_LONG(PyObject **operand1, PyObject *operand2) {
1174 return _INPLACE_OPERATION_BITAND_INT_LONG(operand1, operand2);
1175}
1176#endif
1177
1178/* Code referring to "SET" corresponds to Python 'set' and "SET" to Python 'set'. */
1179static inline bool _INPLACE_OPERATION_BITAND_SET_SET(PyObject **operand1, PyObject *operand2) {
1180 assert(operand1); // Pointer must be non-null.
1181
1182 CHECK_OBJECT(*operand1);
1183 assert(PySet_CheckExact(*operand1));
1184 CHECK_OBJECT(operand2);
1185 assert(PySet_CheckExact(operand2));
1186
1187 // Not every code path will make use of all possible results.
1188 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1189
1190 PyObject *x = PySet_Type.tp_as_number->nb_inplace_and(*operand1, operand2);
1191
1192 assert(x != Py_NotImplemented);
1193
1194 obj_result = x;
1195 goto exit_result_object;
1196
1197exit_result_object:
1198 if (unlikely(obj_result == NULL)) {
1199 goto exit_result_exception;
1200 }
1201 // We got an object handed, that we have to release.
1202 Py_DECREF(*operand1);
1203
1204 *operand1 = obj_result;
1205 goto exit_result_ok;
1206
1207exit_result_ok:
1208 return true;
1209
1210exit_result_exception:
1211 return false;
1212}
1213
1214bool INPLACE_OPERATION_BITAND_SET_SET(PyObject **operand1, PyObject *operand2) {
1215 return _INPLACE_OPERATION_BITAND_SET_SET(operand1, operand2);
1216}
1217
1218/* Code referring to "OBJECT" corresponds to any Python object and "SET" to Python 'set'. */
1219static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_BITAND_OBJECT_SET(PyObject **operand1, PyObject *operand2) {
1220 PyTypeObject *type1 = Py_TYPE(*operand1);
1221
1222#if defined(_MSC_VER)
1223#pragma warning(push)
1224#pragma warning(disable : 4101)
1225#endif
1226 NUITKA_MAY_BE_UNUSED bool cbool_result;
1227 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1228#if defined(_MSC_VER)
1229#pragma warning(pop)
1230#endif
1231
1232 binaryfunc islot =
1233 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_and : NULL;
1234
1235 if (islot != NULL) {
1236 PyObject *x = islot(*operand1, operand2);
1237
1238 if (x != Py_NotImplemented) {
1239 obj_result = x;
1240 goto exit_inplace_result_object;
1241 }
1242
1243 Py_DECREF_IMMORTAL(x);
1244 }
1245
1246 {
1247 binaryfunc slot1 =
1248 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_and : NULL;
1249 binaryfunc slot2 = NULL;
1250
1251 if (!(type1 == &PySet_Type)) {
1252 // Different types, need to consider second value slot.
1253
1254 slot2 = PySet_Type.tp_as_number->nb_and;
1255
1256 if (slot1 == slot2) {
1257 slot2 = NULL;
1258 }
1259 }
1260
1261 if (slot1 != NULL) {
1262 PyObject *x = slot1(*operand1, operand2);
1263
1264 if (x != Py_NotImplemented) {
1265 obj_result = x;
1266 goto exit_inplace_result_object;
1267 }
1268
1269 Py_DECREF_IMMORTAL(x);
1270 }
1271
1272 if (slot2 != NULL) {
1273 PyObject *x = slot2(*operand1, operand2);
1274
1275 if (x != Py_NotImplemented) {
1276 obj_result = x;
1277 goto exit_inplace_result_object;
1278 }
1279
1280 Py_DECREF_IMMORTAL(x);
1281 }
1282
1283#if PYTHON_VERSION < 0x300
1284 if (!NEW_STYLE_NUMBER_TYPE(type1) || !0) {
1285 coercion c1 =
1286 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1287
1288 if (c1 != NULL) {
1289 PyObject *coerced1 = *operand1;
1290 PyObject *coerced2 = operand2;
1291
1292 int err = c1(&coerced1, &coerced2);
1293
1294 if (unlikely(err < 0)) {
1295 goto exit_inplace_exception;
1296 }
1297
1298 if (err == 0) {
1299 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1300
1301 if (likely(mv == NULL)) {
1302 binaryfunc slot = mv->nb_and;
1303
1304 if (likely(slot != NULL)) {
1305 PyObject *x = slot(coerced1, coerced2);
1306
1307 Py_DECREF(coerced1);
1308 Py_DECREF(coerced2);
1309
1310 obj_result = x;
1311 goto exit_inplace_result_object;
1312 }
1313 }
1314
1315 // nb_coerce took a reference.
1316 Py_DECREF(coerced1);
1317 Py_DECREF(coerced2);
1318 }
1319 }
1320 }
1321#endif
1322
1323 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: '%s' and 'set'", type1->tp_name);
1324 goto exit_inplace_exception;
1325 }
1326
1327exit_inplace_result_object:
1328 if (unlikely(obj_result == NULL)) {
1329 return false;
1330 }
1331
1332 // We got an object handed, that we have to release.
1333 Py_DECREF(*operand1);
1334
1335 // That's our return value then. As we use a dedicated variable, it's
1336 // OK that way.
1337 *operand1 = obj_result;
1338
1339 return true;
1340
1341exit_inplace_exception:
1342 return false;
1343}
1344static inline bool _INPLACE_OPERATION_BITAND_OBJECT_SET(PyObject **operand1, PyObject *operand2) {
1345 assert(operand1); // Pointer must be non-null.
1346
1347 CHECK_OBJECT(*operand1);
1348 CHECK_OBJECT(operand2);
1349 assert(PySet_CheckExact(operand2));
1350
1351 PyTypeObject *type1 = Py_TYPE(*operand1);
1352
1353 if (type1 == &PySet_Type) {
1354 // return _BINARY_OPERATION_BITAND_SET_SET_INPLACE(operand1, operand2);
1355
1356 // Not every code path will make use of all possible results.
1357 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1358
1359 PyObject *x = PySet_Type.tp_as_number->nb_inplace_and(*operand1, operand2);
1360
1361 assert(x != Py_NotImplemented);
1362
1363 obj_result = x;
1364 goto exit_result_object;
1365
1366 exit_result_object:
1367 if (unlikely(obj_result == NULL)) {
1368 goto exit_result_exception;
1369 }
1370 // We got an object handed, that we have to release.
1371 Py_DECREF(*operand1);
1372
1373 *operand1 = obj_result;
1374 goto exit_result_ok;
1375
1376 exit_result_ok:
1377 return true;
1378
1379 exit_result_exception:
1380 return false;
1381 }
1382
1383 return __INPLACE_OPERATION_BITAND_OBJECT_SET(operand1, operand2);
1384}
1385
1386bool INPLACE_OPERATION_BITAND_OBJECT_SET(PyObject **operand1, PyObject *operand2) {
1387 return _INPLACE_OPERATION_BITAND_OBJECT_SET(operand1, operand2);
1388}
1389
1390/* Code referring to "SET" corresponds to Python 'set' and "OBJECT" to any Python object. */
1391static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_BITAND_SET_OBJECT(PyObject **operand1, PyObject *operand2) {
1392 PyTypeObject *type2 = Py_TYPE(operand2);
1393
1394#if defined(_MSC_VER)
1395#pragma warning(push)
1396#pragma warning(disable : 4101)
1397#endif
1398 NUITKA_MAY_BE_UNUSED bool cbool_result;
1399 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1400#if defined(_MSC_VER)
1401#pragma warning(pop)
1402#endif
1403
1404 binaryfunc islot = PySet_Type.tp_as_number->nb_inplace_and;
1405
1406 if (islot != NULL) {
1407 PyObject *x = islot(*operand1, operand2);
1408
1409 if (x != Py_NotImplemented) {
1410 obj_result = x;
1411 goto exit_inplace_result_object;
1412 }
1413
1414 Py_DECREF_IMMORTAL(x);
1415 }
1416
1417 {
1418 binaryfunc slot1 = PySet_Type.tp_as_number->nb_and;
1419 binaryfunc slot2 = NULL;
1420
1421 if (!(&PySet_Type == type2)) {
1422 // Different types, need to consider second value slot.
1423
1424 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_and : NULL;
1425
1426 if (slot1 == slot2) {
1427 slot2 = NULL;
1428 }
1429 }
1430
1431 if (slot1 != NULL) {
1432 if (slot2 != NULL) {
1433 if (Nuitka_Type_IsSubtype(type2, &PySet_Type)) {
1434 PyObject *x = slot2(*operand1, operand2);
1435
1436 if (x != Py_NotImplemented) {
1437 obj_result = x;
1438 goto exit_inplace_result_object;
1439 }
1440
1441 Py_DECREF_IMMORTAL(x);
1442 slot2 = NULL;
1443 }
1444 }
1445
1446 PyObject *x = slot1(*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 }
1455
1456 if (slot2 != NULL) {
1457 PyObject *x = slot2(*operand1, operand2);
1458
1459 if (x != Py_NotImplemented) {
1460 obj_result = x;
1461 goto exit_inplace_result_object;
1462 }
1463
1464 Py_DECREF_IMMORTAL(x);
1465 }
1466
1467#if PYTHON_VERSION < 0x300
1468 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
1469 coercion c2 =
1470 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1471
1472 if (c2 != NULL) {
1473 PyObject *coerced1 = *operand1;
1474 PyObject *coerced2 = operand2;
1475
1476 int err = c2(&coerced2, &coerced1);
1477
1478 if (unlikely(err < 0)) {
1479 goto exit_inplace_exception;
1480 }
1481
1482 if (err == 0) {
1483 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1484
1485 if (likely(mv == NULL)) {
1486 binaryfunc slot = mv->nb_and;
1487
1488 if (likely(slot != NULL)) {
1489 PyObject *x = slot(coerced1, coerced2);
1490
1491 Py_DECREF(coerced1);
1492 Py_DECREF(coerced2);
1493
1494 obj_result = x;
1495 goto exit_inplace_result_object;
1496 }
1497 }
1498
1499 // nb_coerce took a reference.
1500 Py_DECREF(coerced1);
1501 Py_DECREF(coerced2);
1502 }
1503 }
1504 }
1505#endif
1506
1507 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: 'set' and '%s'", type2->tp_name);
1508 goto exit_inplace_exception;
1509 }
1510
1511exit_inplace_result_object:
1512 if (unlikely(obj_result == NULL)) {
1513 return false;
1514 }
1515
1516 // We got an object handed, that we have to release.
1517 Py_DECREF(*operand1);
1518
1519 // That's our return value then. As we use a dedicated variable, it's
1520 // OK that way.
1521 *operand1 = obj_result;
1522
1523 return true;
1524
1525exit_inplace_exception:
1526 return false;
1527}
1528static inline bool _INPLACE_OPERATION_BITAND_SET_OBJECT(PyObject **operand1, PyObject *operand2) {
1529 assert(operand1); // Pointer must be non-null.
1530
1531 CHECK_OBJECT(*operand1);
1532 assert(PySet_CheckExact(*operand1));
1533 CHECK_OBJECT(operand2);
1534
1535 PyTypeObject *type2 = Py_TYPE(operand2);
1536
1537 if (&PySet_Type == type2) {
1538 // return _BINARY_OPERATION_BITAND_SET_SET_INPLACE(operand1, operand2);
1539
1540 // Not every code path will make use of all possible results.
1541 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1542
1543 PyObject *x = PySet_Type.tp_as_number->nb_inplace_and(*operand1, operand2);
1544
1545 assert(x != Py_NotImplemented);
1546
1547 obj_result = x;
1548 goto exit_result_object;
1549
1550 exit_result_object:
1551 if (unlikely(obj_result == NULL)) {
1552 goto exit_result_exception;
1553 }
1554 // We got an object handed, that we have to release.
1555 Py_DECREF(*operand1);
1556
1557 *operand1 = obj_result;
1558 goto exit_result_ok;
1559
1560 exit_result_ok:
1561 return true;
1562
1563 exit_result_exception:
1564 return false;
1565 }
1566
1567 return __INPLACE_OPERATION_BITAND_SET_OBJECT(operand1, operand2);
1568}
1569
1570bool INPLACE_OPERATION_BITAND_SET_OBJECT(PyObject **operand1, PyObject *operand2) {
1571 return _INPLACE_OPERATION_BITAND_SET_OBJECT(operand1, operand2);
1572}
1573
1574/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
1575static inline bool _INPLACE_OPERATION_BITAND_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
1576 assert(operand1); // Pointer must be non-null.
1577
1578 CHECK_OBJECT(*operand1);
1579 CHECK_OBJECT(operand2);
1580
1581#if PYTHON_VERSION < 0x300
1582 if (PyInt_CheckExact(*operand1) && PyInt_CheckExact(operand2)) {
1583
1584 // Not every code path will make use of all possible results.
1585#if defined(_MSC_VER)
1586#pragma warning(push)
1587#pragma warning(disable : 4101)
1588#endif
1589 NUITKA_MAY_BE_UNUSED bool cbool_result;
1590 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1591 NUITKA_MAY_BE_UNUSED long clong_result;
1592 NUITKA_MAY_BE_UNUSED double cfloat_result;
1593#if defined(_MSC_VER)
1594#pragma warning(pop)
1595#endif
1596
1597 CHECK_OBJECT(*operand1);
1598 assert(PyInt_CheckExact(*operand1));
1599 CHECK_OBJECT(operand2);
1600 assert(PyInt_CheckExact(operand2));
1601
1602 const long a = PyInt_AS_LONG(*operand1);
1603 const long b = PyInt_AS_LONG(operand2);
1604
1605 const long r = a & b;
1606
1607 clong_result = r;
1608 goto exit_result_ok_clong;
1609
1610 exit_result_ok_clong:
1611
1612 // We got an object handed, that we have to release.
1613 Py_DECREF(*operand1);
1614
1615 // That's our return value then. As we use a dedicated variable, it's
1616 // OK that way.
1617 *operand1 = Nuitka_PyInt_FromLong(clong_result);
1618 goto exit_result_ok;
1619
1620 exit_result_ok:
1621 return true;
1622 }
1623#endif
1624
1625 if (Py_TYPE(*operand1) == Py_TYPE(operand2)) {
1626#if PYTHON_VERSION >= 0x300
1627 if (PyLong_CheckExact(operand2)) {
1628 return _INPLACE_OPERATION_BITAND_LONG_LONG(operand1, operand2);
1629 }
1630#endif
1631 }
1632
1633 PyTypeObject *type1 = Py_TYPE(*operand1);
1634 PyTypeObject *type2 = Py_TYPE(operand2);
1635
1636#if defined(_MSC_VER)
1637#pragma warning(push)
1638#pragma warning(disable : 4101)
1639#endif
1640 NUITKA_MAY_BE_UNUSED bool cbool_result;
1641 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1642#if defined(_MSC_VER)
1643#pragma warning(pop)
1644#endif
1645
1646 binaryfunc islot =
1647 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_and : NULL;
1648
1649 if (islot != NULL) {
1650 PyObject *x = islot(*operand1, operand2);
1651
1652 if (x != Py_NotImplemented) {
1653 obj_result = x;
1654 goto exit_inplace_result_object;
1655 }
1656
1657 Py_DECREF_IMMORTAL(x);
1658 }
1659
1660 {
1661 binaryfunc slot1 =
1662 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_and : NULL;
1663 binaryfunc slot2 = NULL;
1664
1665 if (!(type1 == type2)) {
1666 // Different types, need to consider second value slot.
1667
1668 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_and : NULL;
1669
1670 if (slot1 == slot2) {
1671 slot2 = NULL;
1672 }
1673 }
1674
1675 if (slot1 != NULL) {
1676 if (slot2 != NULL) {
1677 if (Nuitka_Type_IsSubtype(type2, type1)) {
1678 PyObject *x = slot2(*operand1, operand2);
1679
1680 if (x != Py_NotImplemented) {
1681 obj_result = x;
1682 goto exit_inplace_result_object;
1683 }
1684
1685 Py_DECREF_IMMORTAL(x);
1686 slot2 = NULL;
1687 }
1688 }
1689
1690 PyObject *x = slot1(*operand1, operand2);
1691
1692 if (x != Py_NotImplemented) {
1693 obj_result = x;
1694 goto exit_inplace_result_object;
1695 }
1696
1697 Py_DECREF_IMMORTAL(x);
1698 }
1699
1700 if (slot2 != NULL) {
1701 PyObject *x = slot2(*operand1, operand2);
1702
1703 if (x != Py_NotImplemented) {
1704 obj_result = x;
1705 goto exit_inplace_result_object;
1706 }
1707
1708 Py_DECREF_IMMORTAL(x);
1709 }
1710
1711#if PYTHON_VERSION < 0x300
1712 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
1713 coercion c1 =
1714 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1715
1716 if (c1 != NULL) {
1717 PyObject *coerced1 = *operand1;
1718 PyObject *coerced2 = operand2;
1719
1720 int err = c1(&coerced1, &coerced2);
1721
1722 if (unlikely(err < 0)) {
1723 goto exit_inplace_exception;
1724 }
1725
1726 if (err == 0) {
1727 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1728
1729 if (likely(mv == NULL)) {
1730 binaryfunc slot = mv->nb_and;
1731
1732 if (likely(slot != NULL)) {
1733 PyObject *x = slot(coerced1, coerced2);
1734
1735 Py_DECREF(coerced1);
1736 Py_DECREF(coerced2);
1737
1738 obj_result = x;
1739 goto exit_inplace_result_object;
1740 }
1741 }
1742
1743 // nb_coerce took a reference.
1744 Py_DECREF(coerced1);
1745 Py_DECREF(coerced2);
1746 }
1747 }
1748 coercion c2 =
1749 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1750
1751 if (c2 != NULL) {
1752 PyObject *coerced1 = *operand1;
1753 PyObject *coerced2 = operand2;
1754
1755 int err = c2(&coerced2, &coerced1);
1756
1757 if (unlikely(err < 0)) {
1758 goto exit_inplace_exception;
1759 }
1760
1761 if (err == 0) {
1762 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1763
1764 if (likely(mv == NULL)) {
1765 binaryfunc slot = mv->nb_and;
1766
1767 if (likely(slot != NULL)) {
1768 PyObject *x = slot(coerced1, coerced2);
1769
1770 Py_DECREF(coerced1);
1771 Py_DECREF(coerced2);
1772
1773 obj_result = x;
1774 goto exit_inplace_result_object;
1775 }
1776 }
1777
1778 // nb_coerce took a reference.
1779 Py_DECREF(coerced1);
1780 Py_DECREF(coerced2);
1781 }
1782 }
1783 }
1784#endif
1785
1786 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for &=: '%s' and '%s'", type1->tp_name,
1787 type2->tp_name);
1788 goto exit_inplace_exception;
1789 }
1790
1791exit_inplace_result_object:
1792 if (unlikely(obj_result == NULL)) {
1793 return false;
1794 }
1795
1796 // We got an object handed, that we have to release.
1797 Py_DECREF(*operand1);
1798
1799 // That's our return value then. As we use a dedicated variable, it's
1800 // OK that way.
1801 *operand1 = obj_result;
1802
1803 return true;
1804
1805exit_inplace_exception:
1806 return false;
1807}
1808
1809bool INPLACE_OPERATION_BITAND_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
1810 return _INPLACE_OPERATION_BITAND_OBJECT_OBJECT(operand1, operand2);
1811}
1812
1813// Part of "Nuitka", an optimizing Python compiler that is compatible and
1814// integrates with CPython, but also works on its own.
1815//
1816// Licensed under the Apache License, Version 2.0 (the "License");
1817// you may not use this file except in compliance with the License.
1818// You may obtain a copy of the License at
1819//
1820// http://www.apache.org/licenses/LICENSE-2.0
1821//
1822// Unless required by applicable law or agreed to in writing, software
1823// distributed under the License is distributed on an "AS IS" BASIS,
1824// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1825// See the License for the specific language governing permissions and
1826// limitations under the License.