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