Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationBinaryAdd.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 HelperOperationBinary.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#include "HelpersOperationBinaryAddUtils.c"
11/* C helpers for type specialized "+" (ADD) operations */
12
13#if PYTHON_VERSION < 0x300
14/* Code referring to "INT" corresponds to Python2 'int' and "INT" to Python2 'int'. */
15static PyObject *_BINARY_OPERATION_ADD_OBJECT_INT_INT(PyObject *operand1, PyObject *operand2) {
16 CHECK_OBJECT(operand1);
17 assert(PyInt_CheckExact(operand1));
18 CHECK_OBJECT(operand2);
19 assert(PyInt_CheckExact(operand2));
20
21 PyObject *result;
22
23 // Not every code path will make use of all possible results.
24#if defined(_MSC_VER)
25#pragma warning(push)
26#pragma warning(disable : 4101)
27#endif
28 NUITKA_MAY_BE_UNUSED bool cbool_result;
29 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
30 NUITKA_MAY_BE_UNUSED long clong_result;
31 NUITKA_MAY_BE_UNUSED double cfloat_result;
32#if defined(_MSC_VER)
33#pragma warning(pop)
34#endif
35
36 CHECK_OBJECT(operand1);
37 assert(PyInt_CheckExact(operand1));
38 CHECK_OBJECT(operand2);
39 assert(PyInt_CheckExact(operand2));
40
41 const long a = PyInt_AS_LONG(operand1);
42 const long b = PyInt_AS_LONG(operand2);
43
44 const long x = (long)((unsigned long)a + b);
45 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
46 if (likely(no_overflow)) {
47 clong_result = x;
48 goto exit_result_ok_clong;
49 }
50
51 {
52 PyObject *operand1_object = operand1;
53 PyObject *operand2_object = operand2;
54
55 PyObject *r = PyLong_Type.tp_as_number->nb_add(operand1_object, operand2_object);
56 assert(r != Py_NotImplemented);
57
58 obj_result = r;
59 goto exit_result_object;
60 }
61
62exit_result_ok_clong:
63 result = Nuitka_PyInt_FromLong(clong_result);
64 goto exit_result_ok;
65
66exit_result_object:
67 if (unlikely(obj_result == NULL)) {
68 goto exit_result_exception;
69 }
70 result = obj_result;
71 goto exit_result_ok;
72
73exit_result_ok:
74 return result;
75
76exit_result_exception:
77 return NULL;
78}
79
80PyObject *BINARY_OPERATION_ADD_OBJECT_INT_INT(PyObject *operand1, PyObject *operand2) {
81 return _BINARY_OPERATION_ADD_OBJECT_INT_INT(operand1, operand2);
82}
83#endif
84
85#if PYTHON_VERSION < 0x300
86/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
87static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
88 PyTypeObject *type1 = Py_TYPE(operand1);
89
90#if defined(_MSC_VER)
91#pragma warning(push)
92#pragma warning(disable : 4101)
93#endif
94 NUITKA_MAY_BE_UNUSED bool cbool_result;
95 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
96#if defined(_MSC_VER)
97#pragma warning(pop)
98#endif
99
100 binaryfunc slot1 =
101 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
102 binaryfunc slot2 = NULL;
103
104 if (!(type1 == &PyInt_Type)) {
105 // Different types, need to consider second value slot.
106
107 slot2 = PyInt_Type.tp_as_number->nb_add;
108
109 if (slot1 == slot2) {
110 slot2 = NULL;
111 }
112 }
113
114 if (slot1 != NULL) {
115 PyObject *x = slot1(operand1, operand2);
116
117 if (x != Py_NotImplemented) {
118 obj_result = x;
119 goto exit_binary_result_object;
120 }
121
122 Py_DECREF_IMMORTAL(x);
123 }
124
125 if (slot2 != NULL) {
126 PyObject *x = slot2(operand1, operand2);
127
128 if (x != Py_NotImplemented) {
129 obj_result = x;
130 goto exit_binary_result_object;
131 }
132
133 Py_DECREF_IMMORTAL(x);
134 }
135
136#if PYTHON_VERSION < 0x300
137 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
138 coercion c1 =
139 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
140
141 if (c1 != NULL) {
142 PyObject *coerced1 = operand1;
143 PyObject *coerced2 = operand2;
144
145 int err = c1(&coerced1, &coerced2);
146
147 if (unlikely(err < 0)) {
148 goto exit_binary_exception;
149 }
150
151 if (err == 0) {
152 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
153
154 if (likely(mv == NULL)) {
155 binaryfunc slot = mv->nb_add;
156
157 if (likely(slot != NULL)) {
158 PyObject *x = slot(coerced1, coerced2);
159
160 Py_DECREF(coerced1);
161 Py_DECREF(coerced2);
162
163 obj_result = x;
164 goto exit_binary_result_object;
165 }
166 }
167
168 // nb_coerce took a reference.
169 Py_DECREF(coerced1);
170 Py_DECREF(coerced2);
171 }
172 }
173 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
174
175 if (c2 != NULL) {
176 PyObject *coerced1 = operand1;
177 PyObject *coerced2 = operand2;
178
179 int err = c2(&coerced2, &coerced1);
180
181 if (unlikely(err < 0)) {
182 goto exit_binary_exception;
183 }
184
185 if (err == 0) {
186 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
187
188 if (likely(mv == NULL)) {
189 binaryfunc slot = mv->nb_add;
190
191 if (likely(slot != NULL)) {
192 PyObject *x = slot(coerced1, coerced2);
193
194 Py_DECREF(coerced1);
195 Py_DECREF(coerced2);
196
197 obj_result = x;
198 goto exit_binary_result_object;
199 }
200 }
201
202 // nb_coerce took a reference.
203 Py_DECREF(coerced1);
204 Py_DECREF(coerced2);
205 }
206 }
207 }
208#endif
209
210 {
211 // Special case for "+" and "*", also works as sequence concat/repeat.
212 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
213
214 if (sq_slot != NULL) {
215 PyObject *result = sq_slot(operand1, operand2);
216
217 obj_result = result;
218 goto exit_binary_result_object;
219 }
220 }
221
222 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'int'", type1->tp_name);
223 goto exit_binary_exception;
224
225exit_binary_result_object:
226 return obj_result;
227
228exit_binary_exception:
229 return NULL;
230}
231static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
232 CHECK_OBJECT(operand1);
233 CHECK_OBJECT(operand2);
234 assert(PyInt_CheckExact(operand2));
235
236 PyTypeObject *type1 = Py_TYPE(operand1);
237
238 if (type1 == &PyInt_Type) {
239 PyObject *result;
240
241 // return _BINARY_OPERATION_ADD_OBJECT_INT_INT(operand1, operand2);
242
243 // Not every code path will make use of all possible results.
244#if defined(_MSC_VER)
245#pragma warning(push)
246#pragma warning(disable : 4101)
247#endif
248 NUITKA_MAY_BE_UNUSED bool cbool_result;
249 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
250 NUITKA_MAY_BE_UNUSED long clong_result;
251 NUITKA_MAY_BE_UNUSED double cfloat_result;
252#if defined(_MSC_VER)
253#pragma warning(pop)
254#endif
255
256 CHECK_OBJECT(operand1);
257 assert(PyInt_CheckExact(operand1));
258 CHECK_OBJECT(operand2);
259 assert(PyInt_CheckExact(operand2));
260
261 const long a = PyInt_AS_LONG(operand1);
262 const long b = PyInt_AS_LONG(operand2);
263
264 const long x = (long)((unsigned long)a + b);
265 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
266 if (likely(no_overflow)) {
267 clong_result = x;
268 goto exit_result_ok_clong;
269 }
270
271 {
272 PyObject *operand1_object = operand1;
273 PyObject *operand2_object = operand2;
274
275 PyObject *r = PyLong_Type.tp_as_number->nb_add(operand1_object, operand2_object);
276 assert(r != Py_NotImplemented);
277
278 obj_result = r;
279 goto exit_result_object;
280 }
281
282 exit_result_ok_clong:
283 result = Nuitka_PyInt_FromLong(clong_result);
284 goto exit_result_ok;
285
286 exit_result_object:
287 if (unlikely(obj_result == NULL)) {
288 goto exit_result_exception;
289 }
290 result = obj_result;
291 goto exit_result_ok;
292
293 exit_result_ok:
294 return result;
295
296 exit_result_exception:
297 return NULL;
298 }
299
300 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_INT(operand1, operand2);
301}
302
303PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
304 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_INT(operand1, operand2);
305}
306#endif
307
308#if PYTHON_VERSION < 0x300
309/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
310static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
311 PyTypeObject *type2 = Py_TYPE(operand2);
312
313#if defined(_MSC_VER)
314#pragma warning(push)
315#pragma warning(disable : 4101)
316#endif
317 NUITKA_MAY_BE_UNUSED bool cbool_result;
318 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
319#if defined(_MSC_VER)
320#pragma warning(pop)
321#endif
322
323 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_add;
324 binaryfunc slot2 = NULL;
325
326 if (!(&PyInt_Type == type2)) {
327 // Different types, need to consider second value slot.
328
329 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
330
331 if (slot1 == slot2) {
332 slot2 = NULL;
333 }
334 }
335
336 if (slot1 != NULL) {
337 if (slot2 != NULL) {
338 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
339 PyObject *x = slot2(operand1, operand2);
340
341 if (x != Py_NotImplemented) {
342 obj_result = x;
343 goto exit_binary_result_object;
344 }
345
346 Py_DECREF_IMMORTAL(x);
347 slot2 = NULL;
348 }
349 }
350
351 PyObject *x = slot1(operand1, operand2);
352
353 if (x != Py_NotImplemented) {
354 obj_result = x;
355 goto exit_binary_result_object;
356 }
357
358 Py_DECREF_IMMORTAL(x);
359 }
360
361 if (slot2 != NULL) {
362 PyObject *x = slot2(operand1, operand2);
363
364 if (x != Py_NotImplemented) {
365 obj_result = x;
366 goto exit_binary_result_object;
367 }
368
369 Py_DECREF_IMMORTAL(x);
370 }
371
372#if PYTHON_VERSION < 0x300
373 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
374 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
375
376 if (c1 != NULL) {
377 PyObject *coerced1 = operand1;
378 PyObject *coerced2 = operand2;
379
380 int err = c1(&coerced1, &coerced2);
381
382 if (unlikely(err < 0)) {
383 goto exit_binary_exception;
384 }
385
386 if (err == 0) {
387 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
388
389 if (likely(mv == NULL)) {
390 binaryfunc slot = mv->nb_add;
391
392 if (likely(slot != NULL)) {
393 PyObject *x = slot(coerced1, coerced2);
394
395 Py_DECREF(coerced1);
396 Py_DECREF(coerced2);
397
398 obj_result = x;
399 goto exit_binary_result_object;
400 }
401 }
402
403 // nb_coerce took a reference.
404 Py_DECREF(coerced1);
405 Py_DECREF(coerced2);
406 }
407 }
408 coercion c2 =
409 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
410
411 if (c2 != NULL) {
412 PyObject *coerced1 = operand1;
413 PyObject *coerced2 = operand2;
414
415 int err = c2(&coerced2, &coerced1);
416
417 if (unlikely(err < 0)) {
418 goto exit_binary_exception;
419 }
420
421 if (err == 0) {
422 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
423
424 if (likely(mv == NULL)) {
425 binaryfunc slot = mv->nb_add;
426
427 if (likely(slot != NULL)) {
428 PyObject *x = slot(coerced1, coerced2);
429
430 Py_DECREF(coerced1);
431 Py_DECREF(coerced2);
432
433 obj_result = x;
434 goto exit_binary_result_object;
435 }
436 }
437
438 // nb_coerce took a reference.
439 Py_DECREF(coerced1);
440 Py_DECREF(coerced2);
441 }
442 }
443 }
444#endif
445
446 {
447 // No sequence repeat slot sq_concat available for this type.
448 }
449
450 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and '%s'", type2->tp_name);
451 goto exit_binary_exception;
452
453exit_binary_result_object:
454 return obj_result;
455
456exit_binary_exception:
457 return NULL;
458}
459static PyObject *_BINARY_OPERATION_ADD_OBJECT_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
460 CHECK_OBJECT(operand1);
461 assert(PyInt_CheckExact(operand1));
462 CHECK_OBJECT(operand2);
463
464 PyTypeObject *type2 = Py_TYPE(operand2);
465
466 if (&PyInt_Type == type2) {
467 PyObject *result;
468
469 // return _BINARY_OPERATION_ADD_OBJECT_INT_INT(operand1, operand2);
470
471 // Not every code path will make use of all possible results.
472#if defined(_MSC_VER)
473#pragma warning(push)
474#pragma warning(disable : 4101)
475#endif
476 NUITKA_MAY_BE_UNUSED bool cbool_result;
477 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
478 NUITKA_MAY_BE_UNUSED long clong_result;
479 NUITKA_MAY_BE_UNUSED double cfloat_result;
480#if defined(_MSC_VER)
481#pragma warning(pop)
482#endif
483
484 CHECK_OBJECT(operand1);
485 assert(PyInt_CheckExact(operand1));
486 CHECK_OBJECT(operand2);
487 assert(PyInt_CheckExact(operand2));
488
489 const long a = PyInt_AS_LONG(operand1);
490 const long b = PyInt_AS_LONG(operand2);
491
492 const long x = (long)((unsigned long)a + b);
493 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
494 if (likely(no_overflow)) {
495 clong_result = x;
496 goto exit_result_ok_clong;
497 }
498
499 {
500 PyObject *operand1_object = operand1;
501 PyObject *operand2_object = operand2;
502
503 PyObject *r = PyLong_Type.tp_as_number->nb_add(operand1_object, operand2_object);
504 assert(r != Py_NotImplemented);
505
506 obj_result = r;
507 goto exit_result_object;
508 }
509
510 exit_result_ok_clong:
511 result = Nuitka_PyInt_FromLong(clong_result);
512 goto exit_result_ok;
513
514 exit_result_object:
515 if (unlikely(obj_result == NULL)) {
516 goto exit_result_exception;
517 }
518 result = obj_result;
519 goto exit_result_ok;
520
521 exit_result_ok:
522 return result;
523
524 exit_result_exception:
525 return NULL;
526 }
527
528 return __BINARY_OPERATION_ADD_OBJECT_INT_OBJECT(operand1, operand2);
529}
530
531PyObject *BINARY_OPERATION_ADD_OBJECT_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
532 return _BINARY_OPERATION_ADD_OBJECT_INT_OBJECT(operand1, operand2);
533}
534#endif
535
536#if PYTHON_VERSION < 0x300
537/* Code referring to "INT" corresponds to Python2 'int' and "INT" to Python2 'int'. */
538static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_INT_INT(PyObject *operand1, PyObject *operand2) {
539 CHECK_OBJECT(operand1);
540 assert(PyInt_CheckExact(operand1));
541 CHECK_OBJECT(operand2);
542 assert(PyInt_CheckExact(operand2));
543
544 nuitka_bool result;
545
546 // Not every code path will make use of all possible results.
547#if defined(_MSC_VER)
548#pragma warning(push)
549#pragma warning(disable : 4101)
550#endif
551 NUITKA_MAY_BE_UNUSED bool cbool_result;
552 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
553 NUITKA_MAY_BE_UNUSED long clong_result;
554 NUITKA_MAY_BE_UNUSED double cfloat_result;
555#if defined(_MSC_VER)
556#pragma warning(pop)
557#endif
558
559 CHECK_OBJECT(operand1);
560 assert(PyInt_CheckExact(operand1));
561 CHECK_OBJECT(operand2);
562 assert(PyInt_CheckExact(operand2));
563
564 const long a = PyInt_AS_LONG(operand1);
565 const long b = PyInt_AS_LONG(operand2);
566
567 const long x = (long)((unsigned long)a + b);
568 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
569 bool t = !no_overflow || x != 0;
570
571 cbool_result = t;
572 goto exit_result_ok_cbool;
573
574exit_result_ok_cbool:
575 result = cbool_result ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
576 goto exit_result_ok;
577
578exit_result_ok:
579 return result;
580}
581
582nuitka_bool BINARY_OPERATION_ADD_NBOOL_INT_INT(PyObject *operand1, PyObject *operand2) {
583 return _BINARY_OPERATION_ADD_NBOOL_INT_INT(operand1, operand2);
584}
585#endif
586
587#if PYTHON_VERSION < 0x300
588/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
589static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
590 PyTypeObject *type1 = Py_TYPE(operand1);
591
592#if defined(_MSC_VER)
593#pragma warning(push)
594#pragma warning(disable : 4101)
595#endif
596 NUITKA_MAY_BE_UNUSED bool cbool_result;
597 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
598#if defined(_MSC_VER)
599#pragma warning(pop)
600#endif
601
602 binaryfunc slot1 =
603 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
604 binaryfunc slot2 = NULL;
605
606 if (!(type1 == &PyInt_Type)) {
607 // Different types, need to consider second value slot.
608
609 slot2 = PyInt_Type.tp_as_number->nb_add;
610
611 if (slot1 == slot2) {
612 slot2 = NULL;
613 }
614 }
615
616 if (slot1 != NULL) {
617 PyObject *x = slot1(operand1, operand2);
618
619 if (x != Py_NotImplemented) {
620 obj_result = x;
621 goto exit_binary_result_object;
622 }
623
624 Py_DECREF_IMMORTAL(x);
625 }
626
627 if (slot2 != NULL) {
628 PyObject *x = slot2(operand1, operand2);
629
630 if (x != Py_NotImplemented) {
631 obj_result = x;
632 goto exit_binary_result_object;
633 }
634
635 Py_DECREF_IMMORTAL(x);
636 }
637
638#if PYTHON_VERSION < 0x300
639 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
640 coercion c1 =
641 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
642
643 if (c1 != NULL) {
644 PyObject *coerced1 = operand1;
645 PyObject *coerced2 = operand2;
646
647 int err = c1(&coerced1, &coerced2);
648
649 if (unlikely(err < 0)) {
650 goto exit_binary_exception;
651 }
652
653 if (err == 0) {
654 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
655
656 if (likely(mv == NULL)) {
657 binaryfunc slot = mv->nb_add;
658
659 if (likely(slot != NULL)) {
660 PyObject *x = slot(coerced1, coerced2);
661
662 Py_DECREF(coerced1);
663 Py_DECREF(coerced2);
664
665 obj_result = x;
666 goto exit_binary_result_object;
667 }
668 }
669
670 // nb_coerce took a reference.
671 Py_DECREF(coerced1);
672 Py_DECREF(coerced2);
673 }
674 }
675 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
676
677 if (c2 != NULL) {
678 PyObject *coerced1 = operand1;
679 PyObject *coerced2 = operand2;
680
681 int err = c2(&coerced2, &coerced1);
682
683 if (unlikely(err < 0)) {
684 goto exit_binary_exception;
685 }
686
687 if (err == 0) {
688 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
689
690 if (likely(mv == NULL)) {
691 binaryfunc slot = mv->nb_add;
692
693 if (likely(slot != NULL)) {
694 PyObject *x = slot(coerced1, coerced2);
695
696 Py_DECREF(coerced1);
697 Py_DECREF(coerced2);
698
699 obj_result = x;
700 goto exit_binary_result_object;
701 }
702 }
703
704 // nb_coerce took a reference.
705 Py_DECREF(coerced1);
706 Py_DECREF(coerced2);
707 }
708 }
709 }
710#endif
711
712 {
713 // Special case for "+" and "*", also works as sequence concat/repeat.
714 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
715
716 if (sq_slot != NULL) {
717 PyObject *result = sq_slot(operand1, operand2);
718
719 obj_result = result;
720 goto exit_binary_result_object;
721 }
722 }
723
724 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'int'", type1->tp_name);
725 goto exit_binary_exception;
726
727exit_binary_result_object:
728 if (unlikely(obj_result == NULL)) {
729 return NUITKA_BOOL_EXCEPTION;
730 }
731
732 {
733 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
734 Py_DECREF(obj_result);
735 return r;
736 }
737
738exit_binary_exception:
739 return NUITKA_BOOL_EXCEPTION;
740}
741static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
742 CHECK_OBJECT(operand1);
743 CHECK_OBJECT(operand2);
744 assert(PyInt_CheckExact(operand2));
745
746 PyTypeObject *type1 = Py_TYPE(operand1);
747
748 if (type1 == &PyInt_Type) {
749 nuitka_bool result;
750
751 // return _BINARY_OPERATION_ADD_NBOOL_INT_INT(operand1, operand2);
752
753 // Not every code path will make use of all possible results.
754#if defined(_MSC_VER)
755#pragma warning(push)
756#pragma warning(disable : 4101)
757#endif
758 NUITKA_MAY_BE_UNUSED bool cbool_result;
759 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
760 NUITKA_MAY_BE_UNUSED long clong_result;
761 NUITKA_MAY_BE_UNUSED double cfloat_result;
762#if defined(_MSC_VER)
763#pragma warning(pop)
764#endif
765
766 CHECK_OBJECT(operand1);
767 assert(PyInt_CheckExact(operand1));
768 CHECK_OBJECT(operand2);
769 assert(PyInt_CheckExact(operand2));
770
771 const long a = PyInt_AS_LONG(operand1);
772 const long b = PyInt_AS_LONG(operand2);
773
774 const long x = (long)((unsigned long)a + b);
775 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
776 bool t = !no_overflow || x != 0;
777
778 cbool_result = t;
779 goto exit_result_ok_cbool;
780
781 exit_result_ok_cbool:
782 result = cbool_result ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
783 goto exit_result_ok;
784
785 exit_result_ok:
786 return result;
787 }
788
789 return __BINARY_OPERATION_ADD_NBOOL_OBJECT_INT(operand1, operand2);
790}
791
792nuitka_bool BINARY_OPERATION_ADD_NBOOL_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
793 return _BINARY_OPERATION_ADD_NBOOL_OBJECT_INT(operand1, operand2);
794}
795#endif
796
797#if PYTHON_VERSION < 0x300
798/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
799static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
800 PyTypeObject *type2 = Py_TYPE(operand2);
801
802#if defined(_MSC_VER)
803#pragma warning(push)
804#pragma warning(disable : 4101)
805#endif
806 NUITKA_MAY_BE_UNUSED bool cbool_result;
807 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
808#if defined(_MSC_VER)
809#pragma warning(pop)
810#endif
811
812 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_add;
813 binaryfunc slot2 = NULL;
814
815 if (!(&PyInt_Type == type2)) {
816 // Different types, need to consider second value slot.
817
818 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
819
820 if (slot1 == slot2) {
821 slot2 = NULL;
822 }
823 }
824
825 if (slot1 != NULL) {
826 if (slot2 != NULL) {
827 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
828 PyObject *x = slot2(operand1, operand2);
829
830 if (x != Py_NotImplemented) {
831 obj_result = x;
832 goto exit_binary_result_object;
833 }
834
835 Py_DECREF_IMMORTAL(x);
836 slot2 = NULL;
837 }
838 }
839
840 PyObject *x = slot1(operand1, operand2);
841
842 if (x != Py_NotImplemented) {
843 obj_result = x;
844 goto exit_binary_result_object;
845 }
846
847 Py_DECREF_IMMORTAL(x);
848 }
849
850 if (slot2 != NULL) {
851 PyObject *x = slot2(operand1, operand2);
852
853 if (x != Py_NotImplemented) {
854 obj_result = x;
855 goto exit_binary_result_object;
856 }
857
858 Py_DECREF_IMMORTAL(x);
859 }
860
861#if PYTHON_VERSION < 0x300
862 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
863 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
864
865 if (c1 != NULL) {
866 PyObject *coerced1 = operand1;
867 PyObject *coerced2 = operand2;
868
869 int err = c1(&coerced1, &coerced2);
870
871 if (unlikely(err < 0)) {
872 goto exit_binary_exception;
873 }
874
875 if (err == 0) {
876 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
877
878 if (likely(mv == NULL)) {
879 binaryfunc slot = mv->nb_add;
880
881 if (likely(slot != NULL)) {
882 PyObject *x = slot(coerced1, coerced2);
883
884 Py_DECREF(coerced1);
885 Py_DECREF(coerced2);
886
887 obj_result = x;
888 goto exit_binary_result_object;
889 }
890 }
891
892 // nb_coerce took a reference.
893 Py_DECREF(coerced1);
894 Py_DECREF(coerced2);
895 }
896 }
897 coercion c2 =
898 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
899
900 if (c2 != NULL) {
901 PyObject *coerced1 = operand1;
902 PyObject *coerced2 = operand2;
903
904 int err = c2(&coerced2, &coerced1);
905
906 if (unlikely(err < 0)) {
907 goto exit_binary_exception;
908 }
909
910 if (err == 0) {
911 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
912
913 if (likely(mv == NULL)) {
914 binaryfunc slot = mv->nb_add;
915
916 if (likely(slot != NULL)) {
917 PyObject *x = slot(coerced1, coerced2);
918
919 Py_DECREF(coerced1);
920 Py_DECREF(coerced2);
921
922 obj_result = x;
923 goto exit_binary_result_object;
924 }
925 }
926
927 // nb_coerce took a reference.
928 Py_DECREF(coerced1);
929 Py_DECREF(coerced2);
930 }
931 }
932 }
933#endif
934
935 {
936 // No sequence repeat slot sq_concat available for this type.
937 }
938
939 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and '%s'", type2->tp_name);
940 goto exit_binary_exception;
941
942exit_binary_result_object:
943 if (unlikely(obj_result == NULL)) {
944 return NUITKA_BOOL_EXCEPTION;
945 }
946
947 {
948 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
949 Py_DECREF(obj_result);
950 return r;
951 }
952
953exit_binary_exception:
954 return NUITKA_BOOL_EXCEPTION;
955}
956static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
957 CHECK_OBJECT(operand1);
958 assert(PyInt_CheckExact(operand1));
959 CHECK_OBJECT(operand2);
960
961 PyTypeObject *type2 = Py_TYPE(operand2);
962
963 if (&PyInt_Type == type2) {
964 nuitka_bool result;
965
966 // return _BINARY_OPERATION_ADD_NBOOL_INT_INT(operand1, operand2);
967
968 // Not every code path will make use of all possible results.
969#if defined(_MSC_VER)
970#pragma warning(push)
971#pragma warning(disable : 4101)
972#endif
973 NUITKA_MAY_BE_UNUSED bool cbool_result;
974 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
975 NUITKA_MAY_BE_UNUSED long clong_result;
976 NUITKA_MAY_BE_UNUSED double cfloat_result;
977#if defined(_MSC_VER)
978#pragma warning(pop)
979#endif
980
981 CHECK_OBJECT(operand1);
982 assert(PyInt_CheckExact(operand1));
983 CHECK_OBJECT(operand2);
984 assert(PyInt_CheckExact(operand2));
985
986 const long a = PyInt_AS_LONG(operand1);
987 const long b = PyInt_AS_LONG(operand2);
988
989 const long x = (long)((unsigned long)a + b);
990 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
991 bool t = !no_overflow || x != 0;
992
993 cbool_result = t;
994 goto exit_result_ok_cbool;
995
996 exit_result_ok_cbool:
997 result = cbool_result ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
998 goto exit_result_ok;
999
1000 exit_result_ok:
1001 return result;
1002 }
1003
1004 return __BINARY_OPERATION_ADD_NBOOL_INT_OBJECT(operand1, operand2);
1005}
1006
1007nuitka_bool BINARY_OPERATION_ADD_NBOOL_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
1008 return _BINARY_OPERATION_ADD_NBOOL_INT_OBJECT(operand1, operand2);
1009}
1010#endif
1011
1012/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "LONG" to Python2 'long', Python3 'int'. */
1013static PyObject *_BINARY_OPERATION_ADD_OBJECT_LONG_LONG(PyObject *operand1, PyObject *operand2) {
1014 CHECK_OBJECT(operand1);
1015 assert(PyLong_CheckExact(operand1));
1016 CHECK_OBJECT(operand2);
1017 assert(PyLong_CheckExact(operand2));
1018
1019 PyObject *result;
1020
1021 // Not every code path will make use of all possible results.
1022#if defined(_MSC_VER)
1023#pragma warning(push)
1024#pragma warning(disable : 4101)
1025#endif
1026 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1027 NUITKA_MAY_BE_UNUSED long clong_result;
1028#if defined(_MSC_VER)
1029#pragma warning(pop)
1030#endif
1031
1032 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
1033
1034 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
1035
1036 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && Nuitka_LongGetDigitSize(operand2_long_object) <= 1) {
1037 long r = (long)(MEDIUM_VALUE(operand1_long_object) + MEDIUM_VALUE(operand2_long_object));
1038
1039 clong_result = r;
1040 goto exit_result_ok_clong;
1041 }
1042
1043 {
1044 PyLongObject *z;
1045
1046 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
1047 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
1048 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
1049 digit const *b_digits = Nuitka_LongGetDigitPointer(operand2_long_object);
1050 Py_ssize_t b_digit_count = Nuitka_LongGetDigitSize(operand2_long_object);
1051 bool b_negative = Nuitka_LongIsNegative(operand2_long_object);
1052
1053 if (a_negative) {
1054 if (b_negative) {
1055 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1056 Nuitka_LongFlipSign(z);
1057 } else {
1058 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
1059 }
1060 } else {
1061 if (b_negative) {
1062 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1063 } else {
1064 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1065 }
1066 }
1067
1068 obj_result = (PyObject *)z;
1069 goto exit_result_object;
1070 }
1071
1072exit_result_object:
1073 if (unlikely(obj_result == NULL)) {
1074 goto exit_result_exception;
1075 }
1076 result = obj_result;
1077 goto exit_result_ok;
1078
1079exit_result_ok_clong:
1080 result = Nuitka_LongFromCLong(clong_result);
1081 goto exit_result_ok;
1082
1083exit_result_ok:
1084 return result;
1085
1086exit_result_exception:
1087 return NULL;
1088}
1089
1090PyObject *BINARY_OPERATION_ADD_OBJECT_LONG_LONG(PyObject *operand1, PyObject *operand2) {
1091 return _BINARY_OPERATION_ADD_OBJECT_LONG_LONG(operand1, operand2);
1092}
1093
1094/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
1095static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
1096 PyTypeObject *type1 = Py_TYPE(operand1);
1097
1098#if defined(_MSC_VER)
1099#pragma warning(push)
1100#pragma warning(disable : 4101)
1101#endif
1102 NUITKA_MAY_BE_UNUSED bool cbool_result;
1103 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1104#if defined(_MSC_VER)
1105#pragma warning(pop)
1106#endif
1107
1108 binaryfunc slot1 =
1109 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
1110 binaryfunc slot2 = NULL;
1111
1112 if (!(type1 == &PyLong_Type)) {
1113 // Different types, need to consider second value slot.
1114
1115 slot2 = PyLong_Type.tp_as_number->nb_add;
1116
1117 if (slot1 == slot2) {
1118 slot2 = NULL;
1119 }
1120 }
1121
1122 if (slot1 != NULL) {
1123 PyObject *x = slot1(operand1, operand2);
1124
1125 if (x != Py_NotImplemented) {
1126 obj_result = x;
1127 goto exit_binary_result_object;
1128 }
1129
1130 Py_DECREF_IMMORTAL(x);
1131 }
1132
1133 if (slot2 != NULL) {
1134 PyObject *x = slot2(operand1, operand2);
1135
1136 if (x != Py_NotImplemented) {
1137 obj_result = x;
1138 goto exit_binary_result_object;
1139 }
1140
1141 Py_DECREF_IMMORTAL(x);
1142 }
1143
1144#if PYTHON_VERSION < 0x300
1145 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
1146 coercion c1 =
1147 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1148
1149 if (c1 != NULL) {
1150 PyObject *coerced1 = operand1;
1151 PyObject *coerced2 = operand2;
1152
1153 int err = c1(&coerced1, &coerced2);
1154
1155 if (unlikely(err < 0)) {
1156 goto exit_binary_exception;
1157 }
1158
1159 if (err == 0) {
1160 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1161
1162 if (likely(mv == NULL)) {
1163 binaryfunc slot = mv->nb_add;
1164
1165 if (likely(slot != NULL)) {
1166 PyObject *x = slot(coerced1, coerced2);
1167
1168 Py_DECREF(coerced1);
1169 Py_DECREF(coerced2);
1170
1171 obj_result = x;
1172 goto exit_binary_result_object;
1173 }
1174 }
1175
1176 // nb_coerce took a reference.
1177 Py_DECREF(coerced1);
1178 Py_DECREF(coerced2);
1179 }
1180 }
1181 coercion c2 = PyLong_Type.tp_as_number->nb_coerce;
1182
1183 if (c2 != NULL) {
1184 PyObject *coerced1 = operand1;
1185 PyObject *coerced2 = operand2;
1186
1187 int err = c2(&coerced2, &coerced1);
1188
1189 if (unlikely(err < 0)) {
1190 goto exit_binary_exception;
1191 }
1192
1193 if (err == 0) {
1194 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1195
1196 if (likely(mv == NULL)) {
1197 binaryfunc slot = mv->nb_add;
1198
1199 if (likely(slot != NULL)) {
1200 PyObject *x = slot(coerced1, coerced2);
1201
1202 Py_DECREF(coerced1);
1203 Py_DECREF(coerced2);
1204
1205 obj_result = x;
1206 goto exit_binary_result_object;
1207 }
1208 }
1209
1210 // nb_coerce took a reference.
1211 Py_DECREF(coerced1);
1212 Py_DECREF(coerced2);
1213 }
1214 }
1215 }
1216#endif
1217
1218 {
1219 // Special case for "+" and "*", also works as sequence concat/repeat.
1220 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
1221
1222 if (sq_slot != NULL) {
1223 PyObject *result = sq_slot(operand1, operand2);
1224
1225 obj_result = result;
1226 goto exit_binary_result_object;
1227 }
1228 }
1229
1230#if PYTHON_VERSION < 0x300
1231 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'long'", type1->tp_name);
1232#else
1233 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'int'", type1->tp_name);
1234#endif
1235 goto exit_binary_exception;
1236
1237exit_binary_result_object:
1238 return obj_result;
1239
1240exit_binary_exception:
1241 return NULL;
1242}
1243static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
1244 CHECK_OBJECT(operand1);
1245 CHECK_OBJECT(operand2);
1246 assert(PyLong_CheckExact(operand2));
1247
1248 PyTypeObject *type1 = Py_TYPE(operand1);
1249
1250 if (type1 == &PyLong_Type) {
1251 PyObject *result;
1252
1253 // return _BINARY_OPERATION_ADD_OBJECT_LONG_LONG(operand1, operand2);
1254
1255 // Not every code path will make use of all possible results.
1256#if defined(_MSC_VER)
1257#pragma warning(push)
1258#pragma warning(disable : 4101)
1259#endif
1260 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1261 NUITKA_MAY_BE_UNUSED long clong_result;
1262#if defined(_MSC_VER)
1263#pragma warning(pop)
1264#endif
1265
1266 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
1267
1268 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
1269
1270 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && Nuitka_LongGetDigitSize(operand2_long_object) <= 1) {
1271 long r = (long)(MEDIUM_VALUE(operand1_long_object) + MEDIUM_VALUE(operand2_long_object));
1272
1273 clong_result = r;
1274 goto exit_result_ok_clong;
1275 }
1276
1277 {
1278 PyLongObject *z;
1279
1280 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
1281 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
1282 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
1283 digit const *b_digits = Nuitka_LongGetDigitPointer(operand2_long_object);
1284 Py_ssize_t b_digit_count = Nuitka_LongGetDigitSize(operand2_long_object);
1285 bool b_negative = Nuitka_LongIsNegative(operand2_long_object);
1286
1287 if (a_negative) {
1288 if (b_negative) {
1289 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1290 Nuitka_LongFlipSign(z);
1291 } else {
1292 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
1293 }
1294 } else {
1295 if (b_negative) {
1296 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1297 } else {
1298 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1299 }
1300 }
1301
1302 obj_result = (PyObject *)z;
1303 goto exit_result_object;
1304 }
1305
1306 exit_result_object:
1307 if (unlikely(obj_result == NULL)) {
1308 goto exit_result_exception;
1309 }
1310 result = obj_result;
1311 goto exit_result_ok;
1312
1313 exit_result_ok_clong:
1314 result = Nuitka_LongFromCLong(clong_result);
1315 goto exit_result_ok;
1316
1317 exit_result_ok:
1318 return result;
1319
1320 exit_result_exception:
1321 return NULL;
1322 }
1323
1324 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_LONG(operand1, operand2);
1325}
1326
1327PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
1328 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_LONG(operand1, operand2);
1329}
1330
1331/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
1332static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
1333 PyTypeObject *type2 = Py_TYPE(operand2);
1334
1335#if defined(_MSC_VER)
1336#pragma warning(push)
1337#pragma warning(disable : 4101)
1338#endif
1339 NUITKA_MAY_BE_UNUSED bool cbool_result;
1340 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1341#if defined(_MSC_VER)
1342#pragma warning(pop)
1343#endif
1344
1345 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_add;
1346 binaryfunc slot2 = NULL;
1347
1348 if (!(&PyLong_Type == type2)) {
1349 // Different types, need to consider second value slot.
1350
1351 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
1352
1353 if (slot1 == slot2) {
1354 slot2 = NULL;
1355 }
1356 }
1357
1358 if (slot1 != NULL) {
1359 if (slot2 != NULL) {
1360 if (Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
1361 PyObject *x = slot2(operand1, operand2);
1362
1363 if (x != Py_NotImplemented) {
1364 obj_result = x;
1365 goto exit_binary_result_object;
1366 }
1367
1368 Py_DECREF_IMMORTAL(x);
1369 slot2 = NULL;
1370 }
1371 }
1372
1373 PyObject *x = slot1(operand1, operand2);
1374
1375 if (x != Py_NotImplemented) {
1376 obj_result = x;
1377 goto exit_binary_result_object;
1378 }
1379
1380 Py_DECREF_IMMORTAL(x);
1381 }
1382
1383 if (slot2 != NULL) {
1384 PyObject *x = slot2(operand1, operand2);
1385
1386 if (x != Py_NotImplemented) {
1387 obj_result = x;
1388 goto exit_binary_result_object;
1389 }
1390
1391 Py_DECREF_IMMORTAL(x);
1392 }
1393
1394#if PYTHON_VERSION < 0x300
1395 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
1396 coercion c1 = PyLong_Type.tp_as_number->nb_coerce;
1397
1398 if (c1 != NULL) {
1399 PyObject *coerced1 = operand1;
1400 PyObject *coerced2 = operand2;
1401
1402 int err = c1(&coerced1, &coerced2);
1403
1404 if (unlikely(err < 0)) {
1405 goto exit_binary_exception;
1406 }
1407
1408 if (err == 0) {
1409 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1410
1411 if (likely(mv == NULL)) {
1412 binaryfunc slot = mv->nb_add;
1413
1414 if (likely(slot != NULL)) {
1415 PyObject *x = slot(coerced1, coerced2);
1416
1417 Py_DECREF(coerced1);
1418 Py_DECREF(coerced2);
1419
1420 obj_result = x;
1421 goto exit_binary_result_object;
1422 }
1423 }
1424
1425 // nb_coerce took a reference.
1426 Py_DECREF(coerced1);
1427 Py_DECREF(coerced2);
1428 }
1429 }
1430 coercion c2 =
1431 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1432
1433 if (c2 != NULL) {
1434 PyObject *coerced1 = operand1;
1435 PyObject *coerced2 = operand2;
1436
1437 int err = c2(&coerced2, &coerced1);
1438
1439 if (unlikely(err < 0)) {
1440 goto exit_binary_exception;
1441 }
1442
1443 if (err == 0) {
1444 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1445
1446 if (likely(mv == NULL)) {
1447 binaryfunc slot = mv->nb_add;
1448
1449 if (likely(slot != NULL)) {
1450 PyObject *x = slot(coerced1, coerced2);
1451
1452 Py_DECREF(coerced1);
1453 Py_DECREF(coerced2);
1454
1455 obj_result = x;
1456 goto exit_binary_result_object;
1457 }
1458 }
1459
1460 // nb_coerce took a reference.
1461 Py_DECREF(coerced1);
1462 Py_DECREF(coerced2);
1463 }
1464 }
1465 }
1466#endif
1467
1468 {
1469 // No sequence repeat slot sq_concat available for this type.
1470 }
1471
1472#if PYTHON_VERSION < 0x300
1473 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and '%s'", type2->tp_name);
1474#else
1475 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and '%s'", type2->tp_name);
1476#endif
1477 goto exit_binary_exception;
1478
1479exit_binary_result_object:
1480 return obj_result;
1481
1482exit_binary_exception:
1483 return NULL;
1484}
1485static PyObject *_BINARY_OPERATION_ADD_OBJECT_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
1486 CHECK_OBJECT(operand1);
1487 assert(PyLong_CheckExact(operand1));
1488 CHECK_OBJECT(operand2);
1489
1490 PyTypeObject *type2 = Py_TYPE(operand2);
1491
1492 if (&PyLong_Type == type2) {
1493 PyObject *result;
1494
1495 // return _BINARY_OPERATION_ADD_OBJECT_LONG_LONG(operand1, operand2);
1496
1497 // Not every code path will make use of all possible results.
1498#if defined(_MSC_VER)
1499#pragma warning(push)
1500#pragma warning(disable : 4101)
1501#endif
1502 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1503 NUITKA_MAY_BE_UNUSED long clong_result;
1504#if defined(_MSC_VER)
1505#pragma warning(pop)
1506#endif
1507
1508 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
1509
1510 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
1511
1512 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && Nuitka_LongGetDigitSize(operand2_long_object) <= 1) {
1513 long r = (long)(MEDIUM_VALUE(operand1_long_object) + MEDIUM_VALUE(operand2_long_object));
1514
1515 clong_result = r;
1516 goto exit_result_ok_clong;
1517 }
1518
1519 {
1520 PyLongObject *z;
1521
1522 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
1523 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
1524 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
1525 digit const *b_digits = Nuitka_LongGetDigitPointer(operand2_long_object);
1526 Py_ssize_t b_digit_count = Nuitka_LongGetDigitSize(operand2_long_object);
1527 bool b_negative = Nuitka_LongIsNegative(operand2_long_object);
1528
1529 if (a_negative) {
1530 if (b_negative) {
1531 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1532 Nuitka_LongFlipSign(z);
1533 } else {
1534 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
1535 }
1536 } else {
1537 if (b_negative) {
1538 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1539 } else {
1540 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1541 }
1542 }
1543
1544 obj_result = (PyObject *)z;
1545 goto exit_result_object;
1546 }
1547
1548 exit_result_object:
1549 if (unlikely(obj_result == NULL)) {
1550 goto exit_result_exception;
1551 }
1552 result = obj_result;
1553 goto exit_result_ok;
1554
1555 exit_result_ok_clong:
1556 result = Nuitka_LongFromCLong(clong_result);
1557 goto exit_result_ok;
1558
1559 exit_result_ok:
1560 return result;
1561
1562 exit_result_exception:
1563 return NULL;
1564 }
1565
1566 return __BINARY_OPERATION_ADD_OBJECT_LONG_OBJECT(operand1, operand2);
1567}
1568
1569PyObject *BINARY_OPERATION_ADD_OBJECT_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
1570 return _BINARY_OPERATION_ADD_OBJECT_LONG_OBJECT(operand1, operand2);
1571}
1572
1573/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "LONG" to Python2 'long', Python3 'int'. */
1574static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LONG_LONG(PyObject *operand1, PyObject *operand2) {
1575 CHECK_OBJECT(operand1);
1576 assert(PyLong_CheckExact(operand1));
1577 CHECK_OBJECT(operand2);
1578 assert(PyLong_CheckExact(operand2));
1579
1580 nuitka_bool result;
1581
1582 // Not every code path will make use of all possible results.
1583#if defined(_MSC_VER)
1584#pragma warning(push)
1585#pragma warning(disable : 4101)
1586#endif
1587 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1588 NUITKA_MAY_BE_UNUSED long clong_result;
1589#if defined(_MSC_VER)
1590#pragma warning(pop)
1591#endif
1592
1593 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
1594
1595 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
1596
1597 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && Nuitka_LongGetDigitSize(operand2_long_object) <= 1) {
1598 long r = (long)(MEDIUM_VALUE(operand1_long_object) + MEDIUM_VALUE(operand2_long_object));
1599
1600 clong_result = r;
1601 goto exit_result_ok_clong;
1602 }
1603
1604 {
1605 PyLongObject *z;
1606
1607 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
1608 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
1609 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
1610 digit const *b_digits = Nuitka_LongGetDigitPointer(operand2_long_object);
1611 Py_ssize_t b_digit_count = Nuitka_LongGetDigitSize(operand2_long_object);
1612 bool b_negative = Nuitka_LongIsNegative(operand2_long_object);
1613
1614 if (a_negative) {
1615 if (b_negative) {
1616 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1617 Nuitka_LongFlipSign(z);
1618 } else {
1619 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
1620 }
1621 } else {
1622 if (b_negative) {
1623 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1624 } else {
1625 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1626 }
1627 }
1628
1629 obj_result = (PyObject *)z;
1630 goto exit_result_object;
1631 }
1632
1633exit_result_object:
1634 if (unlikely(obj_result == NULL)) {
1635 goto exit_result_exception;
1636 }
1637 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1638 Py_DECREF(obj_result);
1639 goto exit_result_ok;
1640
1641exit_result_ok_clong:
1642 result = clong_result != 0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1643 goto exit_result_ok;
1644
1645exit_result_ok:
1646 return result;
1647
1648exit_result_exception:
1649 return NUITKA_BOOL_EXCEPTION;
1650}
1651
1652nuitka_bool BINARY_OPERATION_ADD_NBOOL_LONG_LONG(PyObject *operand1, PyObject *operand2) {
1653 return _BINARY_OPERATION_ADD_NBOOL_LONG_LONG(operand1, operand2);
1654}
1655
1656/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
1657static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_OBJECT_LONG(PyObject *operand1,
1658 PyObject *operand2) {
1659 PyTypeObject *type1 = Py_TYPE(operand1);
1660
1661#if defined(_MSC_VER)
1662#pragma warning(push)
1663#pragma warning(disable : 4101)
1664#endif
1665 NUITKA_MAY_BE_UNUSED bool cbool_result;
1666 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1667#if defined(_MSC_VER)
1668#pragma warning(pop)
1669#endif
1670
1671 binaryfunc slot1 =
1672 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
1673 binaryfunc slot2 = NULL;
1674
1675 if (!(type1 == &PyLong_Type)) {
1676 // Different types, need to consider second value slot.
1677
1678 slot2 = PyLong_Type.tp_as_number->nb_add;
1679
1680 if (slot1 == slot2) {
1681 slot2 = NULL;
1682 }
1683 }
1684
1685 if (slot1 != NULL) {
1686 PyObject *x = slot1(operand1, operand2);
1687
1688 if (x != Py_NotImplemented) {
1689 obj_result = x;
1690 goto exit_binary_result_object;
1691 }
1692
1693 Py_DECREF_IMMORTAL(x);
1694 }
1695
1696 if (slot2 != NULL) {
1697 PyObject *x = slot2(operand1, operand2);
1698
1699 if (x != Py_NotImplemented) {
1700 obj_result = x;
1701 goto exit_binary_result_object;
1702 }
1703
1704 Py_DECREF_IMMORTAL(x);
1705 }
1706
1707#if PYTHON_VERSION < 0x300
1708 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
1709 coercion c1 =
1710 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1711
1712 if (c1 != NULL) {
1713 PyObject *coerced1 = operand1;
1714 PyObject *coerced2 = operand2;
1715
1716 int err = c1(&coerced1, &coerced2);
1717
1718 if (unlikely(err < 0)) {
1719 goto exit_binary_exception;
1720 }
1721
1722 if (err == 0) {
1723 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1724
1725 if (likely(mv == NULL)) {
1726 binaryfunc slot = mv->nb_add;
1727
1728 if (likely(slot != NULL)) {
1729 PyObject *x = slot(coerced1, coerced2);
1730
1731 Py_DECREF(coerced1);
1732 Py_DECREF(coerced2);
1733
1734 obj_result = x;
1735 goto exit_binary_result_object;
1736 }
1737 }
1738
1739 // nb_coerce took a reference.
1740 Py_DECREF(coerced1);
1741 Py_DECREF(coerced2);
1742 }
1743 }
1744 coercion c2 = PyLong_Type.tp_as_number->nb_coerce;
1745
1746 if (c2 != NULL) {
1747 PyObject *coerced1 = operand1;
1748 PyObject *coerced2 = operand2;
1749
1750 int err = c2(&coerced2, &coerced1);
1751
1752 if (unlikely(err < 0)) {
1753 goto exit_binary_exception;
1754 }
1755
1756 if (err == 0) {
1757 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1758
1759 if (likely(mv == NULL)) {
1760 binaryfunc slot = mv->nb_add;
1761
1762 if (likely(slot != NULL)) {
1763 PyObject *x = slot(coerced1, coerced2);
1764
1765 Py_DECREF(coerced1);
1766 Py_DECREF(coerced2);
1767
1768 obj_result = x;
1769 goto exit_binary_result_object;
1770 }
1771 }
1772
1773 // nb_coerce took a reference.
1774 Py_DECREF(coerced1);
1775 Py_DECREF(coerced2);
1776 }
1777 }
1778 }
1779#endif
1780
1781 {
1782 // Special case for "+" and "*", also works as sequence concat/repeat.
1783 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
1784
1785 if (sq_slot != NULL) {
1786 PyObject *result = sq_slot(operand1, operand2);
1787
1788 obj_result = result;
1789 goto exit_binary_result_object;
1790 }
1791 }
1792
1793#if PYTHON_VERSION < 0x300
1794 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'long'", type1->tp_name);
1795#else
1796 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'int'", type1->tp_name);
1797#endif
1798 goto exit_binary_exception;
1799
1800exit_binary_result_object:
1801 if (unlikely(obj_result == NULL)) {
1802 return NUITKA_BOOL_EXCEPTION;
1803 }
1804
1805 {
1806 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1807 Py_DECREF(obj_result);
1808 return r;
1809 }
1810
1811exit_binary_exception:
1812 return NUITKA_BOOL_EXCEPTION;
1813}
1814static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
1815 CHECK_OBJECT(operand1);
1816 CHECK_OBJECT(operand2);
1817 assert(PyLong_CheckExact(operand2));
1818
1819 PyTypeObject *type1 = Py_TYPE(operand1);
1820
1821 if (type1 == &PyLong_Type) {
1822 nuitka_bool result;
1823
1824 // return _BINARY_OPERATION_ADD_NBOOL_LONG_LONG(operand1, operand2);
1825
1826 // Not every code path will make use of all possible results.
1827#if defined(_MSC_VER)
1828#pragma warning(push)
1829#pragma warning(disable : 4101)
1830#endif
1831 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1832 NUITKA_MAY_BE_UNUSED long clong_result;
1833#if defined(_MSC_VER)
1834#pragma warning(pop)
1835#endif
1836
1837 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
1838
1839 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
1840
1841 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && Nuitka_LongGetDigitSize(operand2_long_object) <= 1) {
1842 long r = (long)(MEDIUM_VALUE(operand1_long_object) + MEDIUM_VALUE(operand2_long_object));
1843
1844 clong_result = r;
1845 goto exit_result_ok_clong;
1846 }
1847
1848 {
1849 PyLongObject *z;
1850
1851 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
1852 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
1853 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
1854 digit const *b_digits = Nuitka_LongGetDigitPointer(operand2_long_object);
1855 Py_ssize_t b_digit_count = Nuitka_LongGetDigitSize(operand2_long_object);
1856 bool b_negative = Nuitka_LongIsNegative(operand2_long_object);
1857
1858 if (a_negative) {
1859 if (b_negative) {
1860 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1861 Nuitka_LongFlipSign(z);
1862 } else {
1863 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
1864 }
1865 } else {
1866 if (b_negative) {
1867 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1868 } else {
1869 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
1870 }
1871 }
1872
1873 obj_result = (PyObject *)z;
1874 goto exit_result_object;
1875 }
1876
1877 exit_result_object:
1878 if (unlikely(obj_result == NULL)) {
1879 goto exit_result_exception;
1880 }
1881 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1882 Py_DECREF(obj_result);
1883 goto exit_result_ok;
1884
1885 exit_result_ok_clong:
1886 result = clong_result != 0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1887 goto exit_result_ok;
1888
1889 exit_result_ok:
1890 return result;
1891
1892 exit_result_exception:
1893 return NUITKA_BOOL_EXCEPTION;
1894 }
1895
1896 return __BINARY_OPERATION_ADD_NBOOL_OBJECT_LONG(operand1, operand2);
1897}
1898
1899nuitka_bool BINARY_OPERATION_ADD_NBOOL_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
1900 return _BINARY_OPERATION_ADD_NBOOL_OBJECT_LONG(operand1, operand2);
1901}
1902
1903/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
1904static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_LONG_OBJECT(PyObject *operand1,
1905 PyObject *operand2) {
1906 PyTypeObject *type2 = Py_TYPE(operand2);
1907
1908#if defined(_MSC_VER)
1909#pragma warning(push)
1910#pragma warning(disable : 4101)
1911#endif
1912 NUITKA_MAY_BE_UNUSED bool cbool_result;
1913 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1914#if defined(_MSC_VER)
1915#pragma warning(pop)
1916#endif
1917
1918 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_add;
1919 binaryfunc slot2 = NULL;
1920
1921 if (!(&PyLong_Type == type2)) {
1922 // Different types, need to consider second value slot.
1923
1924 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
1925
1926 if (slot1 == slot2) {
1927 slot2 = NULL;
1928 }
1929 }
1930
1931 if (slot1 != NULL) {
1932 if (slot2 != NULL) {
1933 if (Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
1934 PyObject *x = slot2(operand1, operand2);
1935
1936 if (x != Py_NotImplemented) {
1937 obj_result = x;
1938 goto exit_binary_result_object;
1939 }
1940
1941 Py_DECREF_IMMORTAL(x);
1942 slot2 = NULL;
1943 }
1944 }
1945
1946 PyObject *x = slot1(operand1, operand2);
1947
1948 if (x != Py_NotImplemented) {
1949 obj_result = x;
1950 goto exit_binary_result_object;
1951 }
1952
1953 Py_DECREF_IMMORTAL(x);
1954 }
1955
1956 if (slot2 != NULL) {
1957 PyObject *x = slot2(operand1, operand2);
1958
1959 if (x != Py_NotImplemented) {
1960 obj_result = x;
1961 goto exit_binary_result_object;
1962 }
1963
1964 Py_DECREF_IMMORTAL(x);
1965 }
1966
1967#if PYTHON_VERSION < 0x300
1968 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
1969 coercion c1 = PyLong_Type.tp_as_number->nb_coerce;
1970
1971 if (c1 != NULL) {
1972 PyObject *coerced1 = operand1;
1973 PyObject *coerced2 = operand2;
1974
1975 int err = c1(&coerced1, &coerced2);
1976
1977 if (unlikely(err < 0)) {
1978 goto exit_binary_exception;
1979 }
1980
1981 if (err == 0) {
1982 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1983
1984 if (likely(mv == NULL)) {
1985 binaryfunc slot = mv->nb_add;
1986
1987 if (likely(slot != NULL)) {
1988 PyObject *x = slot(coerced1, coerced2);
1989
1990 Py_DECREF(coerced1);
1991 Py_DECREF(coerced2);
1992
1993 obj_result = x;
1994 goto exit_binary_result_object;
1995 }
1996 }
1997
1998 // nb_coerce took a reference.
1999 Py_DECREF(coerced1);
2000 Py_DECREF(coerced2);
2001 }
2002 }
2003 coercion c2 =
2004 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
2005
2006 if (c2 != NULL) {
2007 PyObject *coerced1 = operand1;
2008 PyObject *coerced2 = operand2;
2009
2010 int err = c2(&coerced2, &coerced1);
2011
2012 if (unlikely(err < 0)) {
2013 goto exit_binary_exception;
2014 }
2015
2016 if (err == 0) {
2017 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2018
2019 if (likely(mv == NULL)) {
2020 binaryfunc slot = mv->nb_add;
2021
2022 if (likely(slot != NULL)) {
2023 PyObject *x = slot(coerced1, coerced2);
2024
2025 Py_DECREF(coerced1);
2026 Py_DECREF(coerced2);
2027
2028 obj_result = x;
2029 goto exit_binary_result_object;
2030 }
2031 }
2032
2033 // nb_coerce took a reference.
2034 Py_DECREF(coerced1);
2035 Py_DECREF(coerced2);
2036 }
2037 }
2038 }
2039#endif
2040
2041 {
2042 // No sequence repeat slot sq_concat available for this type.
2043 }
2044
2045#if PYTHON_VERSION < 0x300
2046 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and '%s'", type2->tp_name);
2047#else
2048 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'int' and '%s'", type2->tp_name);
2049#endif
2050 goto exit_binary_exception;
2051
2052exit_binary_result_object:
2053 if (unlikely(obj_result == NULL)) {
2054 return NUITKA_BOOL_EXCEPTION;
2055 }
2056
2057 {
2058 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2059 Py_DECREF(obj_result);
2060 return r;
2061 }
2062
2063exit_binary_exception:
2064 return NUITKA_BOOL_EXCEPTION;
2065}
2066static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
2067 CHECK_OBJECT(operand1);
2068 assert(PyLong_CheckExact(operand1));
2069 CHECK_OBJECT(operand2);
2070
2071 PyTypeObject *type2 = Py_TYPE(operand2);
2072
2073 if (&PyLong_Type == type2) {
2074 nuitka_bool result;
2075
2076 // return _BINARY_OPERATION_ADD_NBOOL_LONG_LONG(operand1, operand2);
2077
2078 // Not every code path will make use of all possible results.
2079#if defined(_MSC_VER)
2080#pragma warning(push)
2081#pragma warning(disable : 4101)
2082#endif
2083 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2084 NUITKA_MAY_BE_UNUSED long clong_result;
2085#if defined(_MSC_VER)
2086#pragma warning(pop)
2087#endif
2088
2089 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
2090
2091 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
2092
2093 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && Nuitka_LongGetDigitSize(operand2_long_object) <= 1) {
2094 long r = (long)(MEDIUM_VALUE(operand1_long_object) + MEDIUM_VALUE(operand2_long_object));
2095
2096 clong_result = r;
2097 goto exit_result_ok_clong;
2098 }
2099
2100 {
2101 PyLongObject *z;
2102
2103 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
2104 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
2105 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
2106 digit const *b_digits = Nuitka_LongGetDigitPointer(operand2_long_object);
2107 Py_ssize_t b_digit_count = Nuitka_LongGetDigitSize(operand2_long_object);
2108 bool b_negative = Nuitka_LongIsNegative(operand2_long_object);
2109
2110 if (a_negative) {
2111 if (b_negative) {
2112 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
2113 Nuitka_LongFlipSign(z);
2114 } else {
2115 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
2116 }
2117 } else {
2118 if (b_negative) {
2119 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
2120 } else {
2121 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
2122 }
2123 }
2124
2125 obj_result = (PyObject *)z;
2126 goto exit_result_object;
2127 }
2128
2129 exit_result_object:
2130 if (unlikely(obj_result == NULL)) {
2131 goto exit_result_exception;
2132 }
2133 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2134 Py_DECREF(obj_result);
2135 goto exit_result_ok;
2136
2137 exit_result_ok_clong:
2138 result = clong_result != 0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2139 goto exit_result_ok;
2140
2141 exit_result_ok:
2142 return result;
2143
2144 exit_result_exception:
2145 return NUITKA_BOOL_EXCEPTION;
2146 }
2147
2148 return __BINARY_OPERATION_ADD_NBOOL_LONG_OBJECT(operand1, operand2);
2149}
2150
2151nuitka_bool BINARY_OPERATION_ADD_NBOOL_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
2152 return _BINARY_OPERATION_ADD_NBOOL_LONG_OBJECT(operand1, operand2);
2153}
2154
2155/* Code referring to "FLOAT" corresponds to Python 'float' and "FLOAT" to Python 'float'. */
2156static PyObject *_BINARY_OPERATION_ADD_OBJECT_FLOAT_FLOAT(PyObject *operand1, PyObject *operand2) {
2157 CHECK_OBJECT(operand1);
2158 assert(PyFloat_CheckExact(operand1));
2159 CHECK_OBJECT(operand2);
2160 assert(PyFloat_CheckExact(operand2));
2161
2162 PyObject *result;
2163
2164#if defined(_MSC_VER)
2165#pragma warning(push)
2166#pragma warning(disable : 4101)
2167#endif
2168 // Not every code path will make use of all possible results.
2169 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2170 NUITKA_MAY_BE_UNUSED long clong_result;
2171 NUITKA_MAY_BE_UNUSED double cfloat_result;
2172#if defined(_MSC_VER)
2173#pragma warning(pop)
2174#endif
2175
2176 CHECK_OBJECT(operand1);
2177 assert(PyFloat_CheckExact(operand1));
2178 CHECK_OBJECT(operand2);
2179 assert(PyFloat_CheckExact(operand2));
2180
2181 const double a = PyFloat_AS_DOUBLE(operand1);
2182 const double b = PyFloat_AS_DOUBLE(operand2);
2183
2184 double r = a + b;
2185
2186 cfloat_result = r;
2187 goto exit_result_ok_cfloat;
2188
2189exit_result_ok_cfloat:
2190 result = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
2191 goto exit_result_ok;
2192
2193exit_result_ok:
2194 return result;
2195}
2196
2197PyObject *BINARY_OPERATION_ADD_OBJECT_FLOAT_FLOAT(PyObject *operand1, PyObject *operand2) {
2198 return _BINARY_OPERATION_ADD_OBJECT_FLOAT_FLOAT(operand1, operand2);
2199}
2200
2201/* Code referring to "OBJECT" corresponds to any Python object and "FLOAT" to Python 'float'. */
2202static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_FLOAT(PyObject *operand1,
2203 PyObject *operand2) {
2204 PyTypeObject *type1 = Py_TYPE(operand1);
2205
2206#if defined(_MSC_VER)
2207#pragma warning(push)
2208#pragma warning(disable : 4101)
2209#endif
2210 NUITKA_MAY_BE_UNUSED bool cbool_result;
2211 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2212#if defined(_MSC_VER)
2213#pragma warning(pop)
2214#endif
2215
2216 binaryfunc slot1 =
2217 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
2218 binaryfunc slot2 = NULL;
2219
2220 if (!(type1 == &PyFloat_Type)) {
2221 // Different types, need to consider second value slot.
2222
2223 slot2 = PyFloat_Type.tp_as_number->nb_add;
2224
2225 if (slot1 == slot2) {
2226 slot2 = NULL;
2227 }
2228 }
2229
2230 if (slot1 != NULL) {
2231 PyObject *x = slot1(operand1, operand2);
2232
2233 if (x != Py_NotImplemented) {
2234 obj_result = x;
2235 goto exit_binary_result_object;
2236 }
2237
2238 Py_DECREF_IMMORTAL(x);
2239 }
2240
2241 if (slot2 != NULL) {
2242 PyObject *x = slot2(operand1, operand2);
2243
2244 if (x != Py_NotImplemented) {
2245 obj_result = x;
2246 goto exit_binary_result_object;
2247 }
2248
2249 Py_DECREF_IMMORTAL(x);
2250 }
2251
2252#if PYTHON_VERSION < 0x300
2253 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
2254 coercion c1 =
2255 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
2256
2257 if (c1 != NULL) {
2258 PyObject *coerced1 = operand1;
2259 PyObject *coerced2 = operand2;
2260
2261 int err = c1(&coerced1, &coerced2);
2262
2263 if (unlikely(err < 0)) {
2264 goto exit_binary_exception;
2265 }
2266
2267 if (err == 0) {
2268 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2269
2270 if (likely(mv == NULL)) {
2271 binaryfunc slot = mv->nb_add;
2272
2273 if (likely(slot != NULL)) {
2274 PyObject *x = slot(coerced1, coerced2);
2275
2276 Py_DECREF(coerced1);
2277 Py_DECREF(coerced2);
2278
2279 obj_result = x;
2280 goto exit_binary_result_object;
2281 }
2282 }
2283
2284 // nb_coerce took a reference.
2285 Py_DECREF(coerced1);
2286 Py_DECREF(coerced2);
2287 }
2288 }
2289 coercion c2 = PyFloat_Type.tp_as_number->nb_coerce;
2290
2291 if (c2 != NULL) {
2292 PyObject *coerced1 = operand1;
2293 PyObject *coerced2 = operand2;
2294
2295 int err = c2(&coerced2, &coerced1);
2296
2297 if (unlikely(err < 0)) {
2298 goto exit_binary_exception;
2299 }
2300
2301 if (err == 0) {
2302 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2303
2304 if (likely(mv == NULL)) {
2305 binaryfunc slot = mv->nb_add;
2306
2307 if (likely(slot != NULL)) {
2308 PyObject *x = slot(coerced1, coerced2);
2309
2310 Py_DECREF(coerced1);
2311 Py_DECREF(coerced2);
2312
2313 obj_result = x;
2314 goto exit_binary_result_object;
2315 }
2316 }
2317
2318 // nb_coerce took a reference.
2319 Py_DECREF(coerced1);
2320 Py_DECREF(coerced2);
2321 }
2322 }
2323 }
2324#endif
2325
2326 {
2327 // Special case for "+" and "*", also works as sequence concat/repeat.
2328 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
2329
2330 if (sq_slot != NULL) {
2331 PyObject *result = sq_slot(operand1, operand2);
2332
2333 obj_result = result;
2334 goto exit_binary_result_object;
2335 }
2336 }
2337
2338 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'float'", type1->tp_name);
2339 goto exit_binary_exception;
2340
2341exit_binary_result_object:
2342 return obj_result;
2343
2344exit_binary_exception:
2345 return NULL;
2346}
2347static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_FLOAT(PyObject *operand1, PyObject *operand2) {
2348 CHECK_OBJECT(operand1);
2349 CHECK_OBJECT(operand2);
2350 assert(PyFloat_CheckExact(operand2));
2351
2352 PyTypeObject *type1 = Py_TYPE(operand1);
2353
2354 if (type1 == &PyFloat_Type) {
2355 PyObject *result;
2356
2357 // return _BINARY_OPERATION_ADD_OBJECT_FLOAT_FLOAT(operand1, operand2);
2358
2359#if defined(_MSC_VER)
2360#pragma warning(push)
2361#pragma warning(disable : 4101)
2362#endif
2363 // Not every code path will make use of all possible results.
2364 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2365 NUITKA_MAY_BE_UNUSED long clong_result;
2366 NUITKA_MAY_BE_UNUSED double cfloat_result;
2367#if defined(_MSC_VER)
2368#pragma warning(pop)
2369#endif
2370
2371 CHECK_OBJECT(operand1);
2372 assert(PyFloat_CheckExact(operand1));
2373 CHECK_OBJECT(operand2);
2374 assert(PyFloat_CheckExact(operand2));
2375
2376 const double a = PyFloat_AS_DOUBLE(operand1);
2377 const double b = PyFloat_AS_DOUBLE(operand2);
2378
2379 double r = a + b;
2380
2381 cfloat_result = r;
2382 goto exit_result_ok_cfloat;
2383
2384 exit_result_ok_cfloat:
2385 result = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
2386 goto exit_result_ok;
2387
2388 exit_result_ok:
2389 return result;
2390 }
2391
2392 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_FLOAT(operand1, operand2);
2393}
2394
2395PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_FLOAT(PyObject *operand1, PyObject *operand2) {
2396 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_FLOAT(operand1, operand2);
2397}
2398
2399/* Code referring to "FLOAT" corresponds to Python 'float' and "OBJECT" to any Python object. */
2400static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_FLOAT_OBJECT(PyObject *operand1,
2401 PyObject *operand2) {
2402 PyTypeObject *type2 = Py_TYPE(operand2);
2403
2404#if defined(_MSC_VER)
2405#pragma warning(push)
2406#pragma warning(disable : 4101)
2407#endif
2408 NUITKA_MAY_BE_UNUSED bool cbool_result;
2409 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2410#if defined(_MSC_VER)
2411#pragma warning(pop)
2412#endif
2413
2414 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_add;
2415 binaryfunc slot2 = NULL;
2416
2417 if (!(&PyFloat_Type == type2)) {
2418 // Different types, need to consider second value slot.
2419
2420 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
2421
2422 if (slot1 == slot2) {
2423 slot2 = NULL;
2424 }
2425 }
2426
2427 if (slot1 != NULL) {
2428 if (slot2 != NULL) {
2429 if (Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
2430 PyObject *x = slot2(operand1, operand2);
2431
2432 if (x != Py_NotImplemented) {
2433 obj_result = x;
2434 goto exit_binary_result_object;
2435 }
2436
2437 Py_DECREF_IMMORTAL(x);
2438 slot2 = NULL;
2439 }
2440 }
2441
2442 PyObject *x = slot1(operand1, operand2);
2443
2444 if (x != Py_NotImplemented) {
2445 obj_result = x;
2446 goto exit_binary_result_object;
2447 }
2448
2449 Py_DECREF_IMMORTAL(x);
2450 }
2451
2452 if (slot2 != NULL) {
2453 PyObject *x = slot2(operand1, operand2);
2454
2455 if (x != Py_NotImplemented) {
2456 obj_result = x;
2457 goto exit_binary_result_object;
2458 }
2459
2460 Py_DECREF_IMMORTAL(x);
2461 }
2462
2463#if PYTHON_VERSION < 0x300
2464 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
2465 coercion c1 = PyFloat_Type.tp_as_number->nb_coerce;
2466
2467 if (c1 != NULL) {
2468 PyObject *coerced1 = operand1;
2469 PyObject *coerced2 = operand2;
2470
2471 int err = c1(&coerced1, &coerced2);
2472
2473 if (unlikely(err < 0)) {
2474 goto exit_binary_exception;
2475 }
2476
2477 if (err == 0) {
2478 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2479
2480 if (likely(mv == NULL)) {
2481 binaryfunc slot = mv->nb_add;
2482
2483 if (likely(slot != NULL)) {
2484 PyObject *x = slot(coerced1, coerced2);
2485
2486 Py_DECREF(coerced1);
2487 Py_DECREF(coerced2);
2488
2489 obj_result = x;
2490 goto exit_binary_result_object;
2491 }
2492 }
2493
2494 // nb_coerce took a reference.
2495 Py_DECREF(coerced1);
2496 Py_DECREF(coerced2);
2497 }
2498 }
2499 coercion c2 =
2500 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
2501
2502 if (c2 != NULL) {
2503 PyObject *coerced1 = operand1;
2504 PyObject *coerced2 = operand2;
2505
2506 int err = c2(&coerced2, &coerced1);
2507
2508 if (unlikely(err < 0)) {
2509 goto exit_binary_exception;
2510 }
2511
2512 if (err == 0) {
2513 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2514
2515 if (likely(mv == NULL)) {
2516 binaryfunc slot = mv->nb_add;
2517
2518 if (likely(slot != NULL)) {
2519 PyObject *x = slot(coerced1, coerced2);
2520
2521 Py_DECREF(coerced1);
2522 Py_DECREF(coerced2);
2523
2524 obj_result = x;
2525 goto exit_binary_result_object;
2526 }
2527 }
2528
2529 // nb_coerce took a reference.
2530 Py_DECREF(coerced1);
2531 Py_DECREF(coerced2);
2532 }
2533 }
2534 }
2535#endif
2536
2537 {
2538 // No sequence repeat slot sq_concat available for this type.
2539 }
2540
2541 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and '%s'", type2->tp_name);
2542 goto exit_binary_exception;
2543
2544exit_binary_result_object:
2545 return obj_result;
2546
2547exit_binary_exception:
2548 return NULL;
2549}
2550static PyObject *_BINARY_OPERATION_ADD_OBJECT_FLOAT_OBJECT(PyObject *operand1, PyObject *operand2) {
2551 CHECK_OBJECT(operand1);
2552 assert(PyFloat_CheckExact(operand1));
2553 CHECK_OBJECT(operand2);
2554
2555 PyTypeObject *type2 = Py_TYPE(operand2);
2556
2557 if (&PyFloat_Type == type2) {
2558 PyObject *result;
2559
2560 // return _BINARY_OPERATION_ADD_OBJECT_FLOAT_FLOAT(operand1, operand2);
2561
2562#if defined(_MSC_VER)
2563#pragma warning(push)
2564#pragma warning(disable : 4101)
2565#endif
2566 // Not every code path will make use of all possible results.
2567 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2568 NUITKA_MAY_BE_UNUSED long clong_result;
2569 NUITKA_MAY_BE_UNUSED double cfloat_result;
2570#if defined(_MSC_VER)
2571#pragma warning(pop)
2572#endif
2573
2574 CHECK_OBJECT(operand1);
2575 assert(PyFloat_CheckExact(operand1));
2576 CHECK_OBJECT(operand2);
2577 assert(PyFloat_CheckExact(operand2));
2578
2579 const double a = PyFloat_AS_DOUBLE(operand1);
2580 const double b = PyFloat_AS_DOUBLE(operand2);
2581
2582 double r = a + b;
2583
2584 cfloat_result = r;
2585 goto exit_result_ok_cfloat;
2586
2587 exit_result_ok_cfloat:
2588 result = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
2589 goto exit_result_ok;
2590
2591 exit_result_ok:
2592 return result;
2593 }
2594
2595 return __BINARY_OPERATION_ADD_OBJECT_FLOAT_OBJECT(operand1, operand2);
2596}
2597
2598PyObject *BINARY_OPERATION_ADD_OBJECT_FLOAT_OBJECT(PyObject *operand1, PyObject *operand2) {
2599 return _BINARY_OPERATION_ADD_OBJECT_FLOAT_OBJECT(operand1, operand2);
2600}
2601
2602/* Code referring to "FLOAT" corresponds to Python 'float' and "FLOAT" to Python 'float'. */
2603static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_FLOAT_FLOAT(PyObject *operand1, PyObject *operand2) {
2604 CHECK_OBJECT(operand1);
2605 assert(PyFloat_CheckExact(operand1));
2606 CHECK_OBJECT(operand2);
2607 assert(PyFloat_CheckExact(operand2));
2608
2609 nuitka_bool result;
2610
2611#if defined(_MSC_VER)
2612#pragma warning(push)
2613#pragma warning(disable : 4101)
2614#endif
2615 // Not every code path will make use of all possible results.
2616 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2617 NUITKA_MAY_BE_UNUSED long clong_result;
2618 NUITKA_MAY_BE_UNUSED double cfloat_result;
2619#if defined(_MSC_VER)
2620#pragma warning(pop)
2621#endif
2622
2623 CHECK_OBJECT(operand1);
2624 assert(PyFloat_CheckExact(operand1));
2625 CHECK_OBJECT(operand2);
2626 assert(PyFloat_CheckExact(operand2));
2627
2628 const double a = PyFloat_AS_DOUBLE(operand1);
2629 const double b = PyFloat_AS_DOUBLE(operand2);
2630
2631 double r = a + b;
2632
2633 cfloat_result = r;
2634 goto exit_result_ok_cfloat;
2635
2636exit_result_ok_cfloat:
2637 result = cfloat_result != 0.0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2638 goto exit_result_ok;
2639
2640exit_result_ok:
2641 return result;
2642}
2643
2644nuitka_bool BINARY_OPERATION_ADD_NBOOL_FLOAT_FLOAT(PyObject *operand1, PyObject *operand2) {
2645 return _BINARY_OPERATION_ADD_NBOOL_FLOAT_FLOAT(operand1, operand2);
2646}
2647
2648/* Code referring to "OBJECT" corresponds to any Python object and "FLOAT" to Python 'float'. */
2649static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_OBJECT_FLOAT(PyObject *operand1,
2650 PyObject *operand2) {
2651 PyTypeObject *type1 = Py_TYPE(operand1);
2652
2653#if defined(_MSC_VER)
2654#pragma warning(push)
2655#pragma warning(disable : 4101)
2656#endif
2657 NUITKA_MAY_BE_UNUSED bool cbool_result;
2658 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2659#if defined(_MSC_VER)
2660#pragma warning(pop)
2661#endif
2662
2663 binaryfunc slot1 =
2664 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
2665 binaryfunc slot2 = NULL;
2666
2667 if (!(type1 == &PyFloat_Type)) {
2668 // Different types, need to consider second value slot.
2669
2670 slot2 = PyFloat_Type.tp_as_number->nb_add;
2671
2672 if (slot1 == slot2) {
2673 slot2 = NULL;
2674 }
2675 }
2676
2677 if (slot1 != NULL) {
2678 PyObject *x = slot1(operand1, operand2);
2679
2680 if (x != Py_NotImplemented) {
2681 obj_result = x;
2682 goto exit_binary_result_object;
2683 }
2684
2685 Py_DECREF_IMMORTAL(x);
2686 }
2687
2688 if (slot2 != NULL) {
2689 PyObject *x = slot2(operand1, operand2);
2690
2691 if (x != Py_NotImplemented) {
2692 obj_result = x;
2693 goto exit_binary_result_object;
2694 }
2695
2696 Py_DECREF_IMMORTAL(x);
2697 }
2698
2699#if PYTHON_VERSION < 0x300
2700 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
2701 coercion c1 =
2702 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
2703
2704 if (c1 != NULL) {
2705 PyObject *coerced1 = operand1;
2706 PyObject *coerced2 = operand2;
2707
2708 int err = c1(&coerced1, &coerced2);
2709
2710 if (unlikely(err < 0)) {
2711 goto exit_binary_exception;
2712 }
2713
2714 if (err == 0) {
2715 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2716
2717 if (likely(mv == NULL)) {
2718 binaryfunc slot = mv->nb_add;
2719
2720 if (likely(slot != NULL)) {
2721 PyObject *x = slot(coerced1, coerced2);
2722
2723 Py_DECREF(coerced1);
2724 Py_DECREF(coerced2);
2725
2726 obj_result = x;
2727 goto exit_binary_result_object;
2728 }
2729 }
2730
2731 // nb_coerce took a reference.
2732 Py_DECREF(coerced1);
2733 Py_DECREF(coerced2);
2734 }
2735 }
2736 coercion c2 = PyFloat_Type.tp_as_number->nb_coerce;
2737
2738 if (c2 != NULL) {
2739 PyObject *coerced1 = operand1;
2740 PyObject *coerced2 = operand2;
2741
2742 int err = c2(&coerced2, &coerced1);
2743
2744 if (unlikely(err < 0)) {
2745 goto exit_binary_exception;
2746 }
2747
2748 if (err == 0) {
2749 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2750
2751 if (likely(mv == NULL)) {
2752 binaryfunc slot = mv->nb_add;
2753
2754 if (likely(slot != NULL)) {
2755 PyObject *x = slot(coerced1, coerced2);
2756
2757 Py_DECREF(coerced1);
2758 Py_DECREF(coerced2);
2759
2760 obj_result = x;
2761 goto exit_binary_result_object;
2762 }
2763 }
2764
2765 // nb_coerce took a reference.
2766 Py_DECREF(coerced1);
2767 Py_DECREF(coerced2);
2768 }
2769 }
2770 }
2771#endif
2772
2773 {
2774 // Special case for "+" and "*", also works as sequence concat/repeat.
2775 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
2776
2777 if (sq_slot != NULL) {
2778 PyObject *result = sq_slot(operand1, operand2);
2779
2780 obj_result = result;
2781 goto exit_binary_result_object;
2782 }
2783 }
2784
2785 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'float'", type1->tp_name);
2786 goto exit_binary_exception;
2787
2788exit_binary_result_object:
2789 if (unlikely(obj_result == NULL)) {
2790 return NUITKA_BOOL_EXCEPTION;
2791 }
2792
2793 {
2794 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2795 Py_DECREF(obj_result);
2796 return r;
2797 }
2798
2799exit_binary_exception:
2800 return NUITKA_BOOL_EXCEPTION;
2801}
2802static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_OBJECT_FLOAT(PyObject *operand1, PyObject *operand2) {
2803 CHECK_OBJECT(operand1);
2804 CHECK_OBJECT(operand2);
2805 assert(PyFloat_CheckExact(operand2));
2806
2807 PyTypeObject *type1 = Py_TYPE(operand1);
2808
2809 if (type1 == &PyFloat_Type) {
2810 nuitka_bool result;
2811
2812 // return _BINARY_OPERATION_ADD_NBOOL_FLOAT_FLOAT(operand1, operand2);
2813
2814#if defined(_MSC_VER)
2815#pragma warning(push)
2816#pragma warning(disable : 4101)
2817#endif
2818 // Not every code path will make use of all possible results.
2819 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2820 NUITKA_MAY_BE_UNUSED long clong_result;
2821 NUITKA_MAY_BE_UNUSED double cfloat_result;
2822#if defined(_MSC_VER)
2823#pragma warning(pop)
2824#endif
2825
2826 CHECK_OBJECT(operand1);
2827 assert(PyFloat_CheckExact(operand1));
2828 CHECK_OBJECT(operand2);
2829 assert(PyFloat_CheckExact(operand2));
2830
2831 const double a = PyFloat_AS_DOUBLE(operand1);
2832 const double b = PyFloat_AS_DOUBLE(operand2);
2833
2834 double r = a + b;
2835
2836 cfloat_result = r;
2837 goto exit_result_ok_cfloat;
2838
2839 exit_result_ok_cfloat:
2840 result = cfloat_result != 0.0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2841 goto exit_result_ok;
2842
2843 exit_result_ok:
2844 return result;
2845 }
2846
2847 return __BINARY_OPERATION_ADD_NBOOL_OBJECT_FLOAT(operand1, operand2);
2848}
2849
2850nuitka_bool BINARY_OPERATION_ADD_NBOOL_OBJECT_FLOAT(PyObject *operand1, PyObject *operand2) {
2851 return _BINARY_OPERATION_ADD_NBOOL_OBJECT_FLOAT(operand1, operand2);
2852}
2853
2854/* Code referring to "FLOAT" corresponds to Python 'float' and "OBJECT" to any Python object. */
2855static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_FLOAT_OBJECT(PyObject *operand1,
2856 PyObject *operand2) {
2857 PyTypeObject *type2 = Py_TYPE(operand2);
2858
2859#if defined(_MSC_VER)
2860#pragma warning(push)
2861#pragma warning(disable : 4101)
2862#endif
2863 NUITKA_MAY_BE_UNUSED bool cbool_result;
2864 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2865#if defined(_MSC_VER)
2866#pragma warning(pop)
2867#endif
2868
2869 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_add;
2870 binaryfunc slot2 = NULL;
2871
2872 if (!(&PyFloat_Type == type2)) {
2873 // Different types, need to consider second value slot.
2874
2875 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
2876
2877 if (slot1 == slot2) {
2878 slot2 = NULL;
2879 }
2880 }
2881
2882 if (slot1 != NULL) {
2883 if (slot2 != NULL) {
2884 if (Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
2885 PyObject *x = slot2(operand1, operand2);
2886
2887 if (x != Py_NotImplemented) {
2888 obj_result = x;
2889 goto exit_binary_result_object;
2890 }
2891
2892 Py_DECREF_IMMORTAL(x);
2893 slot2 = NULL;
2894 }
2895 }
2896
2897 PyObject *x = slot1(operand1, operand2);
2898
2899 if (x != Py_NotImplemented) {
2900 obj_result = x;
2901 goto exit_binary_result_object;
2902 }
2903
2904 Py_DECREF_IMMORTAL(x);
2905 }
2906
2907 if (slot2 != NULL) {
2908 PyObject *x = slot2(operand1, operand2);
2909
2910 if (x != Py_NotImplemented) {
2911 obj_result = x;
2912 goto exit_binary_result_object;
2913 }
2914
2915 Py_DECREF_IMMORTAL(x);
2916 }
2917
2918#if PYTHON_VERSION < 0x300
2919 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
2920 coercion c1 = PyFloat_Type.tp_as_number->nb_coerce;
2921
2922 if (c1 != NULL) {
2923 PyObject *coerced1 = operand1;
2924 PyObject *coerced2 = operand2;
2925
2926 int err = c1(&coerced1, &coerced2);
2927
2928 if (unlikely(err < 0)) {
2929 goto exit_binary_exception;
2930 }
2931
2932 if (err == 0) {
2933 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2934
2935 if (likely(mv == NULL)) {
2936 binaryfunc slot = mv->nb_add;
2937
2938 if (likely(slot != NULL)) {
2939 PyObject *x = slot(coerced1, coerced2);
2940
2941 Py_DECREF(coerced1);
2942 Py_DECREF(coerced2);
2943
2944 obj_result = x;
2945 goto exit_binary_result_object;
2946 }
2947 }
2948
2949 // nb_coerce took a reference.
2950 Py_DECREF(coerced1);
2951 Py_DECREF(coerced2);
2952 }
2953 }
2954 coercion c2 =
2955 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
2956
2957 if (c2 != NULL) {
2958 PyObject *coerced1 = operand1;
2959 PyObject *coerced2 = operand2;
2960
2961 int err = c2(&coerced2, &coerced1);
2962
2963 if (unlikely(err < 0)) {
2964 goto exit_binary_exception;
2965 }
2966
2967 if (err == 0) {
2968 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2969
2970 if (likely(mv == NULL)) {
2971 binaryfunc slot = mv->nb_add;
2972
2973 if (likely(slot != NULL)) {
2974 PyObject *x = slot(coerced1, coerced2);
2975
2976 Py_DECREF(coerced1);
2977 Py_DECREF(coerced2);
2978
2979 obj_result = x;
2980 goto exit_binary_result_object;
2981 }
2982 }
2983
2984 // nb_coerce took a reference.
2985 Py_DECREF(coerced1);
2986 Py_DECREF(coerced2);
2987 }
2988 }
2989 }
2990#endif
2991
2992 {
2993 // No sequence repeat slot sq_concat available for this type.
2994 }
2995
2996 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and '%s'", type2->tp_name);
2997 goto exit_binary_exception;
2998
2999exit_binary_result_object:
3000 if (unlikely(obj_result == NULL)) {
3001 return NUITKA_BOOL_EXCEPTION;
3002 }
3003
3004 {
3005 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3006 Py_DECREF(obj_result);
3007 return r;
3008 }
3009
3010exit_binary_exception:
3011 return NUITKA_BOOL_EXCEPTION;
3012}
3013static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_FLOAT_OBJECT(PyObject *operand1, PyObject *operand2) {
3014 CHECK_OBJECT(operand1);
3015 assert(PyFloat_CheckExact(operand1));
3016 CHECK_OBJECT(operand2);
3017
3018 PyTypeObject *type2 = Py_TYPE(operand2);
3019
3020 if (&PyFloat_Type == type2) {
3021 nuitka_bool result;
3022
3023 // return _BINARY_OPERATION_ADD_NBOOL_FLOAT_FLOAT(operand1, operand2);
3024
3025#if defined(_MSC_VER)
3026#pragma warning(push)
3027#pragma warning(disable : 4101)
3028#endif
3029 // Not every code path will make use of all possible results.
3030 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3031 NUITKA_MAY_BE_UNUSED long clong_result;
3032 NUITKA_MAY_BE_UNUSED double cfloat_result;
3033#if defined(_MSC_VER)
3034#pragma warning(pop)
3035#endif
3036
3037 CHECK_OBJECT(operand1);
3038 assert(PyFloat_CheckExact(operand1));
3039 CHECK_OBJECT(operand2);
3040 assert(PyFloat_CheckExact(operand2));
3041
3042 const double a = PyFloat_AS_DOUBLE(operand1);
3043 const double b = PyFloat_AS_DOUBLE(operand2);
3044
3045 double r = a + b;
3046
3047 cfloat_result = r;
3048 goto exit_result_ok_cfloat;
3049
3050 exit_result_ok_cfloat:
3051 result = cfloat_result != 0.0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3052 goto exit_result_ok;
3053
3054 exit_result_ok:
3055 return result;
3056 }
3057
3058 return __BINARY_OPERATION_ADD_NBOOL_FLOAT_OBJECT(operand1, operand2);
3059}
3060
3061nuitka_bool BINARY_OPERATION_ADD_NBOOL_FLOAT_OBJECT(PyObject *operand1, PyObject *operand2) {
3062 return _BINARY_OPERATION_ADD_NBOOL_FLOAT_OBJECT(operand1, operand2);
3063}
3064
3065/* Code referring to "FLOAT" corresponds to Python 'float' and "LONG" to Python2 'long', Python3 'int'. */
3066static PyObject *_BINARY_OPERATION_ADD_OBJECT_FLOAT_LONG(PyObject *operand1, PyObject *operand2) {
3067 CHECK_OBJECT(operand1);
3068 assert(PyFloat_CheckExact(operand1));
3069 CHECK_OBJECT(operand2);
3070 assert(PyLong_CheckExact(operand2));
3071
3072#if defined(_MSC_VER)
3073#pragma warning(push)
3074#pragma warning(disable : 4101)
3075#endif
3076 NUITKA_MAY_BE_UNUSED bool cbool_result;
3077 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3078#if defined(_MSC_VER)
3079#pragma warning(pop)
3080#endif
3081
3082 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_add;
3083 // Slot2 ignored on purpose, type1 takes precedence.
3084
3085 if (slot1 != NULL) {
3086 PyObject *x = slot1(operand1, operand2);
3087
3088 if (x != Py_NotImplemented) {
3089 obj_result = x;
3090 goto exit_binary_result_object;
3091 }
3092
3093 Py_DECREF_IMMORTAL(x);
3094 }
3095
3096 // Statically recognized that coercion is not possible with these types
3097
3098 {
3099 // No sequence repeat slot sq_concat available for this type.
3100 }
3101
3102#if PYTHON_VERSION < 0x300
3103 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'long'");
3104#else
3105 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'int'");
3106#endif
3107 goto exit_binary_exception;
3108
3109exit_binary_result_object:
3110 return obj_result;
3111
3112exit_binary_exception:
3113 return NULL;
3114}
3115
3116PyObject *BINARY_OPERATION_ADD_OBJECT_FLOAT_LONG(PyObject *operand1, PyObject *operand2) {
3117 return _BINARY_OPERATION_ADD_OBJECT_FLOAT_LONG(operand1, operand2);
3118}
3119
3120/* Code referring to "FLOAT" corresponds to Python 'float' and "LONG" to Python2 'long', Python3 'int'. */
3121static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_FLOAT_LONG(PyObject *operand1, PyObject *operand2) {
3122 CHECK_OBJECT(operand1);
3123 assert(PyFloat_CheckExact(operand1));
3124 CHECK_OBJECT(operand2);
3125 assert(PyLong_CheckExact(operand2));
3126
3127#if defined(_MSC_VER)
3128#pragma warning(push)
3129#pragma warning(disable : 4101)
3130#endif
3131 NUITKA_MAY_BE_UNUSED bool cbool_result;
3132 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3133#if defined(_MSC_VER)
3134#pragma warning(pop)
3135#endif
3136
3137 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_add;
3138 // Slot2 ignored on purpose, type1 takes precedence.
3139
3140 if (slot1 != NULL) {
3141 PyObject *x = slot1(operand1, operand2);
3142
3143 if (x != Py_NotImplemented) {
3144 obj_result = x;
3145 goto exit_binary_result_object;
3146 }
3147
3148 Py_DECREF_IMMORTAL(x);
3149 }
3150
3151 // Statically recognized that coercion is not possible with these types
3152
3153 {
3154 // No sequence repeat slot sq_concat available for this type.
3155 }
3156
3157#if PYTHON_VERSION < 0x300
3158 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'long'");
3159#else
3160 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'int'");
3161#endif
3162 goto exit_binary_exception;
3163
3164exit_binary_result_object:
3165 if (unlikely(obj_result == NULL)) {
3166 return NUITKA_BOOL_EXCEPTION;
3167 }
3168
3169 {
3170 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3171 Py_DECREF(obj_result);
3172 return r;
3173 }
3174
3175exit_binary_exception:
3176 return NUITKA_BOOL_EXCEPTION;
3177}
3178
3179nuitka_bool BINARY_OPERATION_ADD_NBOOL_FLOAT_LONG(PyObject *operand1, PyObject *operand2) {
3180 return _BINARY_OPERATION_ADD_NBOOL_FLOAT_LONG(operand1, operand2);
3181}
3182
3183#if PYTHON_VERSION < 0x300
3184/* Code referring to "FLOAT" corresponds to Python 'float' and "INT" to Python2 'int'. */
3185static PyObject *_BINARY_OPERATION_ADD_OBJECT_FLOAT_INT(PyObject *operand1, PyObject *operand2) {
3186 CHECK_OBJECT(operand1);
3187 assert(PyFloat_CheckExact(operand1));
3188 CHECK_OBJECT(operand2);
3189 assert(PyInt_CheckExact(operand2));
3190
3191#if defined(_MSC_VER)
3192#pragma warning(push)
3193#pragma warning(disable : 4101)
3194#endif
3195 NUITKA_MAY_BE_UNUSED bool cbool_result;
3196 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3197#if defined(_MSC_VER)
3198#pragma warning(pop)
3199#endif
3200
3201 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_add;
3202 // Slot2 ignored on purpose, type1 takes precedence.
3203
3204 if (slot1 != NULL) {
3205 PyObject *x = slot1(operand1, operand2);
3206
3207 if (x != Py_NotImplemented) {
3208 obj_result = x;
3209 goto exit_binary_result_object;
3210 }
3211
3212 Py_DECREF_IMMORTAL(x);
3213 }
3214
3215 // Statically recognized that coercion is not possible with these types
3216
3217 {
3218 // No sequence repeat slot sq_concat available for this type.
3219 }
3220
3221 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'int'");
3222 goto exit_binary_exception;
3223
3224exit_binary_result_object:
3225 return obj_result;
3226
3227exit_binary_exception:
3228 return NULL;
3229}
3230
3231PyObject *BINARY_OPERATION_ADD_OBJECT_FLOAT_INT(PyObject *operand1, PyObject *operand2) {
3232 return _BINARY_OPERATION_ADD_OBJECT_FLOAT_INT(operand1, operand2);
3233}
3234#endif
3235
3236#if PYTHON_VERSION < 0x300
3237/* Code referring to "FLOAT" corresponds to Python 'float' and "INT" to Python2 'int'. */
3238static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_FLOAT_INT(PyObject *operand1, PyObject *operand2) {
3239 CHECK_OBJECT(operand1);
3240 assert(PyFloat_CheckExact(operand1));
3241 CHECK_OBJECT(operand2);
3242 assert(PyInt_CheckExact(operand2));
3243
3244#if defined(_MSC_VER)
3245#pragma warning(push)
3246#pragma warning(disable : 4101)
3247#endif
3248 NUITKA_MAY_BE_UNUSED bool cbool_result;
3249 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3250#if defined(_MSC_VER)
3251#pragma warning(pop)
3252#endif
3253
3254 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_add;
3255 // Slot2 ignored on purpose, type1 takes precedence.
3256
3257 if (slot1 != NULL) {
3258 PyObject *x = slot1(operand1, operand2);
3259
3260 if (x != Py_NotImplemented) {
3261 obj_result = x;
3262 goto exit_binary_result_object;
3263 }
3264
3265 Py_DECREF_IMMORTAL(x);
3266 }
3267
3268 // Statically recognized that coercion is not possible with these types
3269
3270 {
3271 // No sequence repeat slot sq_concat available for this type.
3272 }
3273
3274 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'float' and 'int'");
3275 goto exit_binary_exception;
3276
3277exit_binary_result_object:
3278 if (unlikely(obj_result == NULL)) {
3279 return NUITKA_BOOL_EXCEPTION;
3280 }
3281
3282 {
3283 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3284 Py_DECREF(obj_result);
3285 return r;
3286 }
3287
3288exit_binary_exception:
3289 return NUITKA_BOOL_EXCEPTION;
3290}
3291
3292nuitka_bool BINARY_OPERATION_ADD_NBOOL_FLOAT_INT(PyObject *operand1, PyObject *operand2) {
3293 return _BINARY_OPERATION_ADD_NBOOL_FLOAT_INT(operand1, operand2);
3294}
3295#endif
3296
3297#if PYTHON_VERSION < 0x300
3298/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
3299static PyObject *_BINARY_OPERATION_ADD_OBJECT_LONG_INT(PyObject *operand1, PyObject *operand2) {
3300 CHECK_OBJECT(operand1);
3301 assert(PyLong_CheckExact(operand1));
3302 CHECK_OBJECT(operand2);
3303 assert(PyInt_CheckExact(operand2));
3304
3305#if defined(_MSC_VER)
3306#pragma warning(push)
3307#pragma warning(disable : 4101)
3308#endif
3309 NUITKA_MAY_BE_UNUSED bool cbool_result;
3310 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3311#if defined(_MSC_VER)
3312#pragma warning(pop)
3313#endif
3314
3315 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_add;
3316 // Slot2 ignored on purpose, type1 takes precedence.
3317
3318 if (slot1 != NULL) {
3319 PyObject *x = slot1(operand1, operand2);
3320
3321 if (x != Py_NotImplemented) {
3322 obj_result = x;
3323 goto exit_binary_result_object;
3324 }
3325
3326 Py_DECREF_IMMORTAL(x);
3327 }
3328
3329 // Statically recognized that coercion is not possible with these types
3330
3331 {
3332 // No sequence repeat slot sq_concat available for this type.
3333 }
3334
3335 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and 'int'");
3336 goto exit_binary_exception;
3337
3338exit_binary_result_object:
3339 return obj_result;
3340
3341exit_binary_exception:
3342 return NULL;
3343}
3344
3345PyObject *BINARY_OPERATION_ADD_OBJECT_LONG_INT(PyObject *operand1, PyObject *operand2) {
3346 return _BINARY_OPERATION_ADD_OBJECT_LONG_INT(operand1, operand2);
3347}
3348#endif
3349
3350#if PYTHON_VERSION < 0x300
3351/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
3352static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LONG_INT(PyObject *operand1, PyObject *operand2) {
3353 CHECK_OBJECT(operand1);
3354 assert(PyLong_CheckExact(operand1));
3355 CHECK_OBJECT(operand2);
3356 assert(PyInt_CheckExact(operand2));
3357
3358#if defined(_MSC_VER)
3359#pragma warning(push)
3360#pragma warning(disable : 4101)
3361#endif
3362 NUITKA_MAY_BE_UNUSED bool cbool_result;
3363 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3364#if defined(_MSC_VER)
3365#pragma warning(pop)
3366#endif
3367
3368 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_add;
3369 // Slot2 ignored on purpose, type1 takes precedence.
3370
3371 if (slot1 != NULL) {
3372 PyObject *x = slot1(operand1, operand2);
3373
3374 if (x != Py_NotImplemented) {
3375 obj_result = x;
3376 goto exit_binary_result_object;
3377 }
3378
3379 Py_DECREF_IMMORTAL(x);
3380 }
3381
3382 // Statically recognized that coercion is not possible with these types
3383
3384 {
3385 // No sequence repeat slot sq_concat available for this type.
3386 }
3387
3388 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: 'long' and 'int'");
3389 goto exit_binary_exception;
3390
3391exit_binary_result_object:
3392 if (unlikely(obj_result == NULL)) {
3393 return NUITKA_BOOL_EXCEPTION;
3394 }
3395
3396 {
3397 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3398 Py_DECREF(obj_result);
3399 return r;
3400 }
3401
3402exit_binary_exception:
3403 return NUITKA_BOOL_EXCEPTION;
3404}
3405
3406nuitka_bool BINARY_OPERATION_ADD_NBOOL_LONG_INT(PyObject *operand1, PyObject *operand2) {
3407 return _BINARY_OPERATION_ADD_NBOOL_LONG_INT(operand1, operand2);
3408}
3409#endif
3410
3411#if PYTHON_VERSION < 0x300
3412/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
3413static PyObject *_BINARY_OPERATION_ADD_OBJECT_INT_CLONG(PyObject *operand1, long operand2) {
3414 CHECK_OBJECT(operand1);
3415 assert(PyInt_CheckExact(operand1));
3416
3417 PyObject *result;
3418
3419 // Not every code path will make use of all possible results.
3420#if defined(_MSC_VER)
3421#pragma warning(push)
3422#pragma warning(disable : 4101)
3423#endif
3424 NUITKA_MAY_BE_UNUSED bool cbool_result;
3425 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3426 NUITKA_MAY_BE_UNUSED long clong_result;
3427 NUITKA_MAY_BE_UNUSED double cfloat_result;
3428#if defined(_MSC_VER)
3429#pragma warning(pop)
3430#endif
3431
3432 CHECK_OBJECT(operand1);
3433 assert(PyInt_CheckExact(operand1));
3434
3435 const long a = PyInt_AS_LONG(operand1);
3436 const long b = operand2;
3437
3438 const long x = (long)((unsigned long)a + b);
3439 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
3440 if (likely(no_overflow)) {
3441 clong_result = x;
3442 goto exit_result_ok_clong;
3443 }
3444
3445 {
3446 PyObject *operand1_object = operand1;
3447 PyObject *operand2_object = Nuitka_PyLong_FromLong(operand2);
3448
3449 PyObject *r = PyLong_Type.tp_as_number->nb_add(operand1_object, operand2_object);
3450 assert(r != Py_NotImplemented);
3451
3452 Py_DECREF(operand2_object);
3453
3454 obj_result = r;
3455 goto exit_result_object;
3456 }
3457
3458exit_result_ok_clong:
3459 result = Nuitka_PyInt_FromLong(clong_result);
3460 goto exit_result_ok;
3461
3462exit_result_object:
3463 if (unlikely(obj_result == NULL)) {
3464 goto exit_result_exception;
3465 }
3466 result = obj_result;
3467 goto exit_result_ok;
3468
3469exit_result_ok:
3470 return result;
3471
3472exit_result_exception:
3473 return NULL;
3474}
3475
3476PyObject *BINARY_OPERATION_ADD_OBJECT_INT_CLONG(PyObject *operand1, long operand2) {
3477 return _BINARY_OPERATION_ADD_OBJECT_INT_CLONG(operand1, operand2);
3478}
3479#endif
3480
3481#if PYTHON_VERSION < 0x300
3482/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
3483static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_INT_CLONG(PyObject *operand1, long operand2) {
3484 CHECK_OBJECT(operand1);
3485 assert(PyInt_CheckExact(operand1));
3486
3487 nuitka_bool result;
3488
3489 // Not every code path will make use of all possible results.
3490#if defined(_MSC_VER)
3491#pragma warning(push)
3492#pragma warning(disable : 4101)
3493#endif
3494 NUITKA_MAY_BE_UNUSED bool cbool_result;
3495 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3496 NUITKA_MAY_BE_UNUSED long clong_result;
3497 NUITKA_MAY_BE_UNUSED double cfloat_result;
3498#if defined(_MSC_VER)
3499#pragma warning(pop)
3500#endif
3501
3502 CHECK_OBJECT(operand1);
3503 assert(PyInt_CheckExact(operand1));
3504
3505 const long a = PyInt_AS_LONG(operand1);
3506 const long b = operand2;
3507
3508 const long x = (long)((unsigned long)a + b);
3509 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
3510 bool t = !no_overflow || x != 0;
3511
3512 cbool_result = t;
3513 goto exit_result_ok_cbool;
3514
3515exit_result_ok_cbool:
3516 result = cbool_result ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3517 goto exit_result_ok;
3518
3519exit_result_ok:
3520 return result;
3521}
3522
3523nuitka_bool BINARY_OPERATION_ADD_NBOOL_INT_CLONG(PyObject *operand1, long operand2) {
3524 return _BINARY_OPERATION_ADD_NBOOL_INT_CLONG(operand1, operand2);
3525}
3526#endif
3527
3528/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "DIGIT" to C platform digit value for long
3529 * Python objects. */
3530static PyObject *_BINARY_OPERATION_ADD_OBJECT_LONG_DIGIT(PyObject *operand1, long operand2) {
3531 CHECK_OBJECT(operand1);
3532 assert(PyLong_CheckExact(operand1));
3533 assert(Py_ABS(operand2) < (1 << PyLong_SHIFT));
3534
3535 PyObject *result;
3536
3537 // Not every code path will make use of all possible results.
3538#if defined(_MSC_VER)
3539#pragma warning(push)
3540#pragma warning(disable : 4101)
3541#endif
3542 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3543 NUITKA_MAY_BE_UNUSED long clong_result;
3544#if defined(_MSC_VER)
3545#pragma warning(pop)
3546#endif
3547
3548 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
3549
3550 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && (operand2 == 0 ? 0 : 1) <= 1) {
3551 long r = (long)(MEDIUM_VALUE(operand1_long_object) + (sdigit)operand2);
3552
3553 clong_result = r;
3554 goto exit_result_ok_clong;
3555 }
3556
3557 {
3558 PyLongObject *z;
3559
3560 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
3561 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
3562 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
3563 digit const *b_digits = (digit *)&operand2;
3564 Py_ssize_t b_digit_count = (operand2 == 0 ? 0 : 1);
3565 bool b_negative = operand2 < 0;
3566
3567 if (a_negative) {
3568 if (b_negative) {
3569 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3570 Nuitka_LongFlipSign(z);
3571 } else {
3572 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
3573 }
3574 } else {
3575 if (b_negative) {
3576 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3577 } else {
3578 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3579 }
3580 }
3581
3582 obj_result = (PyObject *)z;
3583 goto exit_result_object;
3584 }
3585
3586exit_result_object:
3587 if (unlikely(obj_result == NULL)) {
3588 goto exit_result_exception;
3589 }
3590 result = obj_result;
3591 goto exit_result_ok;
3592
3593exit_result_ok_clong:
3594 result = Nuitka_LongFromCLong(clong_result);
3595 goto exit_result_ok;
3596
3597exit_result_ok:
3598 return result;
3599
3600exit_result_exception:
3601 return NULL;
3602}
3603
3604PyObject *BINARY_OPERATION_ADD_OBJECT_LONG_DIGIT(PyObject *operand1, long operand2) {
3605 return _BINARY_OPERATION_ADD_OBJECT_LONG_DIGIT(operand1, operand2);
3606}
3607
3608/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "DIGIT" to C platform digit value for long
3609 * Python objects. */
3610static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LONG_DIGIT(PyObject *operand1, long operand2) {
3611 CHECK_OBJECT(operand1);
3612 assert(PyLong_CheckExact(operand1));
3613 assert(Py_ABS(operand2) < (1 << PyLong_SHIFT));
3614
3615 nuitka_bool result;
3616
3617 // Not every code path will make use of all possible results.
3618#if defined(_MSC_VER)
3619#pragma warning(push)
3620#pragma warning(disable : 4101)
3621#endif
3622 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3623 NUITKA_MAY_BE_UNUSED long clong_result;
3624#if defined(_MSC_VER)
3625#pragma warning(pop)
3626#endif
3627
3628 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
3629
3630 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && (operand2 == 0 ? 0 : 1) <= 1) {
3631 long r = (long)(MEDIUM_VALUE(operand1_long_object) + (sdigit)operand2);
3632
3633 clong_result = r;
3634 goto exit_result_ok_clong;
3635 }
3636
3637 {
3638 PyLongObject *z;
3639
3640 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
3641 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
3642 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
3643 digit const *b_digits = (digit *)&operand2;
3644 Py_ssize_t b_digit_count = (operand2 == 0 ? 0 : 1);
3645 bool b_negative = operand2 < 0;
3646
3647 if (a_negative) {
3648 if (b_negative) {
3649 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3650 Nuitka_LongFlipSign(z);
3651 } else {
3652 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
3653 }
3654 } else {
3655 if (b_negative) {
3656 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3657 } else {
3658 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3659 }
3660 }
3661
3662 obj_result = (PyObject *)z;
3663 goto exit_result_object;
3664 }
3665
3666exit_result_object:
3667 if (unlikely(obj_result == NULL)) {
3668 goto exit_result_exception;
3669 }
3670 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3671 Py_DECREF(obj_result);
3672 goto exit_result_ok;
3673
3674exit_result_ok_clong:
3675 result = clong_result != 0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3676 goto exit_result_ok;
3677
3678exit_result_ok:
3679 return result;
3680
3681exit_result_exception:
3682 return NUITKA_BOOL_EXCEPTION;
3683}
3684
3685nuitka_bool BINARY_OPERATION_ADD_NBOOL_LONG_DIGIT(PyObject *operand1, long operand2) {
3686 return _BINARY_OPERATION_ADD_NBOOL_LONG_DIGIT(operand1, operand2);
3687}
3688
3689/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "CLONG" to C platform long value. */
3690static PyObject *_BINARY_OPERATION_ADD_OBJECT_LONG_CLONG(PyObject *operand1, long operand2) {
3691 CHECK_OBJECT(operand1);
3692 assert(PyLong_CheckExact(operand1));
3693
3694 PyObject *result;
3695
3696 // Not every code path will make use of all possible results.
3697#if defined(_MSC_VER)
3698#pragma warning(push)
3699#pragma warning(disable : 4101)
3700#endif
3701 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3702 NUITKA_MAY_BE_UNUSED long clong_result;
3703#if defined(_MSC_VER)
3704#pragma warning(pop)
3705#endif
3706
3707 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
3708
3709 bool operand2_is_negative;
3710 unsigned long operand2_abs_ival;
3711
3712 if (operand2 < 0) {
3713 operand2_abs_ival = (unsigned long)(-1 - operand2) + 1;
3714 operand2_is_negative = true;
3715 } else {
3716 operand2_abs_ival = (unsigned long)operand2;
3717 operand2_is_negative = false;
3718 }
3719
3720 Py_ssize_t operand2_digit_count = 0;
3721 digit operand2_digits[5] = {0}; // Could be more minimal and depend on sizeof(digit)
3722 {
3723 unsigned long t = operand2_abs_ival;
3724
3725 while (t != 0) {
3726 operand2_digit_count += 1;
3727 assert(operand2_digit_count <= (Py_ssize_t)(sizeof(operand2_digit_count) / sizeof(digit)));
3728
3729 operand2_digits[operand2_digit_count] = (digit)(t & PyLong_MASK);
3730 t >>= PyLong_SHIFT;
3731 }
3732 }
3733
3734 NUITKA_MAY_BE_UNUSED Py_ssize_t operand2_size =
3735 operand2_is_negative == false ? operand2_digit_count : -operand2_digit_count;
3736
3737 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && operand2_digit_count <= 1) {
3738 long r = (long)(MEDIUM_VALUE(operand1_long_object) + (sdigit)operand2);
3739
3740 clong_result = r;
3741 goto exit_result_ok_clong;
3742 }
3743
3744 {
3745 PyLongObject *z;
3746
3747 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
3748 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
3749 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
3750 digit const *b_digits = operand2_digits;
3751 Py_ssize_t b_digit_count = operand2_digit_count;
3752 bool b_negative = operand2_is_negative;
3753
3754 if (a_negative) {
3755 if (b_negative) {
3756 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3757 Nuitka_LongFlipSign(z);
3758 } else {
3759 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
3760 }
3761 } else {
3762 if (b_negative) {
3763 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3764 } else {
3765 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3766 }
3767 }
3768
3769 obj_result = (PyObject *)z;
3770 goto exit_result_object;
3771 }
3772
3773exit_result_object:
3774 if (unlikely(obj_result == NULL)) {
3775 goto exit_result_exception;
3776 }
3777 result = obj_result;
3778 goto exit_result_ok;
3779
3780exit_result_ok_clong:
3781 result = Nuitka_LongFromCLong(clong_result);
3782 goto exit_result_ok;
3783
3784exit_result_ok:
3785 return result;
3786
3787exit_result_exception:
3788 return NULL;
3789}
3790
3791PyObject *BINARY_OPERATION_ADD_OBJECT_LONG_CLONG(PyObject *operand1, long operand2) {
3792 return _BINARY_OPERATION_ADD_OBJECT_LONG_CLONG(operand1, operand2);
3793}
3794
3795/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "CLONG" to C platform long value. */
3796static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LONG_CLONG(PyObject *operand1, long operand2) {
3797 CHECK_OBJECT(operand1);
3798 assert(PyLong_CheckExact(operand1));
3799
3800 nuitka_bool result;
3801
3802 // Not every code path will make use of all possible results.
3803#if defined(_MSC_VER)
3804#pragma warning(push)
3805#pragma warning(disable : 4101)
3806#endif
3807 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3808 NUITKA_MAY_BE_UNUSED long clong_result;
3809#if defined(_MSC_VER)
3810#pragma warning(pop)
3811#endif
3812
3813 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
3814
3815 bool operand2_is_negative;
3816 unsigned long operand2_abs_ival;
3817
3818 if (operand2 < 0) {
3819 operand2_abs_ival = (unsigned long)(-1 - operand2) + 1;
3820 operand2_is_negative = true;
3821 } else {
3822 operand2_abs_ival = (unsigned long)operand2;
3823 operand2_is_negative = false;
3824 }
3825
3826 Py_ssize_t operand2_digit_count = 0;
3827 digit operand2_digits[5] = {0}; // Could be more minimal and depend on sizeof(digit)
3828 {
3829 unsigned long t = operand2_abs_ival;
3830
3831 while (t != 0) {
3832 operand2_digit_count += 1;
3833 assert(operand2_digit_count <= (Py_ssize_t)(sizeof(operand2_digit_count) / sizeof(digit)));
3834
3835 operand2_digits[operand2_digit_count] = (digit)(t & PyLong_MASK);
3836 t >>= PyLong_SHIFT;
3837 }
3838 }
3839
3840 NUITKA_MAY_BE_UNUSED Py_ssize_t operand2_size =
3841 operand2_is_negative == false ? operand2_digit_count : -operand2_digit_count;
3842
3843 if (Nuitka_LongGetDigitSize(operand1_long_object) <= 1 && operand2_digit_count <= 1) {
3844 long r = (long)(MEDIUM_VALUE(operand1_long_object) + (sdigit)operand2);
3845
3846 clong_result = r;
3847 goto exit_result_ok_clong;
3848 }
3849
3850 {
3851 PyLongObject *z;
3852
3853 digit const *a_digits = Nuitka_LongGetDigitPointer(operand1_long_object);
3854 Py_ssize_t a_digit_count = Nuitka_LongGetDigitSize(operand1_long_object);
3855 bool a_negative = Nuitka_LongIsNegative(operand1_long_object);
3856 digit const *b_digits = operand2_digits;
3857 Py_ssize_t b_digit_count = operand2_digit_count;
3858 bool b_negative = operand2_is_negative;
3859
3860 if (a_negative) {
3861 if (b_negative) {
3862 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3863 Nuitka_LongFlipSign(z);
3864 } else {
3865 z = _Nuitka_LongSubDigits(b_digits, b_digit_count, a_digits, a_digit_count);
3866 }
3867 } else {
3868 if (b_negative) {
3869 z = _Nuitka_LongSubDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3870 } else {
3871 z = _Nuitka_LongAddDigits(a_digits, a_digit_count, b_digits, b_digit_count);
3872 }
3873 }
3874
3875 obj_result = (PyObject *)z;
3876 goto exit_result_object;
3877 }
3878
3879exit_result_object:
3880 if (unlikely(obj_result == NULL)) {
3881 goto exit_result_exception;
3882 }
3883 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3884 Py_DECREF(obj_result);
3885 goto exit_result_ok;
3886
3887exit_result_ok_clong:
3888 result = clong_result != 0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3889 goto exit_result_ok;
3890
3891exit_result_ok:
3892 return result;
3893
3894exit_result_exception:
3895 return NUITKA_BOOL_EXCEPTION;
3896}
3897
3898nuitka_bool BINARY_OPERATION_ADD_NBOOL_LONG_CLONG(PyObject *operand1, long operand2) {
3899 return _BINARY_OPERATION_ADD_NBOOL_LONG_CLONG(operand1, operand2);
3900}
3901
3902/* Code referring to "FLOAT" corresponds to Python 'float' and "CFLOAT" to C platform float value. */
3903static PyObject *_BINARY_OPERATION_ADD_OBJECT_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
3904 CHECK_OBJECT(operand1);
3905 assert(PyFloat_CheckExact(operand1));
3906
3907 PyObject *result;
3908
3909#if defined(_MSC_VER)
3910#pragma warning(push)
3911#pragma warning(disable : 4101)
3912#endif
3913 // Not every code path will make use of all possible results.
3914 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3915 NUITKA_MAY_BE_UNUSED long clong_result;
3916 NUITKA_MAY_BE_UNUSED double cfloat_result;
3917#if defined(_MSC_VER)
3918#pragma warning(pop)
3919#endif
3920
3921 CHECK_OBJECT(operand1);
3922 assert(PyFloat_CheckExact(operand1));
3923
3924 const double a = PyFloat_AS_DOUBLE(operand1);
3925 const double b = operand2;
3926
3927 double r = a + b;
3928
3929 cfloat_result = r;
3930 goto exit_result_ok_cfloat;
3931
3932exit_result_ok_cfloat:
3933 result = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
3934 goto exit_result_ok;
3935
3936exit_result_ok:
3937 return result;
3938}
3939
3940PyObject *BINARY_OPERATION_ADD_OBJECT_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
3941 return _BINARY_OPERATION_ADD_OBJECT_FLOAT_CFLOAT(operand1, operand2);
3942}
3943
3944/* Code referring to "FLOAT" corresponds to Python 'float' and "CFLOAT" to C platform float value. */
3945static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
3946 CHECK_OBJECT(operand1);
3947 assert(PyFloat_CheckExact(operand1));
3948
3949 nuitka_bool result;
3950
3951#if defined(_MSC_VER)
3952#pragma warning(push)
3953#pragma warning(disable : 4101)
3954#endif
3955 // Not every code path will make use of all possible results.
3956 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3957 NUITKA_MAY_BE_UNUSED long clong_result;
3958 NUITKA_MAY_BE_UNUSED double cfloat_result;
3959#if defined(_MSC_VER)
3960#pragma warning(pop)
3961#endif
3962
3963 CHECK_OBJECT(operand1);
3964 assert(PyFloat_CheckExact(operand1));
3965
3966 const double a = PyFloat_AS_DOUBLE(operand1);
3967 const double b = operand2;
3968
3969 double r = a + b;
3970
3971 cfloat_result = r;
3972 goto exit_result_ok_cfloat;
3973
3974exit_result_ok_cfloat:
3975 result = cfloat_result != 0.0 ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3976 goto exit_result_ok;
3977
3978exit_result_ok:
3979 return result;
3980}
3981
3982nuitka_bool BINARY_OPERATION_ADD_NBOOL_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
3983 return _BINARY_OPERATION_ADD_NBOOL_FLOAT_CFLOAT(operand1, operand2);
3984}
3985
3986#if PYTHON_VERSION < 0x300
3987/* Code referring to "STR" corresponds to Python2 'str' and "STR" to Python2 'str'. */
3988static PyObject *_BINARY_OPERATION_ADD_OBJECT_STR_STR(PyObject *operand1, PyObject *operand2) {
3989 CHECK_OBJECT(operand1);
3990 assert(PyString_CheckExact(operand1));
3991 CHECK_OBJECT(operand2);
3992 assert(PyString_CheckExact(operand2));
3993
3994 PyObject *result;
3995
3996 // Not every code path will make use of all possible results.
3997 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3998
3999 PyObject *x = PyString_Type.tp_as_sequence->sq_concat(operand1, operand2);
4000 assert(x != Py_NotImplemented);
4001
4002 obj_result = x;
4003 goto exit_result_object;
4004
4005exit_result_object:
4006 if (unlikely(obj_result == NULL)) {
4007 goto exit_result_exception;
4008 }
4009 result = obj_result;
4010 goto exit_result_ok;
4011
4012exit_result_ok:
4013 return result;
4014
4015exit_result_exception:
4016 return NULL;
4017}
4018
4019PyObject *BINARY_OPERATION_ADD_OBJECT_STR_STR(PyObject *operand1, PyObject *operand2) {
4020 return _BINARY_OPERATION_ADD_OBJECT_STR_STR(operand1, operand2);
4021}
4022#endif
4023
4024#if PYTHON_VERSION < 0x300
4025/* Code referring to "OBJECT" corresponds to any Python object and "STR" to Python2 'str'. */
4026static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_STR(PyObject *operand1, PyObject *operand2) {
4027 PyTypeObject *type1 = Py_TYPE(operand1);
4028
4029#if defined(_MSC_VER)
4030#pragma warning(push)
4031#pragma warning(disable : 4101)
4032#endif
4033 NUITKA_MAY_BE_UNUSED bool cbool_result;
4034 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4035#if defined(_MSC_VER)
4036#pragma warning(pop)
4037#endif
4038
4039 binaryfunc slot1 =
4040 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
4041
4042 if (slot1 != NULL) {
4043 PyObject *x = slot1(operand1, operand2);
4044
4045 if (x != Py_NotImplemented) {
4046 obj_result = x;
4047 goto exit_binary_result_object;
4048 }
4049
4050 Py_DECREF_IMMORTAL(x);
4051 }
4052
4053#if PYTHON_VERSION < 0x300
4054 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
4055 coercion c1 =
4056 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
4057
4058 if (c1 != NULL) {
4059 PyObject *coerced1 = operand1;
4060 PyObject *coerced2 = operand2;
4061
4062 int err = c1(&coerced1, &coerced2);
4063
4064 if (unlikely(err < 0)) {
4065 goto exit_binary_exception;
4066 }
4067
4068 if (err == 0) {
4069 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4070
4071 if (likely(mv == NULL)) {
4072 binaryfunc slot = mv->nb_add;
4073
4074 if (likely(slot != NULL)) {
4075 PyObject *x = slot(coerced1, coerced2);
4076
4077 Py_DECREF(coerced1);
4078 Py_DECREF(coerced2);
4079
4080 obj_result = x;
4081 goto exit_binary_result_object;
4082 }
4083 }
4084
4085 // nb_coerce took a reference.
4086 Py_DECREF(coerced1);
4087 Py_DECREF(coerced2);
4088 }
4089 }
4090 }
4091#endif
4092
4093 {
4094 // Special case for "+" and "*", also works as sequence concat/repeat.
4095 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
4096
4097 if (sq_slot != NULL) {
4098 PyObject *result = sq_slot(operand1, operand2);
4099
4100 obj_result = result;
4101 goto exit_binary_result_object;
4102 }
4103 }
4104
4105 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'str'", type1->tp_name);
4106 goto exit_binary_exception;
4107
4108exit_binary_result_object:
4109 return obj_result;
4110
4111exit_binary_exception:
4112 return NULL;
4113}
4114static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_STR(PyObject *operand1, PyObject *operand2) {
4115 CHECK_OBJECT(operand1);
4116 CHECK_OBJECT(operand2);
4117 assert(PyString_CheckExact(operand2));
4118
4119 PyTypeObject *type1 = Py_TYPE(operand1);
4120
4121 if (type1 == &PyString_Type) {
4122 PyObject *result;
4123
4124 // return _BINARY_OPERATION_ADD_OBJECT_STR_STR(operand1, operand2);
4125
4126 // Not every code path will make use of all possible results.
4127 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4128
4129 PyObject *x = PyString_Type.tp_as_sequence->sq_concat(operand1, operand2);
4130 assert(x != Py_NotImplemented);
4131
4132 obj_result = x;
4133 goto exit_result_object;
4134
4135 exit_result_object:
4136 if (unlikely(obj_result == NULL)) {
4137 goto exit_result_exception;
4138 }
4139 result = obj_result;
4140 goto exit_result_ok;
4141
4142 exit_result_ok:
4143 return result;
4144
4145 exit_result_exception:
4146 return NULL;
4147 }
4148
4149 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_STR(operand1, operand2);
4150}
4151
4152PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_STR(PyObject *operand1, PyObject *operand2) {
4153 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_STR(operand1, operand2);
4154}
4155#endif
4156
4157#if PYTHON_VERSION < 0x300
4158/* Code referring to "STR" corresponds to Python2 'str' and "OBJECT" to any Python object. */
4159static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_STR_OBJECT(PyObject *operand1, PyObject *operand2) {
4160 PyTypeObject *type2 = Py_TYPE(operand2);
4161
4162#if defined(_MSC_VER)
4163#pragma warning(push)
4164#pragma warning(disable : 4101)
4165#endif
4166 NUITKA_MAY_BE_UNUSED bool cbool_result;
4167 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4168#if defined(_MSC_VER)
4169#pragma warning(pop)
4170#endif
4171
4172 binaryfunc slot2 = NULL;
4173
4174 if (!(&PyString_Type == type2)) {
4175 // Different types, need to consider second value slot.
4176
4177 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
4178 }
4179
4180 if (slot2 != NULL) {
4181 PyObject *x = slot2(operand1, operand2);
4182
4183 if (x != Py_NotImplemented) {
4184 obj_result = x;
4185 goto exit_binary_result_object;
4186 }
4187
4188 Py_DECREF_IMMORTAL(x);
4189 }
4190
4191#if PYTHON_VERSION < 0x300
4192 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
4193 coercion c2 =
4194 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
4195
4196 if (c2 != NULL) {
4197 PyObject *coerced1 = operand1;
4198 PyObject *coerced2 = operand2;
4199
4200 int err = c2(&coerced2, &coerced1);
4201
4202 if (unlikely(err < 0)) {
4203 goto exit_binary_exception;
4204 }
4205
4206 if (err == 0) {
4207 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4208
4209 if (likely(mv == NULL)) {
4210 binaryfunc slot = mv->nb_add;
4211
4212 if (likely(slot != NULL)) {
4213 PyObject *x = slot(coerced1, coerced2);
4214
4215 Py_DECREF(coerced1);
4216 Py_DECREF(coerced2);
4217
4218 obj_result = x;
4219 goto exit_binary_result_object;
4220 }
4221 }
4222
4223 // nb_coerce took a reference.
4224 Py_DECREF(coerced1);
4225 Py_DECREF(coerced2);
4226 }
4227 }
4228 }
4229#endif
4230
4231 {
4232 PyObject *o = PyString_Type.tp_as_sequence->sq_concat(operand1, operand2);
4233 obj_result = o;
4234 goto exit_binary_result_object;
4235 }
4236
4237 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
4238
4239exit_binary_result_object:
4240 return obj_result;
4241
4242#if PYTHON_VERSION < 0x300
4243exit_binary_exception:
4244 return NULL;
4245#endif
4246}
4247static PyObject *_BINARY_OPERATION_ADD_OBJECT_STR_OBJECT(PyObject *operand1, PyObject *operand2) {
4248 CHECK_OBJECT(operand1);
4249 assert(PyString_CheckExact(operand1));
4250 CHECK_OBJECT(operand2);
4251
4252 PyTypeObject *type2 = Py_TYPE(operand2);
4253
4254 if (&PyString_Type == type2) {
4255 PyObject *result;
4256
4257 // return _BINARY_OPERATION_ADD_OBJECT_STR_STR(operand1, operand2);
4258
4259 // Not every code path will make use of all possible results.
4260 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4261
4262 PyObject *x = PyString_Type.tp_as_sequence->sq_concat(operand1, operand2);
4263 assert(x != Py_NotImplemented);
4264
4265 obj_result = x;
4266 goto exit_result_object;
4267
4268 exit_result_object:
4269 if (unlikely(obj_result == NULL)) {
4270 goto exit_result_exception;
4271 }
4272 result = obj_result;
4273 goto exit_result_ok;
4274
4275 exit_result_ok:
4276 return result;
4277
4278 exit_result_exception:
4279 return NULL;
4280 }
4281
4282 return __BINARY_OPERATION_ADD_OBJECT_STR_OBJECT(operand1, operand2);
4283}
4284
4285PyObject *BINARY_OPERATION_ADD_OBJECT_STR_OBJECT(PyObject *operand1, PyObject *operand2) {
4286 return _BINARY_OPERATION_ADD_OBJECT_STR_OBJECT(operand1, operand2);
4287}
4288#endif
4289
4290/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "UNICODE" to Python2 'unicode',
4291 * Python3 'str'. */
4292static PyObject *_BINARY_OPERATION_ADD_OBJECT_UNICODE_UNICODE(PyObject *operand1, PyObject *operand2) {
4293 CHECK_OBJECT(operand1);
4294 assert(PyUnicode_CheckExact(operand1));
4295 CHECK_OBJECT(operand2);
4296 assert(PyUnicode_CheckExact(operand2));
4297
4298 PyObject *result;
4299
4300 // Not every code path will make use of all possible results.
4301 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4302
4303 // TODO: Have this more globally passed in
4304 PyThreadState *tstate = PyThreadState_GET();
4305
4306 PyObject *x = UNICODE_CONCAT(tstate, operand1, operand2);
4307
4308 obj_result = x;
4309 goto exit_result_object;
4310
4311exit_result_object:
4312 if (unlikely(obj_result == NULL)) {
4313 goto exit_result_exception;
4314 }
4315 result = obj_result;
4316 goto exit_result_ok;
4317
4318exit_result_ok:
4319 return result;
4320
4321exit_result_exception:
4322 return NULL;
4323}
4324
4325PyObject *BINARY_OPERATION_ADD_OBJECT_UNICODE_UNICODE(PyObject *operand1, PyObject *operand2) {
4326 return _BINARY_OPERATION_ADD_OBJECT_UNICODE_UNICODE(operand1, operand2);
4327}
4328
4329/* Code referring to "OBJECT" corresponds to any Python object and "UNICODE" to Python2 'unicode', Python3 'str'. */
4330static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_UNICODE(PyObject *operand1,
4331 PyObject *operand2) {
4332 PyTypeObject *type1 = Py_TYPE(operand1);
4333
4334#if defined(_MSC_VER)
4335#pragma warning(push)
4336#pragma warning(disable : 4101)
4337#endif
4338 NUITKA_MAY_BE_UNUSED bool cbool_result;
4339 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4340#if defined(_MSC_VER)
4341#pragma warning(pop)
4342#endif
4343
4344 binaryfunc slot1 =
4345 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
4346
4347 if (slot1 != NULL) {
4348 PyObject *x = slot1(operand1, operand2);
4349
4350 if (x != Py_NotImplemented) {
4351 obj_result = x;
4352 goto exit_binary_result_object;
4353 }
4354
4355 Py_DECREF_IMMORTAL(x);
4356 }
4357
4358#if PYTHON_VERSION < 0x300
4359 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
4360 coercion c1 =
4361 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
4362
4363 if (c1 != NULL) {
4364 PyObject *coerced1 = operand1;
4365 PyObject *coerced2 = operand2;
4366
4367 int err = c1(&coerced1, &coerced2);
4368
4369 if (unlikely(err < 0)) {
4370 goto exit_binary_exception;
4371 }
4372
4373 if (err == 0) {
4374 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4375
4376 if (likely(mv == NULL)) {
4377 binaryfunc slot = mv->nb_add;
4378
4379 if (likely(slot != NULL)) {
4380 PyObject *x = slot(coerced1, coerced2);
4381
4382 Py_DECREF(coerced1);
4383 Py_DECREF(coerced2);
4384
4385 obj_result = x;
4386 goto exit_binary_result_object;
4387 }
4388 }
4389
4390 // nb_coerce took a reference.
4391 Py_DECREF(coerced1);
4392 Py_DECREF(coerced2);
4393 }
4394 }
4395 }
4396#endif
4397
4398 {
4399 // Special case for "+" and "*", also works as sequence concat/repeat.
4400 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
4401
4402 if (sq_slot != NULL) {
4403 PyObject *result = sq_slot(operand1, operand2);
4404
4405 obj_result = result;
4406 goto exit_binary_result_object;
4407 }
4408 }
4409
4410#if PYTHON_VERSION < 0x300
4411 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'unicode'", type1->tp_name);
4412#else
4413 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'str'", type1->tp_name);
4414#endif
4415 goto exit_binary_exception;
4416
4417exit_binary_result_object:
4418 return obj_result;
4419
4420exit_binary_exception:
4421 return NULL;
4422}
4423static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_UNICODE(PyObject *operand1, PyObject *operand2) {
4424 CHECK_OBJECT(operand1);
4425 CHECK_OBJECT(operand2);
4426 assert(PyUnicode_CheckExact(operand2));
4427
4428 PyTypeObject *type1 = Py_TYPE(operand1);
4429
4430 if (type1 == &PyUnicode_Type) {
4431 PyObject *result;
4432
4433 // return _BINARY_OPERATION_ADD_OBJECT_UNICODE_UNICODE(operand1, operand2);
4434
4435 // Not every code path will make use of all possible results.
4436 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4437
4438 // TODO: Have this more globally passed in
4439 PyThreadState *tstate = PyThreadState_GET();
4440
4441 PyObject *x = UNICODE_CONCAT(tstate, operand1, operand2);
4442
4443 obj_result = x;
4444 goto exit_result_object;
4445
4446 exit_result_object:
4447 if (unlikely(obj_result == NULL)) {
4448 goto exit_result_exception;
4449 }
4450 result = obj_result;
4451 goto exit_result_ok;
4452
4453 exit_result_ok:
4454 return result;
4455
4456 exit_result_exception:
4457 return NULL;
4458 }
4459
4460 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_UNICODE(operand1, operand2);
4461}
4462
4463PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_UNICODE(PyObject *operand1, PyObject *operand2) {
4464 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_UNICODE(operand1, operand2);
4465}
4466
4467/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "OBJECT" to any Python object. */
4468static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_UNICODE_OBJECT(PyObject *operand1,
4469 PyObject *operand2) {
4470 PyTypeObject *type2 = Py_TYPE(operand2);
4471
4472#if defined(_MSC_VER)
4473#pragma warning(push)
4474#pragma warning(disable : 4101)
4475#endif
4476 NUITKA_MAY_BE_UNUSED bool cbool_result;
4477 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4478#if defined(_MSC_VER)
4479#pragma warning(pop)
4480#endif
4481
4482 binaryfunc slot2 = NULL;
4483
4484 if (!(&PyUnicode_Type == type2)) {
4485 // Different types, need to consider second value slot.
4486
4487 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
4488 }
4489
4490 if (slot2 != NULL) {
4491 PyObject *x = slot2(operand1, operand2);
4492
4493 if (x != Py_NotImplemented) {
4494 obj_result = x;
4495 goto exit_binary_result_object;
4496 }
4497
4498 Py_DECREF_IMMORTAL(x);
4499 }
4500
4501#if PYTHON_VERSION < 0x300
4502 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
4503 coercion c2 =
4504 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
4505
4506 if (c2 != NULL) {
4507 PyObject *coerced1 = operand1;
4508 PyObject *coerced2 = operand2;
4509
4510 int err = c2(&coerced2, &coerced1);
4511
4512 if (unlikely(err < 0)) {
4513 goto exit_binary_exception;
4514 }
4515
4516 if (err == 0) {
4517 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4518
4519 if (likely(mv == NULL)) {
4520 binaryfunc slot = mv->nb_add;
4521
4522 if (likely(slot != NULL)) {
4523 PyObject *x = slot(coerced1, coerced2);
4524
4525 Py_DECREF(coerced1);
4526 Py_DECREF(coerced2);
4527
4528 obj_result = x;
4529 goto exit_binary_result_object;
4530 }
4531 }
4532
4533 // nb_coerce took a reference.
4534 Py_DECREF(coerced1);
4535 Py_DECREF(coerced2);
4536 }
4537 }
4538 }
4539#endif
4540
4541 {
4542 PyObject *o = PyUnicode_Type.tp_as_sequence->sq_concat(operand1, operand2);
4543 obj_result = o;
4544 goto exit_binary_result_object;
4545 }
4546
4547 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
4548
4549exit_binary_result_object:
4550 return obj_result;
4551
4552#if PYTHON_VERSION < 0x300
4553exit_binary_exception:
4554 return NULL;
4555#endif
4556}
4557static PyObject *_BINARY_OPERATION_ADD_OBJECT_UNICODE_OBJECT(PyObject *operand1, PyObject *operand2) {
4558 CHECK_OBJECT(operand1);
4559 assert(PyUnicode_CheckExact(operand1));
4560 CHECK_OBJECT(operand2);
4561
4562 PyTypeObject *type2 = Py_TYPE(operand2);
4563
4564 if (&PyUnicode_Type == type2) {
4565 PyObject *result;
4566
4567 // return _BINARY_OPERATION_ADD_OBJECT_UNICODE_UNICODE(operand1, operand2);
4568
4569 // Not every code path will make use of all possible results.
4570 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4571
4572 // TODO: Have this more globally passed in
4573 PyThreadState *tstate = PyThreadState_GET();
4574
4575 PyObject *x = UNICODE_CONCAT(tstate, operand1, operand2);
4576
4577 obj_result = x;
4578 goto exit_result_object;
4579
4580 exit_result_object:
4581 if (unlikely(obj_result == NULL)) {
4582 goto exit_result_exception;
4583 }
4584 result = obj_result;
4585 goto exit_result_ok;
4586
4587 exit_result_ok:
4588 return result;
4589
4590 exit_result_exception:
4591 return NULL;
4592 }
4593
4594 return __BINARY_OPERATION_ADD_OBJECT_UNICODE_OBJECT(operand1, operand2);
4595}
4596
4597PyObject *BINARY_OPERATION_ADD_OBJECT_UNICODE_OBJECT(PyObject *operand1, PyObject *operand2) {
4598 return _BINARY_OPERATION_ADD_OBJECT_UNICODE_OBJECT(operand1, operand2);
4599}
4600
4601#if PYTHON_VERSION >= 0x300
4602/* Code referring to "BYTES" corresponds to Python3 'bytes' and "BYTES" to Python3 'bytes'. */
4603static PyObject *_BINARY_OPERATION_ADD_OBJECT_BYTES_BYTES(PyObject *operand1, PyObject *operand2) {
4604 CHECK_OBJECT(operand1);
4605 assert(PyBytes_CheckExact(operand1));
4606 CHECK_OBJECT(operand2);
4607 assert(PyBytes_CheckExact(operand2));
4608
4609 PyObject *result;
4610
4611 // Not every code path will make use of all possible results.
4612 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4613
4614 PyObject *x = PyBytes_Type.tp_as_sequence->sq_concat(operand1, operand2);
4615 assert(x != Py_NotImplemented);
4616
4617 obj_result = x;
4618 goto exit_result_object;
4619
4620exit_result_object:
4621 if (unlikely(obj_result == NULL)) {
4622 goto exit_result_exception;
4623 }
4624 result = obj_result;
4625 goto exit_result_ok;
4626
4627exit_result_ok:
4628 return result;
4629
4630exit_result_exception:
4631 return NULL;
4632}
4633
4634PyObject *BINARY_OPERATION_ADD_OBJECT_BYTES_BYTES(PyObject *operand1, PyObject *operand2) {
4635 return _BINARY_OPERATION_ADD_OBJECT_BYTES_BYTES(operand1, operand2);
4636}
4637#endif
4638
4639#if PYTHON_VERSION >= 0x300
4640/* Code referring to "OBJECT" corresponds to any Python object and "BYTES" to Python3 'bytes'. */
4641static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_BYTES(PyObject *operand1,
4642 PyObject *operand2) {
4643 PyTypeObject *type1 = Py_TYPE(operand1);
4644
4645#if defined(_MSC_VER)
4646#pragma warning(push)
4647#pragma warning(disable : 4101)
4648#endif
4649 NUITKA_MAY_BE_UNUSED bool cbool_result;
4650 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4651#if defined(_MSC_VER)
4652#pragma warning(pop)
4653#endif
4654
4655 binaryfunc slot1 =
4656 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
4657
4658 if (slot1 != NULL) {
4659 PyObject *x = slot1(operand1, operand2);
4660
4661 if (x != Py_NotImplemented) {
4662 obj_result = x;
4663 goto exit_binary_result_object;
4664 }
4665
4666 Py_DECREF_IMMORTAL(x);
4667 }
4668
4669#if PYTHON_VERSION < 0x300
4670 if (!NEW_STYLE_NUMBER_TYPE(type1) || !0) {
4671 coercion c1 =
4672 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
4673
4674 if (c1 != NULL) {
4675 PyObject *coerced1 = operand1;
4676 PyObject *coerced2 = operand2;
4677
4678 int err = c1(&coerced1, &coerced2);
4679
4680 if (unlikely(err < 0)) {
4681 goto exit_binary_exception;
4682 }
4683
4684 if (err == 0) {
4685 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4686
4687 if (likely(mv == NULL)) {
4688 binaryfunc slot = mv->nb_add;
4689
4690 if (likely(slot != NULL)) {
4691 PyObject *x = slot(coerced1, coerced2);
4692
4693 Py_DECREF(coerced1);
4694 Py_DECREF(coerced2);
4695
4696 obj_result = x;
4697 goto exit_binary_result_object;
4698 }
4699 }
4700
4701 // nb_coerce took a reference.
4702 Py_DECREF(coerced1);
4703 Py_DECREF(coerced2);
4704 }
4705 }
4706 }
4707#endif
4708
4709 {
4710 // Special case for "+" and "*", also works as sequence concat/repeat.
4711 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
4712
4713 if (sq_slot != NULL) {
4714 PyObject *result = sq_slot(operand1, operand2);
4715
4716 obj_result = result;
4717 goto exit_binary_result_object;
4718 }
4719 }
4720
4721 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'bytes'", type1->tp_name);
4722 goto exit_binary_exception;
4723
4724exit_binary_result_object:
4725 return obj_result;
4726
4727exit_binary_exception:
4728 return NULL;
4729}
4730static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_BYTES(PyObject *operand1, PyObject *operand2) {
4731 CHECK_OBJECT(operand1);
4732 CHECK_OBJECT(operand2);
4733 assert(PyBytes_CheckExact(operand2));
4734
4735 PyTypeObject *type1 = Py_TYPE(operand1);
4736
4737 if (type1 == &PyBytes_Type) {
4738 PyObject *result;
4739
4740 // return _BINARY_OPERATION_ADD_OBJECT_BYTES_BYTES(operand1, operand2);
4741
4742 // Not every code path will make use of all possible results.
4743 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4744
4745 PyObject *x = PyBytes_Type.tp_as_sequence->sq_concat(operand1, operand2);
4746 assert(x != Py_NotImplemented);
4747
4748 obj_result = x;
4749 goto exit_result_object;
4750
4751 exit_result_object:
4752 if (unlikely(obj_result == NULL)) {
4753 goto exit_result_exception;
4754 }
4755 result = obj_result;
4756 goto exit_result_ok;
4757
4758 exit_result_ok:
4759 return result;
4760
4761 exit_result_exception:
4762 return NULL;
4763 }
4764
4765 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_BYTES(operand1, operand2);
4766}
4767
4768PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_BYTES(PyObject *operand1, PyObject *operand2) {
4769 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_BYTES(operand1, operand2);
4770}
4771#endif
4772
4773#if PYTHON_VERSION >= 0x300
4774/* Code referring to "BYTES" corresponds to Python3 'bytes' and "OBJECT" to any Python object. */
4775static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_BYTES_OBJECT(PyObject *operand1,
4776 PyObject *operand2) {
4777 PyTypeObject *type2 = Py_TYPE(operand2);
4778
4779#if defined(_MSC_VER)
4780#pragma warning(push)
4781#pragma warning(disable : 4101)
4782#endif
4783 NUITKA_MAY_BE_UNUSED bool cbool_result;
4784 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4785#if defined(_MSC_VER)
4786#pragma warning(pop)
4787#endif
4788
4789 binaryfunc slot2 = NULL;
4790
4791 if (!(&PyBytes_Type == type2)) {
4792 // Different types, need to consider second value slot.
4793
4794 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
4795 }
4796
4797 if (slot2 != NULL) {
4798 PyObject *x = slot2(operand1, operand2);
4799
4800 if (x != Py_NotImplemented) {
4801 obj_result = x;
4802 goto exit_binary_result_object;
4803 }
4804
4805 Py_DECREF_IMMORTAL(x);
4806 }
4807
4808#if PYTHON_VERSION < 0x300
4809 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
4810 coercion c2 =
4811 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
4812
4813 if (c2 != NULL) {
4814 PyObject *coerced1 = operand1;
4815 PyObject *coerced2 = operand2;
4816
4817 int err = c2(&coerced2, &coerced1);
4818
4819 if (unlikely(err < 0)) {
4820 goto exit_binary_exception;
4821 }
4822
4823 if (err == 0) {
4824 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4825
4826 if (likely(mv == NULL)) {
4827 binaryfunc slot = mv->nb_add;
4828
4829 if (likely(slot != NULL)) {
4830 PyObject *x = slot(coerced1, coerced2);
4831
4832 Py_DECREF(coerced1);
4833 Py_DECREF(coerced2);
4834
4835 obj_result = x;
4836 goto exit_binary_result_object;
4837 }
4838 }
4839
4840 // nb_coerce took a reference.
4841 Py_DECREF(coerced1);
4842 Py_DECREF(coerced2);
4843 }
4844 }
4845 }
4846#endif
4847
4848 {
4849 PyObject *o = PyBytes_Type.tp_as_sequence->sq_concat(operand1, operand2);
4850 obj_result = o;
4851 goto exit_binary_result_object;
4852 }
4853
4854 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
4855
4856exit_binary_result_object:
4857 return obj_result;
4858
4859#if PYTHON_VERSION < 0x300
4860exit_binary_exception:
4861 return NULL;
4862#endif
4863}
4864static PyObject *_BINARY_OPERATION_ADD_OBJECT_BYTES_OBJECT(PyObject *operand1, PyObject *operand2) {
4865 CHECK_OBJECT(operand1);
4866 assert(PyBytes_CheckExact(operand1));
4867 CHECK_OBJECT(operand2);
4868
4869 PyTypeObject *type2 = Py_TYPE(operand2);
4870
4871 if (&PyBytes_Type == type2) {
4872 PyObject *result;
4873
4874 // return _BINARY_OPERATION_ADD_OBJECT_BYTES_BYTES(operand1, operand2);
4875
4876 // Not every code path will make use of all possible results.
4877 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4878
4879 PyObject *x = PyBytes_Type.tp_as_sequence->sq_concat(operand1, operand2);
4880 assert(x != Py_NotImplemented);
4881
4882 obj_result = x;
4883 goto exit_result_object;
4884
4885 exit_result_object:
4886 if (unlikely(obj_result == NULL)) {
4887 goto exit_result_exception;
4888 }
4889 result = obj_result;
4890 goto exit_result_ok;
4891
4892 exit_result_ok:
4893 return result;
4894
4895 exit_result_exception:
4896 return NULL;
4897 }
4898
4899 return __BINARY_OPERATION_ADD_OBJECT_BYTES_OBJECT(operand1, operand2);
4900}
4901
4902PyObject *BINARY_OPERATION_ADD_OBJECT_BYTES_OBJECT(PyObject *operand1, PyObject *operand2) {
4903 return _BINARY_OPERATION_ADD_OBJECT_BYTES_OBJECT(operand1, operand2);
4904}
4905#endif
4906
4907/* Code referring to "TUPLE" corresponds to Python 'tuple' and "TUPLE" to Python 'tuple'. */
4908static PyObject *_BINARY_OPERATION_ADD_OBJECT_TUPLE_TUPLE(PyObject *operand1, PyObject *operand2) {
4909 CHECK_OBJECT(operand1);
4910 assert(PyTuple_CheckExact(operand1));
4911 CHECK_OBJECT(operand2);
4912 assert(PyTuple_CheckExact(operand2));
4913
4914 PyObject *result;
4915
4916 // Not every code path will make use of all possible results.
4917 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4918
4919 // TODO: Have this more globally passed in
4920 PyThreadState *tstate = PyThreadState_GET();
4921
4922 PyObject *x = TUPLE_CONCAT(tstate, operand1, operand2);
4923
4924 assert(x != Py_NotImplemented);
4925 obj_result = x;
4926 goto exit_result_object;
4927
4928exit_result_object:
4929 if (unlikely(obj_result == NULL)) {
4930 goto exit_result_exception;
4931 }
4932 result = obj_result;
4933 goto exit_result_ok;
4934
4935exit_result_ok:
4936 return result;
4937
4938exit_result_exception:
4939 return NULL;
4940}
4941
4942PyObject *BINARY_OPERATION_ADD_OBJECT_TUPLE_TUPLE(PyObject *operand1, PyObject *operand2) {
4943 return _BINARY_OPERATION_ADD_OBJECT_TUPLE_TUPLE(operand1, operand2);
4944}
4945
4946/* Code referring to "OBJECT" corresponds to any Python object and "TUPLE" to Python 'tuple'. */
4947static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_TUPLE(PyObject *operand1,
4948 PyObject *operand2) {
4949 PyTypeObject *type1 = Py_TYPE(operand1);
4950
4951#if defined(_MSC_VER)
4952#pragma warning(push)
4953#pragma warning(disable : 4101)
4954#endif
4955 NUITKA_MAY_BE_UNUSED bool cbool_result;
4956 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4957#if defined(_MSC_VER)
4958#pragma warning(pop)
4959#endif
4960
4961 binaryfunc slot1 =
4962 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
4963
4964 if (slot1 != NULL) {
4965 PyObject *x = slot1(operand1, operand2);
4966
4967 if (x != Py_NotImplemented) {
4968 obj_result = x;
4969 goto exit_binary_result_object;
4970 }
4971
4972 Py_DECREF_IMMORTAL(x);
4973 }
4974
4975#if PYTHON_VERSION < 0x300
4976 if (!NEW_STYLE_NUMBER_TYPE(type1) || !0) {
4977 coercion c1 =
4978 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
4979
4980 if (c1 != NULL) {
4981 PyObject *coerced1 = operand1;
4982 PyObject *coerced2 = operand2;
4983
4984 int err = c1(&coerced1, &coerced2);
4985
4986 if (unlikely(err < 0)) {
4987 goto exit_binary_exception;
4988 }
4989
4990 if (err == 0) {
4991 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4992
4993 if (likely(mv == NULL)) {
4994 binaryfunc slot = mv->nb_add;
4995
4996 if (likely(slot != NULL)) {
4997 PyObject *x = slot(coerced1, coerced2);
4998
4999 Py_DECREF(coerced1);
5000 Py_DECREF(coerced2);
5001
5002 obj_result = x;
5003 goto exit_binary_result_object;
5004 }
5005 }
5006
5007 // nb_coerce took a reference.
5008 Py_DECREF(coerced1);
5009 Py_DECREF(coerced2);
5010 }
5011 }
5012 }
5013#endif
5014
5015 {
5016 // Special case for "+" and "*", also works as sequence concat/repeat.
5017 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
5018
5019 if (sq_slot != NULL) {
5020 PyObject *result = sq_slot(operand1, operand2);
5021
5022 obj_result = result;
5023 goto exit_binary_result_object;
5024 }
5025 }
5026
5027 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'tuple'", type1->tp_name);
5028 goto exit_binary_exception;
5029
5030exit_binary_result_object:
5031 return obj_result;
5032
5033exit_binary_exception:
5034 return NULL;
5035}
5036static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_TUPLE(PyObject *operand1, PyObject *operand2) {
5037 CHECK_OBJECT(operand1);
5038 CHECK_OBJECT(operand2);
5039 assert(PyTuple_CheckExact(operand2));
5040
5041 PyTypeObject *type1 = Py_TYPE(operand1);
5042
5043 if (type1 == &PyTuple_Type) {
5044 PyObject *result;
5045
5046 // return _BINARY_OPERATION_ADD_OBJECT_TUPLE_TUPLE(operand1, operand2);
5047
5048 // Not every code path will make use of all possible results.
5049 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5050
5051 // TODO: Have this more globally passed in
5052 PyThreadState *tstate = PyThreadState_GET();
5053
5054 PyObject *x = TUPLE_CONCAT(tstate, operand1, operand2);
5055
5056 assert(x != Py_NotImplemented);
5057 obj_result = x;
5058 goto exit_result_object;
5059
5060 exit_result_object:
5061 if (unlikely(obj_result == NULL)) {
5062 goto exit_result_exception;
5063 }
5064 result = obj_result;
5065 goto exit_result_ok;
5066
5067 exit_result_ok:
5068 return result;
5069
5070 exit_result_exception:
5071 return NULL;
5072 }
5073
5074 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_TUPLE(operand1, operand2);
5075}
5076
5077PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_TUPLE(PyObject *operand1, PyObject *operand2) {
5078 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_TUPLE(operand1, operand2);
5079}
5080
5081/* Code referring to "TUPLE" corresponds to Python 'tuple' and "OBJECT" to any Python object. */
5082static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_TUPLE_OBJECT(PyObject *operand1,
5083 PyObject *operand2) {
5084 PyTypeObject *type2 = Py_TYPE(operand2);
5085
5086#if defined(_MSC_VER)
5087#pragma warning(push)
5088#pragma warning(disable : 4101)
5089#endif
5090 NUITKA_MAY_BE_UNUSED bool cbool_result;
5091 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5092#if defined(_MSC_VER)
5093#pragma warning(pop)
5094#endif
5095
5096 binaryfunc slot2 = NULL;
5097
5098 if (!(&PyTuple_Type == type2)) {
5099 // Different types, need to consider second value slot.
5100
5101 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
5102 }
5103
5104 if (slot2 != NULL) {
5105 PyObject *x = slot2(operand1, operand2);
5106
5107 if (x != Py_NotImplemented) {
5108 obj_result = x;
5109 goto exit_binary_result_object;
5110 }
5111
5112 Py_DECREF_IMMORTAL(x);
5113 }
5114
5115#if PYTHON_VERSION < 0x300
5116 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
5117 coercion c2 =
5118 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
5119
5120 if (c2 != NULL) {
5121 PyObject *coerced1 = operand1;
5122 PyObject *coerced2 = operand2;
5123
5124 int err = c2(&coerced2, &coerced1);
5125
5126 if (unlikely(err < 0)) {
5127 goto exit_binary_exception;
5128 }
5129
5130 if (err == 0) {
5131 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
5132
5133 if (likely(mv == NULL)) {
5134 binaryfunc slot = mv->nb_add;
5135
5136 if (likely(slot != NULL)) {
5137 PyObject *x = slot(coerced1, coerced2);
5138
5139 Py_DECREF(coerced1);
5140 Py_DECREF(coerced2);
5141
5142 obj_result = x;
5143 goto exit_binary_result_object;
5144 }
5145 }
5146
5147 // nb_coerce took a reference.
5148 Py_DECREF(coerced1);
5149 Py_DECREF(coerced2);
5150 }
5151 }
5152 }
5153#endif
5154
5155 {
5156 PyObject *o = PyTuple_Type.tp_as_sequence->sq_concat(operand1, operand2);
5157 obj_result = o;
5158 goto exit_binary_result_object;
5159 }
5160
5161 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5162
5163exit_binary_result_object:
5164 return obj_result;
5165
5166#if PYTHON_VERSION < 0x300
5167exit_binary_exception:
5168 return NULL;
5169#endif
5170}
5171static PyObject *_BINARY_OPERATION_ADD_OBJECT_TUPLE_OBJECT(PyObject *operand1, PyObject *operand2) {
5172 CHECK_OBJECT(operand1);
5173 assert(PyTuple_CheckExact(operand1));
5174 CHECK_OBJECT(operand2);
5175
5176 PyTypeObject *type2 = Py_TYPE(operand2);
5177
5178 if (&PyTuple_Type == type2) {
5179 PyObject *result;
5180
5181 // return _BINARY_OPERATION_ADD_OBJECT_TUPLE_TUPLE(operand1, operand2);
5182
5183 // Not every code path will make use of all possible results.
5184 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5185
5186 // TODO: Have this more globally passed in
5187 PyThreadState *tstate = PyThreadState_GET();
5188
5189 PyObject *x = TUPLE_CONCAT(tstate, operand1, operand2);
5190
5191 assert(x != Py_NotImplemented);
5192 obj_result = x;
5193 goto exit_result_object;
5194
5195 exit_result_object:
5196 if (unlikely(obj_result == NULL)) {
5197 goto exit_result_exception;
5198 }
5199 result = obj_result;
5200 goto exit_result_ok;
5201
5202 exit_result_ok:
5203 return result;
5204
5205 exit_result_exception:
5206 return NULL;
5207 }
5208
5209 return __BINARY_OPERATION_ADD_OBJECT_TUPLE_OBJECT(operand1, operand2);
5210}
5211
5212PyObject *BINARY_OPERATION_ADD_OBJECT_TUPLE_OBJECT(PyObject *operand1, PyObject *operand2) {
5213 return _BINARY_OPERATION_ADD_OBJECT_TUPLE_OBJECT(operand1, operand2);
5214}
5215
5216/* Code referring to "LIST" corresponds to Python 'list' and "LIST" to Python 'list'. */
5217static PyObject *_BINARY_OPERATION_ADD_OBJECT_LIST_LIST(PyObject *operand1, PyObject *operand2) {
5218 CHECK_OBJECT(operand1);
5219 assert(PyList_CheckExact(operand1));
5220 CHECK_OBJECT(operand2);
5221 assert(PyList_CheckExact(operand2));
5222
5223 PyObject *result;
5224
5225 // Not every code path will make use of all possible results.
5226 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5227
5228 // TODO: Have this more globally passed in
5229 PyThreadState *tstate = PyThreadState_GET();
5230
5231 PyObject *x = LIST_CONCAT(tstate, operand1, operand2);
5232 assert(x != Py_NotImplemented);
5233
5234 obj_result = x;
5235 goto exit_result_object;
5236
5237exit_result_object:
5238 if (unlikely(obj_result == NULL)) {
5239 goto exit_result_exception;
5240 }
5241 result = obj_result;
5242 goto exit_result_ok;
5243
5244exit_result_ok:
5245 return result;
5246
5247exit_result_exception:
5248 return NULL;
5249}
5250
5251PyObject *BINARY_OPERATION_ADD_OBJECT_LIST_LIST(PyObject *operand1, PyObject *operand2) {
5252 return _BINARY_OPERATION_ADD_OBJECT_LIST_LIST(operand1, operand2);
5253}
5254
5255/* Code referring to "OBJECT" corresponds to any Python object and "LIST" to Python 'list'. */
5256static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
5257 PyTypeObject *type1 = Py_TYPE(operand1);
5258
5259#if defined(_MSC_VER)
5260#pragma warning(push)
5261#pragma warning(disable : 4101)
5262#endif
5263 NUITKA_MAY_BE_UNUSED bool cbool_result;
5264 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5265#if defined(_MSC_VER)
5266#pragma warning(pop)
5267#endif
5268
5269 binaryfunc slot1 =
5270 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
5271
5272 if (slot1 != NULL) {
5273 PyObject *x = slot1(operand1, operand2);
5274
5275 if (x != Py_NotImplemented) {
5276 obj_result = x;
5277 goto exit_binary_result_object;
5278 }
5279
5280 Py_DECREF_IMMORTAL(x);
5281 }
5282
5283#if PYTHON_VERSION < 0x300
5284 if (!NEW_STYLE_NUMBER_TYPE(type1) || !0) {
5285 coercion c1 =
5286 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
5287
5288 if (c1 != NULL) {
5289 PyObject *coerced1 = operand1;
5290 PyObject *coerced2 = operand2;
5291
5292 int err = c1(&coerced1, &coerced2);
5293
5294 if (unlikely(err < 0)) {
5295 goto exit_binary_exception;
5296 }
5297
5298 if (err == 0) {
5299 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
5300
5301 if (likely(mv == NULL)) {
5302 binaryfunc slot = mv->nb_add;
5303
5304 if (likely(slot != NULL)) {
5305 PyObject *x = slot(coerced1, coerced2);
5306
5307 Py_DECREF(coerced1);
5308 Py_DECREF(coerced2);
5309
5310 obj_result = x;
5311 goto exit_binary_result_object;
5312 }
5313 }
5314
5315 // nb_coerce took a reference.
5316 Py_DECREF(coerced1);
5317 Py_DECREF(coerced2);
5318 }
5319 }
5320 }
5321#endif
5322
5323 {
5324 // Special case for "+" and "*", also works as sequence concat/repeat.
5325 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
5326
5327 if (sq_slot != NULL) {
5328 PyObject *result = sq_slot(operand1, operand2);
5329
5330 obj_result = result;
5331 goto exit_binary_result_object;
5332 }
5333 }
5334
5335 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'list'", type1->tp_name);
5336 goto exit_binary_exception;
5337
5338exit_binary_result_object:
5339 return obj_result;
5340
5341exit_binary_exception:
5342 return NULL;
5343}
5344static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
5345 CHECK_OBJECT(operand1);
5346 CHECK_OBJECT(operand2);
5347 assert(PyList_CheckExact(operand2));
5348
5349 PyTypeObject *type1 = Py_TYPE(operand1);
5350
5351 if (type1 == &PyList_Type) {
5352 PyObject *result;
5353
5354 // return _BINARY_OPERATION_ADD_OBJECT_LIST_LIST(operand1, operand2);
5355
5356 // Not every code path will make use of all possible results.
5357 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5358
5359 // TODO: Have this more globally passed in
5360 PyThreadState *tstate = PyThreadState_GET();
5361
5362 PyObject *x = LIST_CONCAT(tstate, operand1, operand2);
5363 assert(x != Py_NotImplemented);
5364
5365 obj_result = x;
5366 goto exit_result_object;
5367
5368 exit_result_object:
5369 if (unlikely(obj_result == NULL)) {
5370 goto exit_result_exception;
5371 }
5372 result = obj_result;
5373 goto exit_result_ok;
5374
5375 exit_result_ok:
5376 return result;
5377
5378 exit_result_exception:
5379 return NULL;
5380 }
5381
5382 return __BINARY_OPERATION_ADD_OBJECT_OBJECT_LIST(operand1, operand2);
5383}
5384
5385PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
5386 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_LIST(operand1, operand2);
5387}
5388
5389/* Code referring to "LIST" corresponds to Python 'list' and "OBJECT" to any Python object. */
5390static HEDLEY_NEVER_INLINE PyObject *__BINARY_OPERATION_ADD_OBJECT_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
5391 PyTypeObject *type2 = Py_TYPE(operand2);
5392
5393#if defined(_MSC_VER)
5394#pragma warning(push)
5395#pragma warning(disable : 4101)
5396#endif
5397 NUITKA_MAY_BE_UNUSED bool cbool_result;
5398 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5399#if defined(_MSC_VER)
5400#pragma warning(pop)
5401#endif
5402
5403 binaryfunc slot2 = NULL;
5404
5405 if (!(&PyList_Type == type2)) {
5406 // Different types, need to consider second value slot.
5407
5408 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
5409 }
5410
5411 if (slot2 != NULL) {
5412 PyObject *x = slot2(operand1, operand2);
5413
5414 if (x != Py_NotImplemented) {
5415 obj_result = x;
5416 goto exit_binary_result_object;
5417 }
5418
5419 Py_DECREF_IMMORTAL(x);
5420 }
5421
5422#if PYTHON_VERSION < 0x300
5423 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
5424 coercion c2 =
5425 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
5426
5427 if (c2 != NULL) {
5428 PyObject *coerced1 = operand1;
5429 PyObject *coerced2 = operand2;
5430
5431 int err = c2(&coerced2, &coerced1);
5432
5433 if (unlikely(err < 0)) {
5434 goto exit_binary_exception;
5435 }
5436
5437 if (err == 0) {
5438 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
5439
5440 if (likely(mv == NULL)) {
5441 binaryfunc slot = mv->nb_add;
5442
5443 if (likely(slot != NULL)) {
5444 PyObject *x = slot(coerced1, coerced2);
5445
5446 Py_DECREF(coerced1);
5447 Py_DECREF(coerced2);
5448
5449 obj_result = x;
5450 goto exit_binary_result_object;
5451 }
5452 }
5453
5454 // nb_coerce took a reference.
5455 Py_DECREF(coerced1);
5456 Py_DECREF(coerced2);
5457 }
5458 }
5459 }
5460#endif
5461
5462 {
5463 PyObject *o = PyList_Type.tp_as_sequence->sq_concat(operand1, operand2);
5464 obj_result = o;
5465 goto exit_binary_result_object;
5466 }
5467
5468 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5469
5470exit_binary_result_object:
5471 return obj_result;
5472
5473#if PYTHON_VERSION < 0x300
5474exit_binary_exception:
5475 return NULL;
5476#endif
5477}
5478static PyObject *_BINARY_OPERATION_ADD_OBJECT_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
5479 CHECK_OBJECT(operand1);
5480 assert(PyList_CheckExact(operand1));
5481 CHECK_OBJECT(operand2);
5482
5483 PyTypeObject *type2 = Py_TYPE(operand2);
5484
5485 if (&PyList_Type == type2) {
5486 PyObject *result;
5487
5488 // return _BINARY_OPERATION_ADD_OBJECT_LIST_LIST(operand1, operand2);
5489
5490 // Not every code path will make use of all possible results.
5491 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5492
5493 // TODO: Have this more globally passed in
5494 PyThreadState *tstate = PyThreadState_GET();
5495
5496 PyObject *x = LIST_CONCAT(tstate, operand1, operand2);
5497 assert(x != Py_NotImplemented);
5498
5499 obj_result = x;
5500 goto exit_result_object;
5501
5502 exit_result_object:
5503 if (unlikely(obj_result == NULL)) {
5504 goto exit_result_exception;
5505 }
5506 result = obj_result;
5507 goto exit_result_ok;
5508
5509 exit_result_ok:
5510 return result;
5511
5512 exit_result_exception:
5513 return NULL;
5514 }
5515
5516 return __BINARY_OPERATION_ADD_OBJECT_LIST_OBJECT(operand1, operand2);
5517}
5518
5519PyObject *BINARY_OPERATION_ADD_OBJECT_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
5520 return _BINARY_OPERATION_ADD_OBJECT_LIST_OBJECT(operand1, operand2);
5521}
5522
5523/* Code referring to "LIST" corresponds to Python 'list' and "LIST" to Python 'list'. */
5524static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LIST_LIST(PyObject *operand1, PyObject *operand2) {
5525 CHECK_OBJECT(operand1);
5526 assert(PyList_CheckExact(operand1));
5527 CHECK_OBJECT(operand2);
5528 assert(PyList_CheckExact(operand2));
5529
5530 nuitka_bool result;
5531
5532 // Not every code path will make use of all possible results.
5533 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5534
5535 // TODO: Have this more globally passed in
5536 PyThreadState *tstate = PyThreadState_GET();
5537
5538 PyObject *x = LIST_CONCAT(tstate, operand1, operand2);
5539 assert(x != Py_NotImplemented);
5540
5541 obj_result = x;
5542 goto exit_result_object;
5543
5544exit_result_object:
5545 if (unlikely(obj_result == NULL)) {
5546 goto exit_result_exception;
5547 }
5548 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5549 Py_DECREF(obj_result);
5550 goto exit_result_ok;
5551
5552exit_result_ok:
5553 return result;
5554
5555exit_result_exception:
5556 return NUITKA_BOOL_EXCEPTION;
5557}
5558
5559nuitka_bool BINARY_OPERATION_ADD_NBOOL_LIST_LIST(PyObject *operand1, PyObject *operand2) {
5560 return _BINARY_OPERATION_ADD_NBOOL_LIST_LIST(operand1, operand2);
5561}
5562
5563/* Code referring to "OBJECT" corresponds to any Python object and "LIST" to Python 'list'. */
5564static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_OBJECT_LIST(PyObject *operand1,
5565 PyObject *operand2) {
5566 PyTypeObject *type1 = Py_TYPE(operand1);
5567
5568#if defined(_MSC_VER)
5569#pragma warning(push)
5570#pragma warning(disable : 4101)
5571#endif
5572 NUITKA_MAY_BE_UNUSED bool cbool_result;
5573 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5574#if defined(_MSC_VER)
5575#pragma warning(pop)
5576#endif
5577
5578 binaryfunc slot1 =
5579 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
5580
5581 if (slot1 != NULL) {
5582 PyObject *x = slot1(operand1, operand2);
5583
5584 if (x != Py_NotImplemented) {
5585 obj_result = x;
5586 goto exit_binary_result_object;
5587 }
5588
5589 Py_DECREF_IMMORTAL(x);
5590 }
5591
5592#if PYTHON_VERSION < 0x300
5593 if (!NEW_STYLE_NUMBER_TYPE(type1) || !0) {
5594 coercion c1 =
5595 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
5596
5597 if (c1 != NULL) {
5598 PyObject *coerced1 = operand1;
5599 PyObject *coerced2 = operand2;
5600
5601 int err = c1(&coerced1, &coerced2);
5602
5603 if (unlikely(err < 0)) {
5604 goto exit_binary_exception;
5605 }
5606
5607 if (err == 0) {
5608 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
5609
5610 if (likely(mv == NULL)) {
5611 binaryfunc slot = mv->nb_add;
5612
5613 if (likely(slot != NULL)) {
5614 PyObject *x = slot(coerced1, coerced2);
5615
5616 Py_DECREF(coerced1);
5617 Py_DECREF(coerced2);
5618
5619 obj_result = x;
5620 goto exit_binary_result_object;
5621 }
5622 }
5623
5624 // nb_coerce took a reference.
5625 Py_DECREF(coerced1);
5626 Py_DECREF(coerced2);
5627 }
5628 }
5629 }
5630#endif
5631
5632 {
5633 // Special case for "+" and "*", also works as sequence concat/repeat.
5634 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
5635
5636 if (sq_slot != NULL) {
5637 PyObject *result = sq_slot(operand1, operand2);
5638
5639 obj_result = result;
5640 goto exit_binary_result_object;
5641 }
5642 }
5643
5644 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and 'list'", type1->tp_name);
5645 goto exit_binary_exception;
5646
5647exit_binary_result_object:
5648 if (unlikely(obj_result == NULL)) {
5649 return NUITKA_BOOL_EXCEPTION;
5650 }
5651
5652 {
5653 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5654 Py_DECREF(obj_result);
5655 return r;
5656 }
5657
5658exit_binary_exception:
5659 return NUITKA_BOOL_EXCEPTION;
5660}
5661static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
5662 CHECK_OBJECT(operand1);
5663 CHECK_OBJECT(operand2);
5664 assert(PyList_CheckExact(operand2));
5665
5666 PyTypeObject *type1 = Py_TYPE(operand1);
5667
5668 if (type1 == &PyList_Type) {
5669 nuitka_bool result;
5670
5671 // return _BINARY_OPERATION_ADD_NBOOL_LIST_LIST(operand1, operand2);
5672
5673 // Not every code path will make use of all possible results.
5674 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5675
5676 // TODO: Have this more globally passed in
5677 PyThreadState *tstate = PyThreadState_GET();
5678
5679 PyObject *x = LIST_CONCAT(tstate, operand1, operand2);
5680 assert(x != Py_NotImplemented);
5681
5682 obj_result = x;
5683 goto exit_result_object;
5684
5685 exit_result_object:
5686 if (unlikely(obj_result == NULL)) {
5687 goto exit_result_exception;
5688 }
5689 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5690 Py_DECREF(obj_result);
5691 goto exit_result_ok;
5692
5693 exit_result_ok:
5694 return result;
5695
5696 exit_result_exception:
5697 return NUITKA_BOOL_EXCEPTION;
5698 }
5699
5700 return __BINARY_OPERATION_ADD_NBOOL_OBJECT_LIST(operand1, operand2);
5701}
5702
5703nuitka_bool BINARY_OPERATION_ADD_NBOOL_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
5704 return _BINARY_OPERATION_ADD_NBOOL_OBJECT_LIST(operand1, operand2);
5705}
5706
5707/* Code referring to "LIST" corresponds to Python 'list' and "OBJECT" to any Python object. */
5708static HEDLEY_NEVER_INLINE nuitka_bool __BINARY_OPERATION_ADD_NBOOL_LIST_OBJECT(PyObject *operand1,
5709 PyObject *operand2) {
5710 PyTypeObject *type2 = Py_TYPE(operand2);
5711
5712#if defined(_MSC_VER)
5713#pragma warning(push)
5714#pragma warning(disable : 4101)
5715#endif
5716 NUITKA_MAY_BE_UNUSED bool cbool_result;
5717 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5718#if defined(_MSC_VER)
5719#pragma warning(pop)
5720#endif
5721
5722 binaryfunc slot2 = NULL;
5723
5724 if (!(&PyList_Type == type2)) {
5725 // Different types, need to consider second value slot.
5726
5727 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
5728 }
5729
5730 if (slot2 != NULL) {
5731 PyObject *x = slot2(operand1, operand2);
5732
5733 if (x != Py_NotImplemented) {
5734 obj_result = x;
5735 goto exit_binary_result_object;
5736 }
5737
5738 Py_DECREF_IMMORTAL(x);
5739 }
5740
5741#if PYTHON_VERSION < 0x300
5742 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
5743 coercion c2 =
5744 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
5745
5746 if (c2 != NULL) {
5747 PyObject *coerced1 = operand1;
5748 PyObject *coerced2 = operand2;
5749
5750 int err = c2(&coerced2, &coerced1);
5751
5752 if (unlikely(err < 0)) {
5753 goto exit_binary_exception;
5754 }
5755
5756 if (err == 0) {
5757 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
5758
5759 if (likely(mv == NULL)) {
5760 binaryfunc slot = mv->nb_add;
5761
5762 if (likely(slot != NULL)) {
5763 PyObject *x = slot(coerced1, coerced2);
5764
5765 Py_DECREF(coerced1);
5766 Py_DECREF(coerced2);
5767
5768 obj_result = x;
5769 goto exit_binary_result_object;
5770 }
5771 }
5772
5773 // nb_coerce took a reference.
5774 Py_DECREF(coerced1);
5775 Py_DECREF(coerced2);
5776 }
5777 }
5778 }
5779#endif
5780
5781 {
5782 PyObject *o = PyList_Type.tp_as_sequence->sq_concat(operand1, operand2);
5783 obj_result = o;
5784 goto exit_binary_result_object;
5785 }
5786
5787 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5788
5789exit_binary_result_object:
5790 if (unlikely(obj_result == NULL)) {
5791 return NUITKA_BOOL_EXCEPTION;
5792 }
5793
5794 {
5795 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5796 Py_DECREF(obj_result);
5797 return r;
5798 }
5799
5800#if PYTHON_VERSION < 0x300
5801exit_binary_exception:
5802 return NUITKA_BOOL_EXCEPTION;
5803#endif
5804}
5805static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
5806 CHECK_OBJECT(operand1);
5807 assert(PyList_CheckExact(operand1));
5808 CHECK_OBJECT(operand2);
5809
5810 PyTypeObject *type2 = Py_TYPE(operand2);
5811
5812 if (&PyList_Type == type2) {
5813 nuitka_bool result;
5814
5815 // return _BINARY_OPERATION_ADD_NBOOL_LIST_LIST(operand1, operand2);
5816
5817 // Not every code path will make use of all possible results.
5818 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5819
5820 // TODO: Have this more globally passed in
5821 PyThreadState *tstate = PyThreadState_GET();
5822
5823 PyObject *x = LIST_CONCAT(tstate, operand1, operand2);
5824 assert(x != Py_NotImplemented);
5825
5826 obj_result = x;
5827 goto exit_result_object;
5828
5829 exit_result_object:
5830 if (unlikely(obj_result == NULL)) {
5831 goto exit_result_exception;
5832 }
5833 result = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5834 Py_DECREF(obj_result);
5835 goto exit_result_ok;
5836
5837 exit_result_ok:
5838 return result;
5839
5840 exit_result_exception:
5841 return NUITKA_BOOL_EXCEPTION;
5842 }
5843
5844 return __BINARY_OPERATION_ADD_NBOOL_LIST_OBJECT(operand1, operand2);
5845}
5846
5847nuitka_bool BINARY_OPERATION_ADD_NBOOL_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
5848 return _BINARY_OPERATION_ADD_NBOOL_LIST_OBJECT(operand1, operand2);
5849}
5850
5851#if PYTHON_VERSION < 0x300
5852/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "STR" to Python2 'str'. */
5853static PyObject *_BINARY_OPERATION_ADD_OBJECT_UNICODE_STR(PyObject *operand1, PyObject *operand2) {
5854 CHECK_OBJECT(operand1);
5855 assert(PyUnicode_CheckExact(operand1));
5856 CHECK_OBJECT(operand2);
5857 assert(PyString_CheckExact(operand2));
5858
5859#if defined(_MSC_VER)
5860#pragma warning(push)
5861#pragma warning(disable : 4101)
5862#endif
5863 NUITKA_MAY_BE_UNUSED bool cbool_result;
5864 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5865#if defined(_MSC_VER)
5866#pragma warning(pop)
5867#endif
5868
5869 // Statically recognized that coercion is not possible with these types
5870
5871 {
5872 PyObject *o = PyUnicode_Type.tp_as_sequence->sq_concat(operand1, operand2);
5873 obj_result = o;
5874 goto exit_binary_result_object;
5875 }
5876
5877 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5878
5879exit_binary_result_object:
5880 return obj_result;
5881}
5882
5883PyObject *BINARY_OPERATION_ADD_OBJECT_UNICODE_STR(PyObject *operand1, PyObject *operand2) {
5884 return _BINARY_OPERATION_ADD_OBJECT_UNICODE_STR(operand1, operand2);
5885}
5886#endif
5887
5888#if PYTHON_VERSION < 0x300
5889/* Code referring to "STR" corresponds to Python2 'str' and "UNICODE" to Python2 'unicode', Python3 'str'. */
5890static PyObject *_BINARY_OPERATION_ADD_OBJECT_STR_UNICODE(PyObject *operand1, PyObject *operand2) {
5891 CHECK_OBJECT(operand1);
5892 assert(PyString_CheckExact(operand1));
5893 CHECK_OBJECT(operand2);
5894 assert(PyUnicode_CheckExact(operand2));
5895
5896#if defined(_MSC_VER)
5897#pragma warning(push)
5898#pragma warning(disable : 4101)
5899#endif
5900 NUITKA_MAY_BE_UNUSED bool cbool_result;
5901 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5902#if defined(_MSC_VER)
5903#pragma warning(pop)
5904#endif
5905
5906 // Statically recognized that coercion is not possible with these types
5907
5908 {
5909 PyObject *o = PyUnicode_Type.tp_as_sequence->sq_concat(operand1, operand2);
5910 obj_result = o;
5911 goto exit_binary_result_object;
5912 }
5913
5914 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5915
5916exit_binary_result_object:
5917 return obj_result;
5918}
5919
5920PyObject *BINARY_OPERATION_ADD_OBJECT_STR_UNICODE(PyObject *operand1, PyObject *operand2) {
5921 return _BINARY_OPERATION_ADD_OBJECT_STR_UNICODE(operand1, operand2);
5922}
5923#endif
5924
5925#if PYTHON_VERSION < 0x300
5926/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "STR" to Python2 'str'. */
5927static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_UNICODE_STR(PyObject *operand1, PyObject *operand2) {
5928 CHECK_OBJECT(operand1);
5929 assert(PyUnicode_CheckExact(operand1));
5930 CHECK_OBJECT(operand2);
5931 assert(PyString_CheckExact(operand2));
5932
5933#if defined(_MSC_VER)
5934#pragma warning(push)
5935#pragma warning(disable : 4101)
5936#endif
5937 NUITKA_MAY_BE_UNUSED bool cbool_result;
5938 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5939#if defined(_MSC_VER)
5940#pragma warning(pop)
5941#endif
5942
5943 // Statically recognized that coercion is not possible with these types
5944
5945 {
5946 PyObject *o = PyUnicode_Type.tp_as_sequence->sq_concat(operand1, operand2);
5947 obj_result = o;
5948 goto exit_binary_result_object;
5949 }
5950
5951 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5952
5953exit_binary_result_object:
5954 if (unlikely(obj_result == NULL)) {
5955 return NUITKA_BOOL_EXCEPTION;
5956 }
5957
5958 {
5959 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5960 Py_DECREF(obj_result);
5961 return r;
5962 }
5963}
5964
5965nuitka_bool BINARY_OPERATION_ADD_NBOOL_UNICODE_STR(PyObject *operand1, PyObject *operand2) {
5966 return _BINARY_OPERATION_ADD_NBOOL_UNICODE_STR(operand1, operand2);
5967}
5968#endif
5969
5970#if PYTHON_VERSION < 0x300
5971/* Code referring to "STR" corresponds to Python2 'str' and "UNICODE" to Python2 'unicode', Python3 'str'. */
5972static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_STR_UNICODE(PyObject *operand1, PyObject *operand2) {
5973 CHECK_OBJECT(operand1);
5974 assert(PyString_CheckExact(operand1));
5975 CHECK_OBJECT(operand2);
5976 assert(PyUnicode_CheckExact(operand2));
5977
5978#if defined(_MSC_VER)
5979#pragma warning(push)
5980#pragma warning(disable : 4101)
5981#endif
5982 NUITKA_MAY_BE_UNUSED bool cbool_result;
5983 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
5984#if defined(_MSC_VER)
5985#pragma warning(pop)
5986#endif
5987
5988 // Statically recognized that coercion is not possible with these types
5989
5990 {
5991 PyObject *o = PyUnicode_Type.tp_as_sequence->sq_concat(operand1, operand2);
5992 obj_result = o;
5993 goto exit_binary_result_object;
5994 }
5995
5996 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
5997
5998exit_binary_result_object:
5999 if (unlikely(obj_result == NULL)) {
6000 return NUITKA_BOOL_EXCEPTION;
6001 }
6002
6003 {
6004 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6005 Py_DECREF(obj_result);
6006 return r;
6007 }
6008}
6009
6010nuitka_bool BINARY_OPERATION_ADD_NBOOL_STR_UNICODE(PyObject *operand1, PyObject *operand2) {
6011 return _BINARY_OPERATION_ADD_NBOOL_STR_UNICODE(operand1, operand2);
6012}
6013#endif
6014
6015/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
6016static PyObject *_BINARY_OPERATION_ADD_OBJECT_OBJECT_OBJECT(PyObject *operand1, PyObject *operand2) {
6017 CHECK_OBJECT(operand1);
6018 CHECK_OBJECT(operand2);
6019
6020#if PYTHON_VERSION < 0x300
6021 if (PyInt_CheckExact(operand1) && PyInt_CheckExact(operand2)) {
6022 PyObject *result;
6023
6024 // Not every code path will make use of all possible results.
6025#if defined(_MSC_VER)
6026#pragma warning(push)
6027#pragma warning(disable : 4101)
6028#endif
6029 NUITKA_MAY_BE_UNUSED bool cbool_result;
6030 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
6031 NUITKA_MAY_BE_UNUSED long clong_result;
6032 NUITKA_MAY_BE_UNUSED double cfloat_result;
6033#if defined(_MSC_VER)
6034#pragma warning(pop)
6035#endif
6036
6037 CHECK_OBJECT(operand1);
6038 assert(PyInt_CheckExact(operand1));
6039 CHECK_OBJECT(operand2);
6040 assert(PyInt_CheckExact(operand2));
6041
6042 const long a = PyInt_AS_LONG(operand1);
6043 const long b = PyInt_AS_LONG(operand2);
6044
6045 const long x = (long)((unsigned long)a + b);
6046 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
6047 if (likely(no_overflow)) {
6048 clong_result = x;
6049 goto exit_result_ok_clong;
6050 }
6051
6052 {
6053 PyObject *operand1_object = operand1;
6054 PyObject *operand2_object = operand2;
6055
6056 PyObject *r = PyLong_Type.tp_as_number->nb_add(operand1_object, operand2_object);
6057 assert(r != Py_NotImplemented);
6058
6059 obj_result = r;
6060 goto exit_result_object;
6061 }
6062
6063 exit_result_ok_clong:
6064 result = Nuitka_PyInt_FromLong(clong_result);
6065 goto exit_result_ok;
6066
6067 exit_result_object:
6068 if (unlikely(obj_result == NULL)) {
6069 goto exit_result_exception;
6070 }
6071 result = obj_result;
6072 goto exit_result_ok;
6073
6074 exit_result_ok:
6075 return result;
6076
6077 exit_result_exception:
6078 return NULL;
6079 }
6080#endif
6081
6082 PyTypeObject *type1 = Py_TYPE(operand1);
6083 PyTypeObject *type2 = Py_TYPE(operand2);
6084
6085#if defined(_MSC_VER)
6086#pragma warning(push)
6087#pragma warning(disable : 4101)
6088#endif
6089 NUITKA_MAY_BE_UNUSED bool cbool_result;
6090 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
6091#if defined(_MSC_VER)
6092#pragma warning(pop)
6093#endif
6094
6095 binaryfunc slot1 =
6096 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
6097 binaryfunc slot2 = NULL;
6098
6099 if (!(type1 == type2)) {
6100 // Different types, need to consider second value slot.
6101
6102 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
6103
6104 if (slot1 == slot2) {
6105 slot2 = NULL;
6106 }
6107 }
6108
6109 if (slot1 != NULL) {
6110 if (slot2 != NULL) {
6111 if (Nuitka_Type_IsSubtype(type2, type1)) {
6112 PyObject *x = slot2(operand1, operand2);
6113
6114 if (x != Py_NotImplemented) {
6115 obj_result = x;
6116 goto exit_binary_result_object;
6117 }
6118
6119 Py_DECREF_IMMORTAL(x);
6120 slot2 = NULL;
6121 }
6122 }
6123
6124 PyObject *x = slot1(operand1, operand2);
6125
6126 if (x != Py_NotImplemented) {
6127 obj_result = x;
6128 goto exit_binary_result_object;
6129 }
6130
6131 Py_DECREF_IMMORTAL(x);
6132 }
6133
6134 if (slot2 != NULL) {
6135 PyObject *x = slot2(operand1, operand2);
6136
6137 if (x != Py_NotImplemented) {
6138 obj_result = x;
6139 goto exit_binary_result_object;
6140 }
6141
6142 Py_DECREF_IMMORTAL(x);
6143 }
6144
6145#if PYTHON_VERSION < 0x300
6146 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
6147 coercion c1 =
6148 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
6149
6150 if (c1 != NULL) {
6151 PyObject *coerced1 = operand1;
6152 PyObject *coerced2 = operand2;
6153
6154 int err = c1(&coerced1, &coerced2);
6155
6156 if (unlikely(err < 0)) {
6157 goto exit_binary_exception;
6158 }
6159
6160 if (err == 0) {
6161 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
6162
6163 if (likely(mv == NULL)) {
6164 binaryfunc slot = mv->nb_add;
6165
6166 if (likely(slot != NULL)) {
6167 PyObject *x = slot(coerced1, coerced2);
6168
6169 Py_DECREF(coerced1);
6170 Py_DECREF(coerced2);
6171
6172 obj_result = x;
6173 goto exit_binary_result_object;
6174 }
6175 }
6176
6177 // nb_coerce took a reference.
6178 Py_DECREF(coerced1);
6179 Py_DECREF(coerced2);
6180 }
6181 }
6182 coercion c2 =
6183 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
6184
6185 if (c2 != NULL) {
6186 PyObject *coerced1 = operand1;
6187 PyObject *coerced2 = operand2;
6188
6189 int err = c2(&coerced2, &coerced1);
6190
6191 if (unlikely(err < 0)) {
6192 goto exit_binary_exception;
6193 }
6194
6195 if (err == 0) {
6196 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
6197
6198 if (likely(mv == NULL)) {
6199 binaryfunc slot = mv->nb_add;
6200
6201 if (likely(slot != NULL)) {
6202 PyObject *x = slot(coerced1, coerced2);
6203
6204 Py_DECREF(coerced1);
6205 Py_DECREF(coerced2);
6206
6207 obj_result = x;
6208 goto exit_binary_result_object;
6209 }
6210 }
6211
6212 // nb_coerce took a reference.
6213 Py_DECREF(coerced1);
6214 Py_DECREF(coerced2);
6215 }
6216 }
6217 }
6218#endif
6219
6220 {
6221 // Special case for "+" and "*", also works as sequence concat/repeat.
6222 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
6223
6224 if (sq_slot != NULL) {
6225 PyObject *result = sq_slot(operand1, operand2);
6226
6227 obj_result = result;
6228 goto exit_binary_result_object;
6229 }
6230 }
6231
6232 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and '%s'", type1->tp_name, type2->tp_name);
6233 goto exit_binary_exception;
6234
6235exit_binary_result_object:
6236 return obj_result;
6237
6238exit_binary_exception:
6239 return NULL;
6240}
6241
6242PyObject *BINARY_OPERATION_ADD_OBJECT_OBJECT_OBJECT(PyObject *operand1, PyObject *operand2) {
6243 return _BINARY_OPERATION_ADD_OBJECT_OBJECT_OBJECT(operand1, operand2);
6244}
6245
6246/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
6247static nuitka_bool _BINARY_OPERATION_ADD_NBOOL_OBJECT_OBJECT(PyObject *operand1, PyObject *operand2) {
6248 CHECK_OBJECT(operand1);
6249 CHECK_OBJECT(operand2);
6250
6251#if PYTHON_VERSION < 0x300
6252 if (PyInt_CheckExact(operand1) && PyInt_CheckExact(operand2)) {
6253 nuitka_bool result;
6254
6255 // Not every code path will make use of all possible results.
6256#if defined(_MSC_VER)
6257#pragma warning(push)
6258#pragma warning(disable : 4101)
6259#endif
6260 NUITKA_MAY_BE_UNUSED bool cbool_result;
6261 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
6262 NUITKA_MAY_BE_UNUSED long clong_result;
6263 NUITKA_MAY_BE_UNUSED double cfloat_result;
6264#if defined(_MSC_VER)
6265#pragma warning(pop)
6266#endif
6267
6268 CHECK_OBJECT(operand1);
6269 assert(PyInt_CheckExact(operand1));
6270 CHECK_OBJECT(operand2);
6271 assert(PyInt_CheckExact(operand2));
6272
6273 const long a = PyInt_AS_LONG(operand1);
6274 const long b = PyInt_AS_LONG(operand2);
6275
6276 const long x = (long)((unsigned long)a + b);
6277 bool no_overflow = ((x ^ a) >= 0 || (x ^ b) >= 0);
6278 bool t = !no_overflow || x != 0;
6279
6280 cbool_result = t;
6281 goto exit_result_ok_cbool;
6282
6283 exit_result_ok_cbool:
6284 result = cbool_result ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6285 goto exit_result_ok;
6286
6287 exit_result_ok:
6288 return result;
6289 }
6290#endif
6291
6292 PyTypeObject *type1 = Py_TYPE(operand1);
6293 PyTypeObject *type2 = Py_TYPE(operand2);
6294
6295#if defined(_MSC_VER)
6296#pragma warning(push)
6297#pragma warning(disable : 4101)
6298#endif
6299 NUITKA_MAY_BE_UNUSED bool cbool_result;
6300 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
6301#if defined(_MSC_VER)
6302#pragma warning(pop)
6303#endif
6304
6305 binaryfunc slot1 =
6306 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_add : NULL;
6307 binaryfunc slot2 = NULL;
6308
6309 if (!(type1 == type2)) {
6310 // Different types, need to consider second value slot.
6311
6312 slot2 = (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_add : NULL;
6313
6314 if (slot1 == slot2) {
6315 slot2 = NULL;
6316 }
6317 }
6318
6319 if (slot1 != NULL) {
6320 if (slot2 != NULL) {
6321 if (Nuitka_Type_IsSubtype(type2, type1)) {
6322 PyObject *x = slot2(operand1, operand2);
6323
6324 if (x != Py_NotImplemented) {
6325 obj_result = x;
6326 goto exit_binary_result_object;
6327 }
6328
6329 Py_DECREF_IMMORTAL(x);
6330 slot2 = NULL;
6331 }
6332 }
6333
6334 PyObject *x = slot1(operand1, operand2);
6335
6336 if (x != Py_NotImplemented) {
6337 obj_result = x;
6338 goto exit_binary_result_object;
6339 }
6340
6341 Py_DECREF_IMMORTAL(x);
6342 }
6343
6344 if (slot2 != NULL) {
6345 PyObject *x = slot2(operand1, operand2);
6346
6347 if (x != Py_NotImplemented) {
6348 obj_result = x;
6349 goto exit_binary_result_object;
6350 }
6351
6352 Py_DECREF_IMMORTAL(x);
6353 }
6354
6355#if PYTHON_VERSION < 0x300
6356 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
6357 coercion c1 =
6358 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
6359
6360 if (c1 != NULL) {
6361 PyObject *coerced1 = operand1;
6362 PyObject *coerced2 = operand2;
6363
6364 int err = c1(&coerced1, &coerced2);
6365
6366 if (unlikely(err < 0)) {
6367 goto exit_binary_exception;
6368 }
6369
6370 if (err == 0) {
6371 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
6372
6373 if (likely(mv == NULL)) {
6374 binaryfunc slot = mv->nb_add;
6375
6376 if (likely(slot != NULL)) {
6377 PyObject *x = slot(coerced1, coerced2);
6378
6379 Py_DECREF(coerced1);
6380 Py_DECREF(coerced2);
6381
6382 obj_result = x;
6383 goto exit_binary_result_object;
6384 }
6385 }
6386
6387 // nb_coerce took a reference.
6388 Py_DECREF(coerced1);
6389 Py_DECREF(coerced2);
6390 }
6391 }
6392 coercion c2 =
6393 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
6394
6395 if (c2 != NULL) {
6396 PyObject *coerced1 = operand1;
6397 PyObject *coerced2 = operand2;
6398
6399 int err = c2(&coerced2, &coerced1);
6400
6401 if (unlikely(err < 0)) {
6402 goto exit_binary_exception;
6403 }
6404
6405 if (err == 0) {
6406 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
6407
6408 if (likely(mv == NULL)) {
6409 binaryfunc slot = mv->nb_add;
6410
6411 if (likely(slot != NULL)) {
6412 PyObject *x = slot(coerced1, coerced2);
6413
6414 Py_DECREF(coerced1);
6415 Py_DECREF(coerced2);
6416
6417 obj_result = x;
6418 goto exit_binary_result_object;
6419 }
6420 }
6421
6422 // nb_coerce took a reference.
6423 Py_DECREF(coerced1);
6424 Py_DECREF(coerced2);
6425 }
6426 }
6427 }
6428#endif
6429
6430 {
6431 // Special case for "+" and "*", also works as sequence concat/repeat.
6432 binaryfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_concat : NULL;
6433
6434 if (sq_slot != NULL) {
6435 PyObject *result = sq_slot(operand1, operand2);
6436
6437 obj_result = result;
6438 goto exit_binary_result_object;
6439 }
6440 }
6441
6442 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for +: '%s' and '%s'", type1->tp_name, type2->tp_name);
6443 goto exit_binary_exception;
6444
6445exit_binary_result_object:
6446 if (unlikely(obj_result == NULL)) {
6447 return NUITKA_BOOL_EXCEPTION;
6448 }
6449
6450 {
6451 nuitka_bool r = CHECK_IF_TRUE(obj_result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6452 Py_DECREF(obj_result);
6453 return r;
6454 }
6455
6456exit_binary_exception:
6457 return NUITKA_BOOL_EXCEPTION;
6458}
6459
6460nuitka_bool BINARY_OPERATION_ADD_NBOOL_OBJECT_OBJECT(PyObject *operand1, PyObject *operand2) {
6461 return _BINARY_OPERATION_ADD_NBOOL_OBJECT_OBJECT(operand1, operand2);
6462}
6463
6464// Part of "Nuitka", an optimizing Python compiler that is compatible and
6465// integrates with CPython, but also works on its own.
6466//
6467// Licensed under the Apache License, Version 2.0 (the "License");
6468// you may not use this file except in compliance with the License.
6469// You may obtain a copy of the License at
6470//
6471// http://www.apache.org/licenses/LICENSE-2.0
6472//
6473// Unless required by applicable law or agreed to in writing, software
6474// distributed under the License is distributed on an "AS IS" BASIS,
6475// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6476// See the License for the specific language governing permissions and
6477// limitations under the License.